Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

adapter-qq 发送单聊主动消息,实际调用了群聊接口 #304

Open
maliut opened this issue Aug 1, 2024 · 0 comments
Open

adapter-qq 发送单聊主动消息,实际调用了群聊接口 #304

maliut opened this issue Aug 1, 2024 · 0 comments

Comments

@maliut
Copy link

maliut commented Aug 1, 2024

使用 adapter-qq 发送单聊主动消息

const userId = '064104A3FACEB533A9CB3B7C375E093A'
const content = 'xxx'
bot.sendPrivateMessage(userId, content)

查看报错信息,发现用户 id 被当成了群的 id,调用了群聊接口进行发送:

[W] qq POST /v2/groups/064104A3FACEB533A9CB3B7C375E093A/messages request: { data: { content: 'xxx', msg_type: 0, msg_id: undefined, msg_seq: undefined } }
[W] qq POST /v2/groups/064104A3FACEB533A9CB3B7C375E093A/messages response: { message: 'invalid request', code: 11255, err_code: 11255, trace_id: '34fbaddd179dd40294612dcf4e2733cd' }, trace id: 34fbaddd179dd40294612dcf4e2733cd

排查原因,发现目前是通过 session.isDirect 判断应调用单聊接口还是群聊接口:

const resp = this.session.isDirect
? await this.bot.internal.sendPrivateMessage(this.session.channelId, data)
: await this.bot.internal.sendMessage(this.session.channelId, data)

但发送主动消息,调用 sendPrivateMessage 方法时并未传入 session,导致默认被当成了群聊。


进一步排查应如何区分单聊和群聊。在 @satorijs/core 中,单聊相比群聊会额外调用 createDirectChannel

async sendMessage(channelId: string, content: h.Fragment, guildId?: string, options?: SendOptions) {
const messages = await this.createMessage(channelId, content, guildId, options)
return messages.map(message => message.id)
}
async sendPrivateMessage(userId: string, content: h.Fragment, guildId?: string, options?: SendOptions) {
const { id } = await this.createDirectChannel(userId, guildId ?? options?.session?.guildId)
return this.sendMessage(id, content, null, options)
}

虽然在 qq 适配器的 createDirectChannel 方法中已经指定了 Channel Type 为 Direct:

async createDirectChannel(id: string) {
return { id, type: Universal.Channel.Type.DIRECT }
}

sendPrivateMessage 方法只使用了 id,无视了 type。而 qq 群场景中,群的 openId 和用户的 openId 格式相同,难以通过 id 格式区分群和私聊。


可能的解决方案:

  1. 仿照 qq 频道的做法,在 qq 群的 createDirectChannel 方法中,为 id 拼接一个特殊的前/后缀,将其与普通 openId 的格式区分开来,并以此判断调用单聊还是群聊接口。算是一个比较取巧的做法。
  2. 从更严谨的角度考虑,当调用方显式调用 sendPrivateMessage 方法时,就必然意味着要调用单聊接口。因此 sendPrivateMessage 方法不应无视 createDirectChannel 返回的 type 参数,而应将它作为判断单聊还是群聊的标准。不过这样修改的话,改动就相对大些。
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant