mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-17 10:14:23 +00:00
feat(channels): add thread support to all channel handlers
Pass threadID and threadType to EnsureContact across all channel integrations: - Discord, Feishu, Slack, Telegram, WhatsApp, Zalo - Include General topic in contact collection
This commit is contained in:
1 parent
ac3af93df5
commit
7d5c670708
9 files changed
+27
-20
No files matched your search
@@ -121,13 +121,13 @@ func processNormalMessage(
|
||||
}
|
||||
displayName := sessionMeta["display_name"]
|
||||
username := sessionMeta["username"]
|
||||
deps.ContactCollector.EnsureContact(ctx, channelType, msg.Channel, senderNumericID, userID, displayName, username, peerKind, "user")
|
||||
deps.ContactCollector.EnsureContact(ctx, channelType, msg.Channel, senderNumericID, userID, displayName, username, peerKind, "user", "", "")
|
||||
|
||||
// Also collect group chat as a contact (for group permission management / merge).
|
||||
// Group IDs (e.g., Telegram "-100456") differ from user IDs — no UNIQUE conflict.
|
||||
if peerKind == string(sessions.PeerGroup) && msg.ChatID != "" {
|
||||
groupTitle := msg.Metadata["chat_title"] // Telegram: message.Chat.Title
|
||||
deps.ContactCollector.EnsureContact(ctx, channelType, msg.Channel, msg.ChatID, "", groupTitle, "", "group", "group")
|
||||
deps.ContactCollector.EnsureContact(ctx, channelType, msg.Channel, msg.ChatID, "", groupTitle, "", "group", "group", "", "")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ func (c *Channel) handleMessage(_ *discordgo.Session, m *discordgo.MessageCreate
|
||||
|
||||
// Collect contact even when bot is not mentioned (cache prevents DB spam).
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, senderName, m.Author.Username, "group", "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, senderName, m.Author.Username, "group", "user", "", "")
|
||||
}
|
||||
|
||||
slog.Debug("discord group message recorded (no mention)",
|
||||
@@ -287,7 +287,7 @@ func (c *Channel) handleMessage(_ *discordgo.Session, m *discordgo.MessageCreate
|
||||
|
||||
// Collect contact for processed messages (DM + group-mentioned).
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, senderName, m.Author.Username, peerKind, "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, senderName, m.Author.Username, peerKind, "user", "", "")
|
||||
}
|
||||
|
||||
// Publish directly to bus (to preserve MediaFile MIME types)
|
||||
|
||||
@@ -106,7 +106,7 @@ func (c *Channel) handleMessageEvent(ctx context.Context, event *MessageEvent) {
|
||||
|
||||
// Collect contact even when bot is not mentioned (cache prevents DB spam).
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), mc.SenderID, mc.SenderID, senderName, "", "group", "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), mc.SenderID, mc.SenderID, senderName, "", "group", "user", "", "")
|
||||
}
|
||||
|
||||
slog.Debug("feishu group message recorded (no mention)",
|
||||
@@ -162,7 +162,7 @@ func (c *Channel) handleMessageEvent(ctx context.Context, event *MessageEvent) {
|
||||
|
||||
// Collect contact for processed messages (DM + group-mentioned).
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), mc.SenderID, mc.SenderID, senderName, "", peerKind, "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), mc.SenderID, mc.SenderID, senderName, "", peerKind, "user", "", "")
|
||||
}
|
||||
|
||||
metadata := map[string]string{
|
||||
|
||||
@@ -575,7 +575,7 @@ func (c *Channel) ListGroupMembers(ctx context.Context, chatID string) ([]channe
|
||||
}
|
||||
// Auto-sync member into contact store
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
cc.EnsureContact(ctx, channels.TypeFeishu, c.Name(), m.MemberID, m.MemberID, m.Name, "", "group", "user")
|
||||
cc.EnsureContact(ctx, channels.TypeFeishu, c.Name(), m.MemberID, m.MemberID, m.Name, "", "group", "user", "", "")
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
|
||||
@@ -200,7 +200,7 @@ func (c *Channel) handleMessage(ev *slackevents.MessageEvent) {
|
||||
|
||||
// Collect contact even when bot is not mentioned (cache prevents DB spam).
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, displayName, "", "group", "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, displayName, "", "group", "user", "", "")
|
||||
}
|
||||
|
||||
slog.Debug("slack group message recorded (no mention)",
|
||||
|
||||
@@ -34,7 +34,7 @@ func (c *Channel) HandleMessage(senderID, chatID, content string, mediaPaths []s
|
||||
// Collect contact for processed messages (DM + group-mentioned).
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
ctx := store.WithTenantID(context.Background(), c.TenantID())
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), userID, userID, metadata["username"], "", peerKind, "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), userID, userID, metadata["username"], "", peerKind, "user", "", "")
|
||||
}
|
||||
|
||||
c.Bus().PublishInbound(bus.InboundMessage{
|
||||
|
||||
@@ -41,9 +41,6 @@ func (c *Channel) handleMessage(ctx context.Context, update telego.Update) {
|
||||
|
||||
userID := fmt.Sprintf("%d", user.ID)
|
||||
senderID := userID
|
||||
if user.Username != "" {
|
||||
senderID = fmt.Sprintf("%s|%s", userID, user.Username)
|
||||
}
|
||||
|
||||
isGroup := message.Chat.Type == "group" || message.Chat.Type == "supergroup"
|
||||
|
||||
@@ -336,9 +333,14 @@ func (c *Channel) handleMessage(ctx context.Context, update telego.Update) {
|
||||
// Collect contact even when bot is not mentioned (cache prevents DB spam).
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
contactName := strings.TrimSpace(user.FirstName + " " + user.LastName)
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, userID, contactName, user.Username, "group", "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, userID, contactName, user.Username, "group", "user", "", "")
|
||||
// Also collect group chat itself as a contact (for group permission / merge).
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), chatIDStr, "", message.Chat.Title, "", "group", "group")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), chatIDStr, "", message.Chat.Title, "", "group", "group", "", "")
|
||||
// Collect forum topic as a distinct delivery target (including General).
|
||||
if isForum && messageThreadID > 0 {
|
||||
threadStr := fmt.Sprintf("%d", messageThreadID)
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), chatIDStr, "", message.Chat.Title, "", "group", "topic", threadStr, "topic")
|
||||
}
|
||||
}
|
||||
|
||||
slog.Debug("telegram group message recorded (no mention)",
|
||||
@@ -591,10 +593,15 @@ func (c *Channel) handleMessage(ctx context.Context, update telego.Update) {
|
||||
// Collect contact for processed messages (DM + group-mentioned).
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
contactName := strings.TrimSpace(user.FirstName + " " + user.LastName)
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, userID, contactName, user.Username, peerKind, "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, userID, contactName, user.Username, peerKind, "user", "", "")
|
||||
// Also collect group chat itself as a contact (for group permission / merge).
|
||||
if isGroup {
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), chatIDStr, "", message.Chat.Title, "", "group", "group")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), chatIDStr, "", message.Chat.Title, "", "group", "group", "", "")
|
||||
// Collect forum topic as a distinct delivery target (including General).
|
||||
if isForum && messageThreadID > 0 {
|
||||
threadStr := fmt.Sprintf("%d", messageThreadID)
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), chatIDStr, "", message.Chat.Title, "", "group", "topic", threadStr, "topic")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -271,7 +271,7 @@ func (c *Channel) handleIncomingMessage(msg map[string]any) {
|
||||
|
||||
// Collect contact for processed messages.
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, metadata["user_name"], "", peerKind, "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, metadata["user_name"], "", peerKind, "user", "", "")
|
||||
}
|
||||
|
||||
// Annotate with sender identity so the agent knows who is messaging.
|
||||
|
||||
@@ -64,7 +64,7 @@ func (c *Channel) handleDM(msg protocol.UserMessage) {
|
||||
|
||||
// Collect contact for DM messages.
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, senderName, "", "direct", "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, senderName, "", "direct", "user", "", "")
|
||||
}
|
||||
|
||||
metadata := map[string]string{
|
||||
@@ -111,7 +111,7 @@ func (c *Channel) handleGroupMessage(msg protocol.GroupMessage) {
|
||||
|
||||
// Collect contact even when bot is not mentioned (cache prevents DB spam).
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, senderName, "", "group", "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, senderName, "", "group", "user", "", "")
|
||||
}
|
||||
|
||||
slog.Debug("zalo_personal group message recorded (no mention)",
|
||||
@@ -144,7 +144,7 @@ func (c *Channel) handleGroupMessage(msg protocol.GroupMessage) {
|
||||
|
||||
// Collect contact for group-mentioned messages.
|
||||
if cc := c.ContactCollector(); cc != nil {
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, senderName, "", "group", "user")
|
||||
cc.EnsureContact(ctx, c.Type(), c.Name(), senderID, senderID, senderName, "", "group", "user", "", "")
|
||||
}
|
||||
|
||||
metadata := map[string]string{
|
||||
|
||||
Reference in new issue
Block a user