契约(internal/channel/adapter):UnifiedMessage 新增三个字段 —— SelfID(她自己在该 平台的账号 id)、MentionAll(是否 @全体,design/26 §2.4 的 mention_all)、AddressedToMe (本条是否指向她本人);判据的唯一出处是新增的 MentionedSelf(结构化 id 精确比对, 空 selfID 一律 false)与 AddressedToSelf(私聊恒 true;群聊 = 点名她或 @全体; 平台未给 SelfID ⇒ fail-closed)。全程不匹配正文文本。 接线(plugins/channels/qq_obv11):新增 addressed.go,把事件里早已解出、此前只用于 debug 日志与 notice 判定的 self_id 接进 toUnified,并从 at 段解出 @全体(qq=all), 在 ChannelType 判定之后统一回写三个字段。 design/18 §2 触发① 的旧口径「Mentions 非空」= @谁不论(实测群 672432767 里 @别人两次 被回);本片让消费侧(light.go:142,归 M12)能改用 AddressedToMe || MentionAll。 既有字段 Mentions/ReplyToID/ReplyToText 语义与形状不变。 测试:qq_obv11 十种帧形态(私聊/@她/@别人/@全体/无@/CQ 形态/fail-closed/纯回复) 逐条断言;adapter 侧覆盖 MentionedSelf 与 AddressedToSelf。变异自证:判据改回 「Mentions 非空」⇒ group_mention_other 红;摘掉 selfId 接线 ⇒ group_mention_me 红。
47 lines
2.5 KiB
Go
47 lines
2.5 KiB
Go
package qq_obv11
|
||
|
||
// 本文件承载「这条消息是不是在叫她」的**结构化接线**:把 OneBot 事件里已有的
|
||
// self_id(她自己在该平台的账号 id)与 at 段(点名 / @全体)写进统一契约
|
||
// adapter.UnifiedMessage,让下游不必再靠「Mentions 非空」这种 **@ 谁不论**的判据
|
||
// (design/18 §2 触发① 的 2026-10-13 修订;主人裁决「甲 = 要」)。
|
||
//
|
||
// 红线:判据**全部来自平台元数据**(self_id + at 段的 qq),绝不匹配正文里的
|
||
// "@<数字>" —— 正文里恰好只有这种文本,而它正是不可靠的原因(@ 她与 @ 别人长得一模一样)。
|
||
//
|
||
// 只覆盖**真消息**那条路径(toUnified)。debug 帧日志(inbound_debug.go)与 notice 的
|
||
// self 命中(notice.go / event.go)各有各的语义,本片不动它们。
|
||
|
||
import (
|
||
"git.yeij.top/AskaEth/Cyrene_v2/internal/channel/adapter"
|
||
)
|
||
|
||
// mentionAllQQ 是 OneBot v11 at 段里 **@全体成员** 的 qq 取值
|
||
// (数组段 `{"type":"at","data":{"qq":"all"}}`,CQ 码形态 `[CQ:at,qq=all]`)。
|
||
// design/26 §2.4 把它登记为随消息到达的**结构化标志**(mention_all),不另立一类事件。
|
||
// 该字面量是 OneBot 协议约定,所以落在平台侧(这里),不污染平台中立的 adapter 包。
|
||
const mentionAllQQ = "all"
|
||
|
||
// mentionsContainAll 报告 mentions 里是否含 @全体。只比对结构化的 UserID 字段,
|
||
// 不看正文;判据是精确相等(QQ 号是纯数字,与 "all" 不可能撞号)。
|
||
func mentionsContainAll(mentions []adapter.Mention) bool {
|
||
for _, m := range mentions {
|
||
if m.UserID == mentionAllQQ {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// applyAddressing 把平台元数据写成统一契约里的结构化字段:SelfID(她自己在该平台的
|
||
// 账号 id)、MentionAll(是否 @全体)、AddressedToMe(本条是否指向她本人,推导见
|
||
// adapter.UnifiedMessage.AddressedToSelf)。三个字段同源同步,下游读哪个都不会自相矛盾。
|
||
//
|
||
// 调用点必须在 ChannelType 判定**之后**:私聊与群聊的 AddressedToMe 取值不同。
|
||
// self_id 取不到(字段缺失 / 为 0)时 SelfID 如实留空、AddressedToMe 随之 false ——
|
||
// fail-closed,绝不退回正文匹配(见 adapter.MentionedSelf)。
|
||
func applyAddressing(msg *adapter.UnifiedMessage, selfID string, mentions []adapter.Mention) {
|
||
msg.SelfID = selfID
|
||
msg.MentionAll = mentionsContainAll(mentions)
|
||
msg.AddressedToMe = msg.AddressedToSelf()
|
||
}
|