Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion adapters/qq/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@
"devDependencies": {
"@noble/ed25519": "^2.1.0",
"@satorijs/core": "^4.6.1",
"@satorijs/protocol": "^1.7.0",
"cordis": "^3.18.1"
},
"peerDependencies": {
"@satorijs/core": "^4.6.1"
"@satorijs/core": "^4.6.1",
"@satorijs/protocol": "^1.7.0"
}
}
10 changes: 9 additions & 1 deletion adapters/qq/src/bot/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Bot, Context, HTTP, Schema, Universal } from '@satorijs/core'
import { Bot, Context, h, HTTP, Schema, Universal } from '@satorijs/core'
import { SendOptions } from '@satorijs/protocol'
import { WsClient } from '../ws'
import * as QQ from '../types'
import { QQGuildBot } from './guild'
Expand Down Expand Up @@ -110,6 +111,13 @@ export class QQBot<C extends Context = Context, T extends QQBot.Config = QQBot.C
return { id, type: Universal.Channel.Type.DIRECT }
}

async sendPrivateMessage(userId: string, content: h.Fragment, guildId?: string, options?: SendOptions) {
// core 只使用了 createDirectChannel 返回的 id,channel type 会在 MessageEncoder 中被丢弃,
// 导致主动私聊被当成群聊发送(/v2/groups/{openid}/messages)。此处显式标记,交由 encoder 选择接口。
const { id } = await this.createDirectChannel(userId)
return this.sendMessage(id, content, null, { ...options, direct: true })
}

async deleteMessage(channelId: string, messageId: string): Promise<void> {
// @TODO: need `private:`
try {
Expand Down
24 changes: 17 additions & 7 deletions adapters/qq/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,12 @@ export class QQMessageEncoder<C extends Context = Context> extends MessageEncode
private retry = false
reference: string

// 主动发送时没有真实 session 可依据(core 的 sendPrivateMessage 只使用 id,丢弃了 createDirectChannel 的 type),
// 而群 openid 与用户 openid 格式相同,无法从 id 区分,因此由 bot.sendPrivateMessage 显式标记。
private get isDirectSend() {
return this.options?.direct === true
}

// 先图后文
async flush() {
if (!this.content.trim() && !this.rows.flat().length && !this.attachedFile) {
Expand Down Expand Up @@ -256,16 +262,19 @@ export class QQMessageEncoder<C extends Context = Context> extends MessageEncode
}
const session = this.bot.session()
session.type = 'send'
const isDirect = this.isDirectSend || this.session.isDirect
const channelId = this.channelId || this.session.channelId
const send = async () => {
try {
const resp = this.session.isDirect
? await this.bot.internal.sendPrivateMessage(this.session.channelId, data)
: await this.bot.internal.sendMessage(this.session.channelId, data)
const resp = isDirect
? await this.bot.internal.sendPrivateMessage(channelId, data)
: await this.bot.internal.sendMessage(channelId, data)
if (resp.id && !resp.audit_id) {
session.messageId = resp.id
session.timestamp = new Date(resp.timestamp).valueOf()
session.channelId = this.session.channelId
session.channelId = channelId
session.guildId = this.session.guildId
session.isDirect = isDirect
session.app.emit(session, 'send', session)
this.results.push(session.event.message)
} else if (resp.audit_id && this.bot.config.intents & QQ.Intents.MESSAGE_AUDIT) {
Expand Down Expand Up @@ -356,10 +365,11 @@ export class QQMessageEncoder<C extends Context = Context> extends MessageEncode
if (fileData || fileDataBase64) {
data.file_data = fileDataBase64 ?? fileData.toString('base64')
}
if (this.session.isDirect) {
res = await this.bot.internal.sendFilePrivate(this.options.session.userId, data)
if (this.isDirectSend || this.session.isDirect) {
// 主动私聊的 channelId 就是用户 openid
res = await this.bot.internal.sendFilePrivate(this.channelId || this.options.session?.userId, data)
} else {
res = await this.bot.internal.sendFileGuild(this.session.channelId, data)
res = await this.bot.internal.sendFileGuild(this.channelId || this.session.channelId, data)
}
}
} catch (e) {
Expand Down
7 changes: 7 additions & 0 deletions adapters/qq/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1567,3 +1567,10 @@ export interface Button {
unsupport_tips?: string
}
}

declare module '@satorijs/protocol' {
interface SendOptions {
/** 由 QQBot.sendPrivateMessage 标记的主动私聊发送(群 openid 与用户 openid 格式相同,无法从 id 区分) */
direct?: boolean
}
}