fix(qq): use correct API for group chat replies

Fixes #759

QQ group @message replies were failing with err_code:11255 because the bot
was calling the C2C (private chat) API instead of the group chat API.

Changes:
- Added chatTypeMap to track whether each ChatID is group or C2C
- Modified Send() method to use PostGroupMessage() for group chats and
  PostC2CMessage() for private chats
- Implemented thread-safe chat type tracking with RWMutex
- Updated handleGroupATMessage() and handleC2CMessage() to record chat types

Testing:
- Verified QQ group @message replies now succeed
- Confirmed private chat messages still work correctly
- Tested concurrent message handling
This commit is contained in:
liugangjian 2026-03-05 19:11:18 +08:00
parent 028605cfd0
commit e5168b376f

View file

@ -30,6 +30,8 @@ type QQChannel struct {
sessionManager botgo.SessionManager sessionManager botgo.SessionManager
processedIDs map[string]bool processedIDs map[string]bool
mu sync.RWMutex mu sync.RWMutex
chatTypeMap map[string]string // Track whether a ChatID is group or C2C
chatTypeMu sync.RWMutex // Protects chatTypeMap
} }
func NewQQChannel(cfg config.QQConfig, messageBus *bus.MessageBus) (*QQChannel, error) { func NewQQChannel(cfg config.QQConfig, messageBus *bus.MessageBus) (*QQChannel, error) {
@ -42,6 +44,7 @@ func NewQQChannel(cfg config.QQConfig, messageBus *bus.MessageBus) (*QQChannel,
BaseChannel: base, BaseChannel: base,
config: cfg, config: cfg,
processedIDs: make(map[string]bool), processedIDs: make(map[string]bool),
chatTypeMap: make(map[string]string),
}, nil }, nil
} }
@ -126,13 +129,29 @@ func (c *QQChannel) Send(ctx context.Context, msg bus.OutboundMessage) error {
Content: msg.Content, Content: msg.Content,
} }
// send C2C message // Check if this is a group chat or C2C chat
c.chatTypeMu.RLock()
chatType, exists := c.chatTypeMap[msg.ChatID]
c.chatTypeMu.RUnlock()
if exists && chatType == "group" {
// Send group message
_, err := c.api.PostGroupMessage(ctx, msg.ChatID, msgToCreate)
if err != nil {
logger.ErrorCF("qq", "Failed to send group message", map[string]any{
"error": err.Error(),
})
return fmt.Errorf("qq send group: %w", channels.ErrTemporary)
}
} else {
// Send C2C message
_, err := c.api.PostC2CMessage(ctx, msg.ChatID, msgToCreate) _, err := c.api.PostC2CMessage(ctx, msg.ChatID, msgToCreate)
if err != nil { if err != nil {
logger.ErrorCF("qq", "Failed to send C2C message", map[string]any{ logger.ErrorCF("qq", "Failed to send C2C message", map[string]any{
"error": err.Error(), "error": err.Error(),
}) })
return fmt.Errorf("qq send: %w", channels.ErrTemporary) return fmt.Errorf("qq send C2C: %w", channels.ErrTemporary)
}
} }
return nil return nil
@ -167,6 +186,11 @@ func (c *QQChannel) handleC2CMessage() event.C2CMessageEventHandler {
"length": len(content), "length": len(content),
}) })
// Record chat type for this sender
c.chatTypeMu.Lock()
c.chatTypeMap[senderID] = "c2c"
c.chatTypeMu.Unlock()
// 转发到消息总线 // 转发到消息总线
metadata := map[string]string{} metadata := map[string]string{}
@ -232,6 +256,11 @@ func (c *QQChannel) handleGroupATMessage() event.GroupATMessageEventHandler {
"length": len(content), "length": len(content),
}) })
// Record chat type for this group
c.chatTypeMu.Lock()
c.chatTypeMap[data.GroupID] = "group"
c.chatTypeMu.Unlock()
// 转发到消息总线(使用 GroupID 作为 ChatID // 转发到消息总线(使用 GroupID 作为 ChatID
metadata := map[string]string{ metadata := map[string]string{
"group_id": data.GroupID, "group_id": data.GroupID,