package channelbridge import ( "git.yeij.top/AskaEth/Cyrene_v2/internal/channel/adapter" ) // 本文件承载按账号的允许/拒绝黑白名单(design/16 §4.6 // §6),在入站流水线的最前端执行,并包含名单匹配所依赖的 // 配置读取函数。 // blacklisted 对非主人的入站消息应用按账号的允许/拒绝黑白名单 // (design/16 §4.6 §6)。群消息按 GroupID // 匹配 allowGroups/denyGroups;私聊消息按发送者用户 // id 匹配 allowUsers/denyUsers。空的允许名单表示「全部允许」(仅 // 拒绝名单生效);非空允许名单即成为白名单。主人 // 永不被拉黑(调用方对主人消息跳过本函数)。 func (b *Bridge) blacklisted(msg adapter.UnifiedMessage, a adapter.PlatformAdapter) (bool, string) { if a == nil { return false, "" } allowGroups, denyGroups, allowUsers, denyUsers := channelLists(a.Config()) if msg.IsGroup() { if sliceContains(denyGroups, msg.GroupID) { return true, "group_denied" } if len(allowGroups) > 0 && !sliceContains(allowGroups, msg.GroupID) { return true, "group_not_allowed" } return false, "" } uid := firstNonEmptyStr(msg.SenderID, msg.Sender.UserID) if sliceContains(denyUsers, uid) { return true, "user_denied" } if len(allowUsers) > 0 && !sliceContains(allowUsers, uid) { return true, "user_not_allowed" } return false, "" } // channelLists 从适配器的 Config 快照中读取允许/拒绝字符串列表。 // 列表以普通 []string 值存储(由多账号装配设置); // 键缺失时得到空列表。 func channelLists(cfg map[string]any) (allowGroups, denyGroups, allowUsers, denyUsers []string) { if cfg == nil { return nil, nil, nil, nil } return cfgStrings(cfg, "allowGroups"), cfgStrings(cfg, "denyGroups"), cfgStrings(cfg, "allowUsers"), cfgStrings(cfg, "denyUsers") } // cfgStrings 从适配器配置 map 中读取 []string 字段,缺失或 // 类型不符时返回 nil。 func cfgStrings(m map[string]any, key string) []string { if m == nil { return nil } switch v := m[key].(type) { case []string: return v case []any: out := make([]string, 0, len(v)) for _, e := range v { if s, ok := e.(string); ok { out = append(out, s) } } return out default: return nil } }