fix(dingtalk): strip leading mentions in group payloads
This commit is contained in:
parent
0775914a41
commit
8e33adcf1b
2 changed files with 46 additions and 4 deletions
|
|
@ -190,8 +190,12 @@ func (c *DingTalkChannel) onChatBotMessageReceived(
|
||||||
peer = bus.Peer{Kind: "direct", ID: peerID}
|
peer = bus.Peer{Kind: "direct", ID: peerID}
|
||||||
} else {
|
} else {
|
||||||
peer = bus.Peer{Kind: "group", ID: data.ConversationId}
|
peer = bus.Peer{Kind: "group", ID: data.ConversationId}
|
||||||
|
isMentioned := data.IsInAtList
|
||||||
|
if isMentioned {
|
||||||
|
content = stripLeadingAtMentions(content)
|
||||||
|
}
|
||||||
// In group chats, apply unified group trigger filtering
|
// In group chats, apply unified group trigger filtering
|
||||||
respond, cleaned := c.ShouldRespondInGroup(data.IsInAtList, content)
|
respond, cleaned := c.ShouldRespondInGroup(isMentioned, content)
|
||||||
if !respond {
|
if !respond {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
@ -253,3 +257,19 @@ func (c *DingTalkChannel) SendDirectReply(ctx context.Context, sessionWebhook, c
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stripLeadingAtMentions(content string) string {
|
||||||
|
fields := strings.Fields(content)
|
||||||
|
if len(fields) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for i < len(fields) && strings.HasPrefix(fields[i], "@") {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if i == 0 {
|
||||||
|
return strings.TrimSpace(content)
|
||||||
|
}
|
||||||
|
return strings.Join(fields[i:], " ")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,13 @@ func mustReceiveInbound(t *testing.T, msgBus *bus.MessageBus) bus.InboundMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOnChatBotMessageReceived_GroupMentionOnlyUsesIsInAtList(t *testing.T) {
|
func TestOnChatBotMessageReceived_GroupMentionOnlyUsesIsInAtListAndStripsMention(t *testing.T) {
|
||||||
ch, msgBus := newTestDingTalkChannel(t, config.DingTalkConfig{
|
ch, msgBus := newTestDingTalkChannel(t, config.DingTalkConfig{
|
||||||
GroupTrigger: config.GroupTriggerConfig{MentionOnly: true},
|
GroupTrigger: config.GroupTriggerConfig{MentionOnly: true},
|
||||||
})
|
})
|
||||||
|
|
||||||
_, err := ch.onChatBotMessageReceived(context.Background(), &chatbot.BotCallbackDataModel{
|
_, err := ch.onChatBotMessageReceived(context.Background(), &chatbot.BotCallbackDataModel{
|
||||||
Text: chatbot.BotCallbackDataTextModel{Content: " @bot hello "},
|
Text: chatbot.BotCallbackDataTextModel{Content: " @bot /help "},
|
||||||
SenderStaffId: "staff-123",
|
SenderStaffId: "staff-123",
|
||||||
SenderNick: "Alice",
|
SenderNick: "Alice",
|
||||||
ConversationType: "2",
|
ConversationType: "2",
|
||||||
|
|
@ -68,7 +68,7 @@ func TestOnChatBotMessageReceived_GroupMentionOnlyUsesIsInAtList(t *testing.T) {
|
||||||
if inbound.Peer.Kind != "group" || inbound.Peer.ID != "group-abc" {
|
if inbound.Peer.Kind != "group" || inbound.Peer.ID != "group-abc" {
|
||||||
t.Fatalf("peer=%+v", inbound.Peer)
|
t.Fatalf("peer=%+v", inbound.Peer)
|
||||||
}
|
}
|
||||||
if inbound.Content != "@bot hello" {
|
if inbound.Content != "/help" {
|
||||||
t.Fatalf("content=%q", inbound.Content)
|
t.Fatalf("content=%q", inbound.Content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -107,3 +107,25 @@ func TestOnChatBotMessageReceived_DirectFallbackSenderIDUsesConversationID(t *te
|
||||||
t.Fatal("unexpected empty chat_id webhook key")
|
t.Fatal("unexpected empty chat_id webhook key")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStripLeadingAtMentions(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
wantOut string
|
||||||
|
}{
|
||||||
|
{name: "single mention and command", input: "@bot /help", wantOut: "/help"},
|
||||||
|
{name: "multiple mentions", input: "@bot @alice /new", wantOut: "/new"},
|
||||||
|
{name: "no mention", input: "/help", wantOut: "/help"},
|
||||||
|
{name: "mention only", input: "@bot", wantOut: ""},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := stripLeadingAtMentions(tt.input)
|
||||||
|
if got != tt.wantOut {
|
||||||
|
t.Fatalf("stripLeadingAtMentions(%q)=%q want=%q", tt.input, got, tt.wantOut)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue