Skip to content
New issue

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

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

Already on GitHub? Sign in 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 参数,而应将它作为判断单聊还是群聊的标准。不过这样修改的话,改动就相对大些。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant