feat(gateway): 优化gateway相关功能
Quality check / Web UI (push) Successful in 9m19s

This commit is contained in:
mei
2026-09-12 15:32:27 +08:00
parent 0d89b7fe8f
commit 9b656cebee
84 changed files with 2769 additions and 825 deletions
+2 -11
View File
@@ -1,7 +1,6 @@
package onebot
import (
"encoding/json"
"fmt"
"net/url"
"strings"
@@ -17,7 +16,7 @@ func (v *OneBotAccountConfigValidator) GetType() string {
}
func (v *OneBotAccountConfigValidator) Validate(config string) error {
cfg, err := parseAccount(config)
cfg, err := ParseAccountConfig(config)
if err != nil {
return err
}
@@ -39,7 +38,7 @@ func (v *OneBotAccountConfigValidator) Validate(config string) error {
// Test 调用 get_login_info 验证地址与 Token
func (v *OneBotAccountConfigValidator) Test(config string) error {
cfg, err := parseAccount(config)
cfg, err := ParseAccountConfig(config)
if err != nil {
return err
}
@@ -62,11 +61,3 @@ func (v *OneBotAccountConfigValidator) Meta() meta.AccountMeta {
},
}
}
func parseAccount(config string) (*OneBotAccount, error) {
var cfg OneBotAccount
if err := json.Unmarshal([]byte(config), &cfg); err != nil {
return nil, fmt.Errorf("解析OneBot账号配置失败: %v", err)
}
return &cfg, nil
}
+12 -23
View File
@@ -6,40 +6,29 @@ import (
"strings"
"github.com/ssdomei232/goodBaby/internal/retry"
"github.com/ssdomei232/goodBaby/model"
)
// SendOneBotMsg 向规则中配置的群和好友发送消息
func SendOneBotMsg(ctx context.Context, rule *model.Rule) error {
oneBotConfig, err := getOneBotConfigFromRule(rule)
if err != nil {
return err
}
oneBotAccount, err := getOneBotAccountFromRule(rule)
if err != nil {
return fmt.Errorf("获取OneBot账户失败: %w", err)
}
// SendMessage 向规则中配置的群和好友发送消息
//
// 每个目标单独重试、互不阻塞,最后汇总失败信息交给上层记录。
func SendMessage(ctx context.Context, account *OneBotAccount, config *OneBotConfig) error {
var fails []string
total := 0
for _, groupID := range oneBotConfig.SendGroups {
for _, groupID := range config.SendGroups {
total++
err := retry.Do(ctx, func() error {
return sendGroupMsg(oneBotAccount, groupID, oneBotConfig.Msg)
})
if err != nil {
if err := retry.Do(ctx, func() error {
return sendGroupMsg(account, groupID, config.Msg)
}); err != nil {
fails = append(fails, fmt.Sprintf("群 %d: %v", groupID, err))
}
}
for _, userID := range oneBotConfig.SendUsers {
for _, userID := range config.SendUsers {
total++
err := retry.Do(ctx, func() error {
return sendPrivateMsg(oneBotAccount, userID, oneBotConfig.Msg)
})
if err != nil {
if err := retry.Do(ctx, func() error {
return sendPrivateMsg(account, userID, config.Msg)
}); err != nil {
fails = append(fails, fmt.Sprintf("好友 %d: %v", userID, err))
}
}
+4 -5
View File
@@ -1,7 +1,6 @@
package onebot
import (
"encoding/json"
"fmt"
"github.com/ssdomei232/goodBaby/internal/meta"
@@ -15,9 +14,9 @@ func (v *OneBotRuleValidator) GetType() string {
}
func (v *OneBotRuleValidator) Validate(configJSON string) error {
var config OneBotConfig
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
return fmt.Errorf("解析OneBot规则配置失败: %v", err)
config, err := ParseRuleConfig(configJSON)
if err != nil {
return err
}
if config.Msg == "" {
@@ -44,7 +43,7 @@ func (v *OneBotRuleValidator) Meta() meta.RuleMeta {
Description: "触发时通过 OneBot 向指定的群或好友发送消息。",
AccountType: AccountType,
Fields: []meta.Field{
{Key: "msg", Label: "消息内容", Type: meta.FieldTextarea, Required: true},
{Key: "msg", Label: "消息内容", Type: meta.FieldTextarea, Required: true, GatewayMessage: true},
{Key: "send_groups", Label: "群号", Type: meta.FieldNumberList, Placeholder: "123456789"},
{Key: "send_users", Label: "好友 QQ 号", Type: meta.FieldNumberList, Placeholder: "123456789"},
},
+11 -4
View File
@@ -2,7 +2,6 @@ package onebot
import (
"context"
"log"
"github.com/ssdomei232/goodBaby/model"
)
@@ -14,8 +13,16 @@ func (e *OneBotExecutor) GetType() string {
return RuleType
}
func (e *OneBotExecutor) Execute(ctx context.Context, rule *model.Rule) error {
log.Printf("执行OneBot规则: %s (ID: %d)", rule.Name, rule.ID)
func (e *OneBotExecutor) Execute(ctx context.Context, task *model.RuleTask) error {
account, err := ParseAccountConfig(task.AccountConfig())
if err != nil {
return err
}
return SendOneBotMsg(ctx, rule)
config, err := ParseRuleConfig(task.Rule.ConfigJson)
if err != nil {
return err
}
return SendMessage(ctx, account, config)
}
+29 -25
View File
@@ -4,37 +4,37 @@ import (
"encoding/json"
"fmt"
"github.com/ssdomei232/goodBaby/handler/db"
"github.com/ssdomei232/goodBaby/model"
napcat "github.com/ssdomei232/napcat-http-go-sdk"
)
// ParseAccountConfig 解析 OneBot 账号配置
func ParseAccountConfig(config string) (*OneBotAccount, error) {
if config == "" {
return nil, fmt.Errorf("解析OneBot账号配置失败: 规则没有关联账号")
}
var account OneBotAccount
if err := json.Unmarshal([]byte(config), &account); err != nil {
return nil, fmt.Errorf("解析OneBot账号配置失败: %v", err)
}
return &account, nil
}
// ParseRuleConfig 解析 OneBot 规则配置
func ParseRuleConfig(configJSON string) (*OneBotConfig, error) {
var config OneBotConfig
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
return nil, fmt.Errorf("解析OneBot规则配置失败: %v", err)
}
return &config, nil
}
// newClient 创建 OneBot HTTP 客户端
func newClient(account *OneBotAccount) *napcat.Client {
return napcat.NewClient(account.Token, account.URL)
}
// 从 Rule 中获取 OneBotConfig
func getOneBotConfigFromRule(rule *model.Rule) (*OneBotConfig, error) {
var oneBotConfig OneBotConfig
if err := json.Unmarshal([]byte(rule.ConfigJson), &oneBotConfig); err != nil {
return nil, fmt.Errorf("解析OneBot规则配置失败: %w", err)
}
return &oneBotConfig, nil
}
// 从 Rule 中获取 OneBotAccount
func getOneBotAccountFromRule(rule *model.Rule) (*OneBotAccount, error) {
var oneBotAccount OneBotAccount
if err := db.LoadAccountConfig(rule.AccountID, &oneBotAccount); err != nil {
return nil, err
}
return &oneBotAccount, nil
}
// 发送一条群消息
//
// SDK 只返回传输层错误,这里自己解析 OneBot 的响应信封,
// 否则 token 错误、群号不存在这类失败会被当成发送成功。
// sendGroupMsg 发送一条群消息
func sendGroupMsg(account *OneBotAccount, groupID int64, msg string) error {
return call(account, "/send_group_msg", map[string]any{
"group_id": groupID,
@@ -42,7 +42,7 @@ func sendGroupMsg(account *OneBotAccount, groupID int64, msg string) error {
})
}
// 发送一条私聊消息
// sendPrivateMsg 发送一条私聊消息
func sendPrivateMsg(account *OneBotAccount, userID int64, msg string) error {
return call(account, "/send_private_msg", map[string]any{
"user_id": userID,
@@ -50,6 +50,10 @@ func sendPrivateMsg(account *OneBotAccount, userID int64, msg string) error {
})
}
// call 调用一次 OneBot HTTP API。
//
// SDK 只返回传输层错误,这里自己解析 OneBot 的响应信封,
// 否则 token 错误、群号不存在这类失败会被当成发送成功。
func call(account *OneBotAccount, endpoint string, payload map[string]any) error {
var resp apiResponse
if err := newClient(account).DoRequest("POST", endpoint, payload, &resp); err != nil {