mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-15 04:18:44 +00:00
fix(telegram): honor per-group/topic overrides for DB instances
The dashboard persists per-group/per-topic overrides (enabled, require_mention, skills, tools, system_prompt, ...) into the channel instance config, but telegramInstanceConfig had no groups field, so the payload was dropped on unmarshal. config.TelegramConfig.Groups stayed nil, resolveTopicConfig fell back to global defaults, and the bot replied in every forum topic regardless of the configured per-topic gating. Map the groups field through the DB-instance factory so per-topic config takes effect for dashboard-created channels, matching the static file-config path.
This commit is contained in:
1 parent
09610e4bfe
commit
a62980bf7c
2 files changed
+95
-20
No files matched your search
@@ -20,26 +20,27 @@ type telegramCreds struct {
|
||||
|
||||
// telegramInstanceConfig maps the non-secret config JSONB from the channel_instances table.
|
||||
type telegramInstanceConfig struct {
|
||||
APIServer string `json:"api_server,omitempty"`
|
||||
Proxy string `json:"proxy,omitempty"`
|
||||
DMPolicy string `json:"dm_policy,omitempty"`
|
||||
GroupPolicy string `json:"group_policy,omitempty"`
|
||||
RequireMention *bool `json:"require_mention,omitempty"`
|
||||
MentionMode string `json:"mention_mode,omitempty"`
|
||||
HistoryLimit int `json:"history_limit,omitempty"`
|
||||
DMStream *bool `json:"dm_stream,omitempty"`
|
||||
GroupStream *bool `json:"group_stream,omitempty"`
|
||||
DraftTransport *bool `json:"draft_transport,omitempty"` // sendMessageDraft for DM streaming (default true)
|
||||
ReasoningDelivery string `json:"reasoning_delivery,omitempty"`
|
||||
ReasoningStream *bool `json:"reasoning_stream,omitempty"` // show reasoning as separate message (default true)
|
||||
ReactionLevel string `json:"reaction_level,omitempty"`
|
||||
MediaMaxMB int64 `json:"media_max_mb,omitempty"`
|
||||
MediaMaxBytes int64 `json:"media_max_bytes,omitempty"` // deprecated: use media_max_mb
|
||||
LinkPreview *bool `json:"link_preview,omitempty"`
|
||||
BlockReply *bool `json:"block_reply,omitempty"`
|
||||
ChatBehavior *config.ChatBehaviorConfig `json:"chat_behavior,omitempty"`
|
||||
ForceIPv4 bool `json:"force_ipv4,omitempty"`
|
||||
AllowFrom []string `json:"allow_from,omitempty"`
|
||||
APIServer string `json:"api_server,omitempty"`
|
||||
Proxy string `json:"proxy,omitempty"`
|
||||
DMPolicy string `json:"dm_policy,omitempty"`
|
||||
GroupPolicy string `json:"group_policy,omitempty"`
|
||||
RequireMention *bool `json:"require_mention,omitempty"`
|
||||
MentionMode string `json:"mention_mode,omitempty"`
|
||||
HistoryLimit int `json:"history_limit,omitempty"`
|
||||
DMStream *bool `json:"dm_stream,omitempty"`
|
||||
GroupStream *bool `json:"group_stream,omitempty"`
|
||||
DraftTransport *bool `json:"draft_transport,omitempty"` // sendMessageDraft for DM streaming (default true)
|
||||
ReasoningDelivery string `json:"reasoning_delivery,omitempty"`
|
||||
ReasoningStream *bool `json:"reasoning_stream,omitempty"` // show reasoning as separate message (default true)
|
||||
ReactionLevel string `json:"reaction_level,omitempty"`
|
||||
MediaMaxMB int64 `json:"media_max_mb,omitempty"`
|
||||
MediaMaxBytes int64 `json:"media_max_bytes,omitempty"` // deprecated: use media_max_mb
|
||||
LinkPreview *bool `json:"link_preview,omitempty"`
|
||||
BlockReply *bool `json:"block_reply,omitempty"`
|
||||
ChatBehavior *config.ChatBehaviorConfig `json:"chat_behavior,omitempty"`
|
||||
ForceIPv4 bool `json:"force_ipv4,omitempty"`
|
||||
AllowFrom []string `json:"allow_from,omitempty"`
|
||||
Groups map[string]*config.TelegramGroupConfig `json:"groups,omitempty"`
|
||||
}
|
||||
|
||||
// Factory creates a Telegram channel from DB instance data (no extra stores).
|
||||
@@ -119,6 +120,7 @@ func buildChannel(name string, creds json.RawMessage, cfg json.RawMessage,
|
||||
BlockReply: ic.BlockReply,
|
||||
ChatBehavior: ic.ChatBehavior,
|
||||
ForceIPv4: ic.ForceIPv4,
|
||||
Groups: ic.Groups,
|
||||
}
|
||||
|
||||
// DB instances default to "pairing" for groups (secure by default).
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package telegram
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const validBotToken = "123456:abcdefghijklmnopqrstuvwxyzABCDE1234"
|
||||
|
||||
func TestFactory_PropagatesGroupsAndTopics(t *testing.T) {
|
||||
creds := json.RawMessage(`{"token":"` + validBotToken + `"}`)
|
||||
cfg := json.RawMessage(`{
|
||||
"groups": {
|
||||
"-1003957927661": {
|
||||
"enabled": false,
|
||||
"topics": {
|
||||
"13": { "enabled": true }
|
||||
}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
|
||||
ch, err := Factory("telegram-test", creds, cfg, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Factory: %v", err)
|
||||
}
|
||||
tg, ok := ch.(*Channel)
|
||||
if !ok {
|
||||
t.Fatalf("Factory returned %T, want *Channel", ch)
|
||||
}
|
||||
|
||||
if tg.config.Groups == nil {
|
||||
t.Fatal("config.Groups is nil — dashboard groups/topics payload was dropped on unmarshal")
|
||||
}
|
||||
group, ok := tg.config.Groups["-1003957927661"]
|
||||
if !ok || group == nil {
|
||||
t.Fatal("group -1003957927661 missing from resolved config")
|
||||
}
|
||||
if group.Enabled == nil || *group.Enabled != false {
|
||||
t.Errorf("group.Enabled = %v, want false", group.Enabled)
|
||||
}
|
||||
|
||||
allowed := resolveTopicConfig(tg.config, "-1003957927661", 13)
|
||||
if !allowed.isEnabled() {
|
||||
t.Error("topic 13: isEnabled() = false, want true")
|
||||
}
|
||||
other := resolveTopicConfig(tg.config, "-1003957927661", 99)
|
||||
if other.isEnabled() {
|
||||
t.Error("topic 99: isEnabled() = true, want false")
|
||||
}
|
||||
general := resolveTopicConfig(tg.config, "-1003957927661", telegramGeneralTopicID)
|
||||
if general.isEnabled() {
|
||||
t.Error("General topic: isEnabled() = true, want false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFactory_NilGroupsWhenAbsent(t *testing.T) {
|
||||
creds := json.RawMessage(`{"token":"` + validBotToken + `"}`)
|
||||
cfg := json.RawMessage(`{"group_policy":"open"}`)
|
||||
|
||||
ch, err := Factory("telegram-test", creds, cfg, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Factory: %v", err)
|
||||
}
|
||||
tg := ch.(*Channel)
|
||||
if tg.config.Groups != nil {
|
||||
t.Errorf("config.Groups = %v, want nil when groups absent", tg.config.Groups)
|
||||
}
|
||||
def := resolveTopicConfig(tg.config, "-100123", 0)
|
||||
if !def.isEnabled() {
|
||||
t.Error("isEnabled() = false, want true by default when no overrides set")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user