feat: add group chat and mention-gating to channel adapters

Slack: add requireMention option, resolve bot user ID on connect.
Telegram: add group chat mention/reply-to-bot detection, strip @mention
from message text, default requireMention=true for groups.
WhatsApp: add allowedGroupIds for group chat support, mention detection
via mentionedIds and body text, strip bot mention from messages.
This commit is contained in:
William Valentin
2026-02-06 16:51:52 -08:00
parent 20930a4816
commit 647d7779c7
6 changed files with 510 additions and 16 deletions
+21
View File
@@ -22,6 +22,8 @@ export interface SlackAdapterConfig {
signingSecret: string;
/** Channel IDs to respond in. Empty = all channels. */
allowedChannelIds?: string[];
/** Require bot mention to respond (default: false). */
requireMention?: boolean;
}
/** Minimal shape of a Slack message event from Bolt. */
@@ -49,6 +51,7 @@ export class SlackAdapter implements ChannelAdapter {
private messageHandler?: (msg: InboundMessage) => void;
private config: SlackAdapterConfig;
private userNameCache: Map<string, string> = new Map();
private botUserId?: string;
get status(): ChannelStatus {
return this._status;
@@ -81,6 +84,15 @@ export class SlackAdapter implements ChannelAdapter {
});
await this.app.start();
// Resolve bot user ID for mention detection
try {
const authResult = await this.app.client.auth.test();
this.botUserId = authResult.user_id as string | undefined;
} catch {
console.warn('Slack: could not resolve bot user ID for mention detection');
}
this._status = 'connected';
console.log('Slack bot connected via Socket Mode');
} catch (error) {
@@ -167,6 +179,15 @@ export class SlackAdapter implements ChannelAdapter {
return;
}
// Mention requirement
const requireMention = this.config.requireMention ?? false;
if (requireMention && this.botUserId) {
const mentionPattern = `<@${this.botUserId}>`;
if (!(message.text ?? '').includes(mentionPattern)) {
return;
}
}
// Build peer ID: channelId:threadTs (thread-aware)
const threadTs = message.thread_ts ?? message.ts ?? '';
const peerId = `${channelId}:${threadTs}`;