mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-05 15:31:27 +00:00
feat(channels): add group chat support for Telegram
- Add GroupGate class for group access control with three policies: disabled (default), allowlist, and open - Implement mention gating: bot only responds when @mentioned or replied to in groups (configurable per-group) - Extend Envelope type with isGroup, isMentioned, isReplyToBot fields - Update TelegramAdapter to detect group context and mentions - Add comprehensive documentation for group chat setup and troubleshooting This enables using Qwen Code bots in Telegram groups with fine-grained access control and mention-based activation to prevent noise. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
8753245b5f
commit
90236465d3
9 changed files with 228 additions and 17 deletions
57
packages/channels/base/src/GroupGate.ts
Normal file
57
packages/channels/base/src/GroupGate.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import type { GroupPolicy, GroupConfig, Envelope } from './types.js';
|
||||
|
||||
export interface GroupCheckResult {
|
||||
allowed: boolean;
|
||||
reason?: 'disabled' | 'not_allowlisted' | 'mention_required';
|
||||
}
|
||||
|
||||
export class GroupGate {
|
||||
private policy: GroupPolicy;
|
||||
private groups: Record<string, GroupConfig>;
|
||||
|
||||
constructor(
|
||||
policy: GroupPolicy = 'disabled',
|
||||
groups: Record<string, GroupConfig> = {},
|
||||
) {
|
||||
this.policy = policy;
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full group check: policy + allowlist + mention gating.
|
||||
* Evaluation order:
|
||||
* 1. groupPolicy (disabled → drop)
|
||||
* 2. group allowlist (allowlist mode, no match → drop)
|
||||
* 3. mention gating (requireMention + not mentioned → drop silently)
|
||||
*
|
||||
* Mention gating runs before sender gate so that unmentioned messages
|
||||
* in groups don't trigger pairing flows.
|
||||
*/
|
||||
check(envelope: Envelope): GroupCheckResult {
|
||||
if (!envelope.isGroup) {
|
||||
return { allowed: true };
|
||||
}
|
||||
|
||||
if (this.policy === 'disabled') {
|
||||
return { allowed: false, reason: 'disabled' };
|
||||
}
|
||||
|
||||
if (this.policy === 'allowlist') {
|
||||
// In allowlist mode, "*" is only a default config — not a wildcard allow.
|
||||
// The group must be explicitly listed by ID.
|
||||
if (!this.groups[envelope.chatId]) {
|
||||
return { allowed: false, reason: 'not_allowlisted' };
|
||||
}
|
||||
}
|
||||
|
||||
// Per-group config, falling back to "*" defaults, then built-in defaults
|
||||
const groupConfig = this.groups[envelope.chatId] || this.groups['*'] || {};
|
||||
const requireMention = groupConfig.requireMention ?? true;
|
||||
|
||||
if (requireMention && !envelope.isMentioned && !envelope.isReplyToBot) {
|
||||
return { allowed: false, reason: 'mention_required' };
|
||||
}
|
||||
|
||||
return { allowed: true };
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue