diff --git a/config.example.json b/config.example.json index a562359..5584e2a 100644 --- a/config.example.json +++ b/config.example.json @@ -82,7 +82,10 @@ "telegram": { "enabled": false, "token": "YOUR_TELEGRAM_BOT_TOKEN", - "allow_from": ["YOUR_USER_ID"] + "allow_from": ["YOUR_USER_ID"], + "allow_chats": [], + "enable_groups": true, + "require_mention_in_groups": true }, "discord": { "enabled": false, diff --git a/pkg/channels/telegram.go b/pkg/channels/telegram.go index 7faa8c0..2c99ae3 100644 --- a/pkg/channels/telegram.go +++ b/pkg/channels/telegram.go @@ -39,6 +39,7 @@ type TelegramChannel struct { stopThinking sync.Map // chatID -> chan struct{} handleSem chan struct{} handleWG sync.WaitGroup + botUsername string } func (c *TelegramChannel) SupportsAction(action string) bool { @@ -109,6 +110,7 @@ func (c *TelegramChannel) Start(ctx context.Context) error { if err != nil { return fmt.Errorf("failed to get bot info: %w", err) } + c.botUsername = strings.ToLower(strings.TrimSpace(botInfo.Username)) logger.InfoCF("telegram", "Telegram bot connected", map[string]interface{}{ "username": botInfo.Username, }) @@ -332,6 +334,44 @@ func (c *TelegramChannel) Send(ctx context.Context, msg bus.OutboundMessage) err return nil } +func (c *TelegramChannel) isAllowedChat(chatID int64) bool { + if len(c.config.AllowChats) == 0 { + return true + } + sid := fmt.Sprintf("%d", chatID) + for _, allowed := range c.config.AllowChats { + if strings.TrimSpace(allowed) == sid { + return true + } + } + return false +} + +func (c *TelegramChannel) shouldHandleGroupMessage(message *telego.Message, content string) bool { + if message == nil { + return false + } + if message.Chat.Type == telego.ChatTypePrivate { + return true + } + if !c.config.EnableGroups { + return false + } + if !c.config.RequireMentionInGroups { + return true + } + if message.ReplyToMessage != nil && message.ReplyToMessage.From != nil && message.ReplyToMessage.From.IsBot { + return true + } + if strings.HasPrefix(strings.TrimSpace(content), "/") { + return true + } + if c.botUsername != "" && strings.Contains(strings.ToLower(content), "@"+c.botUsername) { + return true + } + return false +} + func (c *TelegramChannel) handleMessage(runCtx context.Context, message *telego.Message) { if message == nil { return @@ -418,6 +458,21 @@ func (c *TelegramChannel) handleMessage(runCtx context.Context, message *telego. content = "[empty message]" } + if !c.isAllowedChat(chatID) { + logger.WarnCF("telegram", "Telegram message rejected by chat allowlist", map[string]interface{}{ + logger.FieldSenderID: senderID, + logger.FieldChatID: chatID, + }) + return + } + if !c.shouldHandleGroupMessage(message, content) { + logger.DebugCF("telegram", "Ignoring group message without mention/command", map[string]interface{}{ + logger.FieldSenderID: senderID, + logger.FieldChatID: chatID, + }) + return + } + logger.InfoCF("telegram", "Telegram message received", map[string]interface{}{ logger.FieldSenderID: senderID, logger.FieldPreview: truncateString(content, 50), diff --git a/pkg/config/config.go b/pkg/config/config.go index dda93ae..f2d9dff 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -137,9 +137,12 @@ type WhatsAppConfig struct { } type TelegramConfig struct { - Enabled bool `json:"enabled" env:"CLAWGO_CHANNELS_TELEGRAM_ENABLED"` - Token string `json:"token" env:"CLAWGO_CHANNELS_TELEGRAM_TOKEN"` - AllowFrom []string `json:"allow_from" env:"CLAWGO_CHANNELS_TELEGRAM_ALLOW_FROM"` + Enabled bool `json:"enabled" env:"CLAWGO_CHANNELS_TELEGRAM_ENABLED"` + Token string `json:"token" env:"CLAWGO_CHANNELS_TELEGRAM_TOKEN"` + AllowFrom []string `json:"allow_from" env:"CLAWGO_CHANNELS_TELEGRAM_ALLOW_FROM"` + AllowChats []string `json:"allow_chats" env:"CLAWGO_CHANNELS_TELEGRAM_ALLOW_CHATS"` + EnableGroups bool `json:"enable_groups" env:"CLAWGO_CHANNELS_TELEGRAM_ENABLE_GROUPS"` + RequireMentionInGroups bool `json:"require_mention_in_groups" env:"CLAWGO_CHANNELS_TELEGRAM_REQUIRE_MENTION_IN_GROUPS"` } type FeishuConfig struct { @@ -378,9 +381,12 @@ func DefaultConfig() *Config { AllowFrom: []string{}, }, Telegram: TelegramConfig{ - Enabled: false, - Token: "", - AllowFrom: []string{}, + Enabled: false, + Token: "", + AllowFrom: []string{}, + AllowChats: []string{}, + EnableGroups: true, + RequireMentionInGroups: true, }, Feishu: FeishuConfig{ Enabled: false,