升级至8069版本:版本号更新/代理配置系统/红包计时埋点/长连接重构/回调修复

This commit is contained in:
2026-02-26 10:44:13 +08:00
parent 7cbd3d061d
commit 40a74d2ea7
38 changed files with 3639 additions and 235 deletions

View File

@@ -12,6 +12,7 @@ import (
"regexp"
"strconv"
"time"
"xiawan/wx/db/table"
"xiawan/wx/protobuf/wechat"
"github.com/lunny/log"
@@ -60,8 +61,17 @@ func GenerateSignature(payload []byte, key string) string {
func SendMessageCallback(msg *wechat.AddMsg, uuid string) {
// 获取回调配置
config, err := GetMessageCallbackConfig(uuid)
if err != nil || config == nil || !config.Enabled {
return // 没有配置或未启用回调,直接返回
if err != nil {
log.Errorf("获取回调配置失败 [UUID: %s]: %v", uuid, err)
return
}
if config == nil {
log.Debugf("[回调调试] 未找到回调配置 [UUID: %s]", uuid)
return
}
if !config.Enabled {
log.Debugf("[回调调试] 回调未启用 [UUID: %s]", uuid)
return
}
// 使用消息包装器包含UUID信息
@@ -104,6 +114,59 @@ func SendMessageCallback(msg *wechat.AddMsg, uuid string) {
return
}
// 记录回调结果
log.Infof("Message callback sent to %s for message %d, status: %d", config.CallbackURL, msg.GetMsgId(), resp.StatusCode)
}
// TestMessageCallback 测试消息回调配置
func TestMessageCallback(config *table.MessageCallbackConfig) (bool, string) {
// 构造测试消息
testPayload := map[string]interface{}{
"uuid": config.UUID,
"type": "test",
"data": map[string]interface{}{
"message": "这是一条测试回调消息",
"timestamp": time.Now().Unix(),
},
}
jsonBytes, err := json.Marshal(testPayload)
if err != nil {
return false, fmt.Sprintf("序列化测试数据失败: %v", err)
}
// 创建HTTP请求
req, err := http.NewRequest("POST", config.CallbackURL, bytes.NewBuffer(jsonBytes))
if err != nil {
return false, fmt.Sprintf("创建请求失败: %v", err)
}
// 设置请求头
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Timestamp", fmt.Sprintf("%d", time.Now().Unix()))
req.Header.Set("X-Test", "true")
// 发送请求
client := &http.Client{
Timeout: 5 * time.Second,
}
resp, err := client.Do(req)
if err != nil {
return false, fmt.Sprintf("发送请求失败: %v", err)
}
defer resp.Body.Close()
// 读取响应
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, fmt.Sprintf("读取响应失败: %v", err)
}
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
log.Infof("✓ 测试回调成功 [UUID: %s] -> %s, 状态码: %d",
config.UUID, config.CallbackURL, resp.StatusCode)
return true, fmt.Sprintf("状态码: %d, 响应: %s", resp.StatusCode, string(body))
} else {
log.Warnf("✗ 测试回调失败 [UUID: %s] -> %s, 状态码: %d",
config.UUID, config.CallbackURL, resp.StatusCode)
return false, fmt.Sprintf("状态码: %d, 响应: %s", resp.StatusCode, string(body))
}
}

View File

@@ -88,14 +88,16 @@ func InitDB() {
fmt.Println("auto create MySQL tables success")
MysqlDB.LogMode(false)
// 初始化回调配置
go InitMessageCallbacks()
// 注意:回调配置的初始化移到了 InitAnewLogin 完成后
// 这样可以确保所有账号连接都已建立
}
// InitMessageCallbacks 初始化所有消息回调配置
func InitMessageCallbacks() {
// 等待数据库连接完全建立
time.Sleep(2 * time.Second)
// 账号已经初始化完成,稍微等待一下确保连接稳定
time.Sleep(3 * time.Second)
log.Infof("开始初始化消息回调配置...")
// 检查并重新连接数据库
if err := checkAndReconnect(); err != nil {
@@ -111,19 +113,34 @@ func InitMessageCallbacks() {
return
}
// 确保相关key字段正确设置
if len(configs) == 0 {
log.Infof("未找到启用的消息回调配置")
return
}
log.Infof("找到 %d 个启用的回调配置,开始重新激活...", len(configs))
// 重新保存每个配置,相当于重新设置一遍,激活回调
successCount := 0
for _, config := range configs {
// 确保Key字段正确
if config.Key == "" {
// 如果Key为空但UUID不为空更新Key字段
MysqlDB.Model(&table.MessageCallbackConfig{}).
Where("id = ?", config.ID).
Updates(map[string]interface{}{
"key": config.UUID,
})
config.Key = config.UUID
}
// 重新保存配置(相当于执行 SetCallback 操作)
err := SaveMessageCallbackConfig(&config)
if err != nil {
log.Errorf("✗ 重新激活回调失败 [UUID: %s]: %v", config.UUID, err)
} else {
log.Infof("✓ 重新激活回调成功 [UUID: %s] -> %s", config.UUID, config.CallbackURL)
successCount++
}
}
log.Infof("Initialized %d message callbacks", len(configs))
log.Infof("========================================")
log.Infof("回调配置激活完成: 成功 %d/%d", successCount, len(configs))
log.Infof("========================================")
}
// checkAndReconnect 检查并在需要时重新连接
@@ -1608,7 +1625,7 @@ func SaveMessageCallbackConfig(config *table.MessageCallbackConfig) error {
if result.Error != nil {
if result.Error == gorm.ErrRecordNotFound {
// 记录不存在,创建新记录
// 创建包含完整字段的记录
log.Infof("[回调调试] 创建新配置记录 [UUID: %s]", config.UUID)
newConfig := table.MessageCallbackConfig{
UUID: config.UUID,
Key: config.UUID, // 确保Key和UUID相同
@@ -1619,8 +1636,6 @@ func SaveMessageCallbackConfig(config *table.MessageCallbackConfig) error {
}
return result.Error
}
// 记录存在,更新记录
return MysqlDB.Model(&existingConfig).Updates(map[string]interface{}{
"key": config.UUID, // 更新Key字段
"callback_url": config.CallbackURL,
@@ -1639,11 +1654,12 @@ func GetMessageCallbackConfig(uuid string) (*table.MessageCallbackConfig, error)
result := MysqlDB.Where("uuid = ?", uuid).First(&config)
if result.Error != nil {
if result.Error == gorm.ErrRecordNotFound {
return nil, nil // 返回nil表示配置不存在
log.Debugf("[回调调试] 数据库中未找到配置 [UUID: %s]", uuid)
return nil, nil
}
log.Errorf("[回调调试] 查询配置出错 [UUID: %s]: %v", uuid, result.Error)
return nil, result.Error
}
return &config, nil
}