Skip to content

Commit a97e502

Browse files
mrgoonieviettranx
andauthored
fix(discord): suppress pairing reply in groups without @mention (#1091) (#1092)
* fix(discord): suppress pairing reply in groups without @mention When `pairing` group policy is combined with `Require @mention`, the bot posted a pairing code in response to every group message because `checkGroupPolicy` ran before the mention gate. Pre-compute the mention flag and pass it into `checkGroupPolicy`. When RequireMention is enabled and the bot was not addressed, return silently instead of triggering `sendPairingReply`. DMs are unchanged — every DM is implicitly directed at the bot. Fixes #1091 * refactor(discord): drop issue ref from inline comment --------- Co-authored-by: viettranx <viettranx@gmail.com>
1 parent 364d2d3 commit a97e502

1 file changed

Lines changed: 25 additions & 15 deletions

File tree

internal/channels/discord/handler.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,29 @@ func (c *Channel) handleMessage(_ *discordgo.Session, m *discordgo.MessageCreate
4444
peerKind = "direct"
4545
}
4646

47+
// Pre-compute mention flag for groups so policy gating can suppress
48+
// pairing replies when the bot was not addressed.
49+
mentioned := false
50+
if !isDM {
51+
for _, u := range m.Mentions {
52+
if u.ID == c.botUserID {
53+
mentioned = true
54+
break
55+
}
56+
}
57+
if !mentioned && m.ReferencedMessage != nil &&
58+
m.ReferencedMessage.Author != nil &&
59+
m.ReferencedMessage.Author.ID == c.botUserID {
60+
mentioned = true
61+
}
62+
}
63+
4764
if isDM {
4865
if !c.checkDMPolicy(ctx, senderID, channelID) {
4966
return
5067
}
5168
} else {
52-
if !c.checkGroupPolicy(ctx, senderID, channelID) {
69+
if !c.checkGroupPolicy(ctx, senderID, channelID, mentioned) {
5370
slog.Debug("discord group message rejected by policy",
5471
"user_id", senderID,
5572
"username", senderName,
@@ -167,20 +184,8 @@ func (c *Channel) handleMessage(_ *discordgo.Session, m *discordgo.MessageCreate
167184

168185
// Mention gating: in groups, only respond when bot is @mentioned (default true).
169186
// When not mentioned, record message to pending history for later context.
187+
// `mentioned` was pre-computed above for policy gating.
170188
if peerKind == "group" && c.RequireMention() {
171-
mentioned := false
172-
for _, u := range m.Mentions {
173-
if u.ID == c.botUserID {
174-
mentioned = true
175-
break
176-
}
177-
}
178-
// Reply to bot's message counts as implicit mention.
179-
if !mentioned && m.ReferencedMessage != nil &&
180-
m.ReferencedMessage.Author != nil &&
181-
m.ReferencedMessage.Author.ID == c.botUserID {
182-
mentioned = true
183-
}
184189
if !mentioned {
185190
// Collect media file paths for group history context.
186191
var mediaPaths []string
@@ -318,12 +323,17 @@ func (c *Channel) handleMessage(_ *discordgo.Session, m *discordgo.MessageCreate
318323
}
319324

320325
// checkGroupPolicy evaluates the group policy for a sender, with pairing support.
321-
func (c *Channel) checkGroupPolicy(ctx context.Context, senderID, channelID string) bool {
326+
// When RequireMention is enabled, pairing replies only fire if the bot was
327+
// explicitly addressed — otherwise the bot stays silent in the channel.
328+
func (c *Channel) checkGroupPolicy(ctx context.Context, senderID, channelID string, mentioned bool) bool {
322329
result := c.CheckGroupPolicy(ctx, senderID, channelID, c.config.GroupPolicy)
323330
switch result {
324331
case channels.PolicyAllow:
325332
return true
326333
case channels.PolicyNeedsPairing:
334+
if c.RequireMention() && !mentioned {
335+
return false
336+
}
327337
groupSenderID := fmt.Sprintf("group:%s", channelID)
328338
c.sendPairingReply(ctx, groupSenderID, channelID)
329339
return false

0 commit comments

Comments
 (0)