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

feat(qq): internal api, logging, retries #230

Merged
merged 7 commits into from
Jan 24, 2024
Merged
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
13 changes: 9 additions & 4 deletions adapters/qq/src/bot/guild.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Bot, Context, Quester, Universal } from '@satorijs/satori'
import { QQBot } from '.'
import { decodeChannel, decodeGuild, decodeGuildMember, decodeMessage, decodeUser } from '../utils'
import { GuildInternal } from '../internal/guild'
import { GuildInternal } from '../internal'
import { QQGuildMessageEncoder } from '../message'

export namespace QQGuildBot {
Expand All @@ -22,7 +22,7 @@ export class QQGuildBot<C extends Context = Context> extends Bot<C> {
this.parent = config.parent
this.parent.guildBot = this
this.platform = 'qqguild'
this.internal = new GuildInternal(() => config.parent.guildHttp)
this.internal = new GuildInternal(this, () => config.parent.guildHttp)
this.http = config.parent.guildHttp
}

Expand Down Expand Up @@ -77,7 +77,9 @@ export class QQGuildBot<C extends Context = Context> extends Bot<C> {
}

async muteGuildMember(guildId: string, userId: string, duration: number) {
await this.internal.muteGuildMember(guildId, userId, duration)
await this.internal.muteGuildMember(guildId, userId, {
mute_seconds: Math.floor(duration / 1000),
})
}

async getReactionList(channelId: string, messageId: string, emoji: string, next?: string): Promise<Universal.List<Universal.User>> {
Expand Down Expand Up @@ -121,7 +123,10 @@ export class QQGuildBot<C extends Context = Context> extends Bot<C> {
async createDirectChannel(id: string, guild_id?: string) {
let input_guild_id = guild_id
if (guild_id?.includes('_')) input_guild_id = guild_id.split('_')[0] // call sendPM directly from DM channel
const dms = await this.internal.createDMS(id, input_guild_id)
const dms = await this.internal.createDMS({
recipient_id: id,
source_guild_id: input_guild_id,
})
return { id: `${dms.guild_id}_${input_guild_id}`, type: Universal.Channel.Type.DIRECT }
}
}
6 changes: 4 additions & 2 deletions adapters/qq/src/bot/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Bot, Context, Quester, Schema, Universal } from '@satorijs/satori'
import { WsClient } from '../ws'
import * as QQ from '../types'
import { QQGuildBot } from './guild'
import { GroupInternal } from '../internal/group'
import { QQMessageEncoder } from '../message'
import { GroupInternal } from '../internal'

interface GetAppAccessTokenResult {
access_token: string
Expand Down Expand Up @@ -39,7 +39,7 @@ export class QQBot<C extends Context = Context> extends Bot<C, QQBot.Config> {
this.ctx.plugin(QQGuildBot, {
parent: this,
})
this.internal = new GroupInternal(() => this.groupHttp)
this.internal = new GroupInternal(this, () => this.groupHttp)
this.ctx.plugin(WsClient, this)
}

Expand Down Expand Up @@ -103,6 +103,7 @@ export class QQBot<C extends Context = Context> extends Bot<C, QQBot.Config> {
export namespace QQBot {
export interface Config extends QQ.Options, WsClient.Config {
intents?: number
retryWhen: number[]
}

export const Config: Schema<Config> = Schema.intersect([
Expand All @@ -115,6 +116,7 @@ export namespace QQBot {
endpoint: Schema.string().role('link').description('要连接的服务器地址。').default('https://api.sgroup.qq.com/'),
authType: Schema.union(['bot', 'bearer'] as const).description('采用的验证方式。').default('bot'),
intents: Schema.bitset(QQ.Intents).description('需要订阅的机器人事件。'),
retryWhen: Schema.array(Number).description('发送消息遇到平台错误码时重试。').default([]),
}),
WsClient.Config,
] as const)
Expand Down
5 changes: 2 additions & 3 deletions adapters/qq/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as QQ from './types'
import { QQBot } from './bot'
import { GroupInternal } from './internal/group'
import { GuildInternal } from './internal/guild'
import { GroupInternal, GuildInternal } from './internal'

export { QQ }

Expand All @@ -27,5 +26,5 @@ declare module '@satorijs/core' {
qqguild?: QQ.Payload & GuildInternal
}

interface Events extends QQEvents {}
interface Events extends QQEvents { }
}
80 changes: 29 additions & 51 deletions adapters/qq/src/internal/group.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,37 @@
import { Quester } from '@satorijs/satori'
import * as QQ from '../types'
import { GroupInternal } from '.'

export class GroupInternal {
constructor(private http: () => Quester) { }

async sendPrivateMessage(openid: string, data: QQ.Message.Request) {
return this.http().post<{
sendResult: {
msg_id: string
err_msg: string
index: string
}
// id: string
// timestamp: number
}>(`/v2/users/${openid}/messages`, data)
}

async sendMessage(group_openid: string, data: QQ.Message.Request) {
return this.http().post<{
group_code: string
msg: string
declare module './internal' {
interface GroupInternal {
sendMessage(channel_id: string, data: QQ.Message.Request): Promise<{
id: string
timestamp: string
} & {
code: number
message: string
data: any
}>(`/v2/groups/${group_openid}/messages`, data)
}>
sendPrivateMessage(openid: string, data: QQ.Message.Request): Promise<any>
sendFilePrivate(openid: string, data: QQ.Message.File.Request): Promise<any>
sendFileGuild(group_openid: string, data: QQ.Message.File.Request): Promise<any>
acknowledgeInteraction(interaction_id: string, code: number): Promise<any>
}

async sendFilePrivate(openid: string, data: QQ.Message.File.Request) {
return this.http().post<QQ.Message.File.Response>(`/v2/users/${openid}/files`, data)
}

async sendFileGuild(group_openid: string, data: QQ.Message.File.Request) {
return this.http().post<QQ.Message.File.Response>(`/v2/groups/${group_openid}/files`, data)
}

// @TODO enum
async acknowledgeInteraction(interaction_id: string, code: number) {
return this.http().put(`/interactions/${interaction_id}`, {
code,
})
}

// async getGuildMembers(group_openid: string, start_index: 0) {
// return this.http().get<{
// members: {
// member_openid: string
// join_timestamp: number
// }[]
// next_index: number
// }>(`/v2/groups/${group_openid}/members`, {
// params: {
// limit: 500,
// start_index,
// },
// })
// }
}

GroupInternal.define(false, {
'/v2/groups/{channel.id}/messages': {
POST: 'sendMessage',
},
'/v2/users/{user.id}/messages': {
POST: 'sendPrivateMessage',
},
'/v2/users/{user.id}/files': {
POST: 'sendFilePrivate',
},
'/v2/groups/{channel.id}/files': {
POST: 'sendFileGuild',
},
'/interactions/{interaction.id}/{interaction.token}/callback': {
POST: 'acknowledgeInteraction',
},
})
Loading
Loading