Skip to content

Commit

Permalink
feat(qqguild): implement bot api
Browse files Browse the repository at this point in the history
  • Loading branch information
XxLittleCxX committed Sep 16, 2023
1 parent 6e82ae7 commit 806599d
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 9 deletions.
60 changes: 55 additions & 5 deletions adapters/qqguild/src/bot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Bot, Context, defineProperty, Quester, Schema, Universal } from '@satorijs/satori'
import { adaptUser, decodeMessage } from './utils'
import { adaptChannel, adaptGuild, adaptUser, decodeGuildMember, decodeMessage } from './utils'
import { QQGuildMessageEncoder } from './message'
import { WsClient } from './ws'
import { Internal } from './internal'
Expand Down Expand Up @@ -41,10 +41,60 @@ export class QQGuildBot extends Bot<QQGuildBot.Config> {
return user
}

// async getGuildList() {
// const guilds = await this.internal.guilds
// return { data: guilds.map(adaptGuild) }
// }
async getGuildList(next?: string) {
const guilds = await this.internal.getGuilds()
return { data: guilds.map(adaptGuild) }
}

async getGuild(guildId: string) {
const guild = await this.internal.getGuild(guildId)
return adaptGuild(guild)
}

async getChannelList(guildId: string, next?: string): Promise<Universal.List<Universal.Channel>> {
const channels = await this.internal.getChannels(guildId)
return { data: channels.map(adaptChannel) }
}

async getChannel(channelId: string): Promise<Universal.Channel> {
const channel = await this.internal.getChannel(channelId)
return adaptChannel(channel)
}

async getGuildMemberList(guildId: string, next?: string): Promise<Universal.List<Universal.GuildMember>> {
const members = await this.internal.getGuildMembers(guildId)
return { data: members.map(decodeGuildMember) }
}

async getGuildMember(guildId: string, userId: string): Promise<Universal.GuildMember> {
const member = await this.internal.getGuildMember(guildId, userId)
return decodeGuildMember(member)
}

async kickGuildMember(guildId: string, userId: string) {
await this.internal.deleteGuildMember(guildId, userId)
}

async muteGuildMember(guildId: string, userId: string, duration: number) {
await this.internal.muteGuildMember(guildId, userId, duration)
}

async getReactionList(channelId: string, messageId: string, emoji: string, next?: string): Promise<Universal.List<Universal.User>> {
const [type, id] = emoji.split(':')
const { users } = await this.internal.getReactions(channelId, messageId, type, id)
return { data: users.map(adaptUser) }
}

async createReaction(channelId: string, messageId: string, emoji: string) {
const [type, id] = emoji.split(':')
await this.internal.createReaction(channelId, messageId, type, id)
}

async deleteReaction(channelId: string, messageId: string, emoji: string) {
const [type, id] = emoji.split(':')
await this.internal.deleteReaction(channelId, messageId, type, id)
}

async getMessage(channelId: string, messageId: string): Promise<Universal.Message> {
const r = await this.internal.getMessage(channelId, messageId)
return decodeMessage(this, r)
Expand Down
73 changes: 69 additions & 4 deletions adapters/qqguild/src/internal.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,89 @@
import { Quester } from '@satorijs/satori'
import { DMS, Message, User } from './types'
import * as QQGuild from './types'

export class Internal {
constructor(private http: Quester) { }

async getMe() {
return this.http.get<User>('/users/@me')
return this.http.get<QQGuild.User>('/users/@me')
}

/** https://bot.q.qq.com/wiki/develop/api/openapi/dms/post_dms.html */
async createDMS(recipient_id: string, source_guild_id: string) {
return this.http.post<DMS>('/users/@me/dms', {
return this.http.post<QQGuild.DMS>('/users/@me/dms', {
recipient_id, source_guild_id,
})
}

async getMessage(channelId: string, messageId: string) {
const { message } = await this.http.get<{
message: Message
message: QQGuild.Message
}>(`/channels/${channelId}/messages/${messageId}`)
return message
}

async getGuilds(params?: Partial<{
before: string
after: string
limit: number
}>) {
return this.http.get<QQGuild.Guild[]>('/users/@me/guilds', {
params,
})
}

async getGuild(guild_id: string) {
return this.http.get<QQGuild.Guild>(`/guilds/${guild_id}`)
}

async getChannels(guild_id: string) {
return this.http.get<QQGuild.Channel[]>(`/guilds/${guild_id}/channels`)
}

async getChannel(channel_id: string) {
return this.http.get<QQGuild.Channel>(`/channels/${channel_id}`)
}

async getGuildMembers(guild_id: string) {
return this.http.get<QQGuild.Member[]>(`/guilds/${guild_id}/members`)
}

async getGuildMember(guild_id: string, user_id: string) {
return this.http.get<QQGuild.Member>(`/guilds/${guild_id}/members/${user_id}`)
}

async deleteGuildMember(guild_id: string, user_id: string) {
return this.http.delete(`/guilds/${guild_id}/members/${user_id}`)
}

async getGuildRoles(guild_id: string) {
return this.http.get<QQGuild.Role[]>(`/guilds/${guild_id}/roles`)
}

async muteGuildMember(guild_id: string, user_id: string, duration: number) {
return this.http.patch(`/guilds/${guild_id}/members/${user_id}/mute`, {
mute_seconds: duration / 1000,
})
}

async getReactions(channel_id: string, message_id: string, type: string, id: string, params?: Partial<{
cookie: string
limit: number
}>) {
return this.http.get<{
cookie: string
is_end: boolean
users: Pick<QQGuild.User, 'id' | 'username' | 'avatar'>[]
}>(`/channels/${channel_id}/messages/${message_id}/reactions/${type}/${id}`, {
params,
})
}

async createReaction(channel_id: string, message_id: string, type: string, id: string) {
return this.http.put(`/channels/${channel_id}/messages/${message_id}/reactions/${type}/${id}`)
}

async deleteReaction(channel_id: string, message_id: string, type: string, id: string) {
return this.http.delete(`/channels/${channel_id}/messages/${message_id}/reactions/${type}/${id}`)
}
}
13 changes: 13 additions & 0 deletions adapters/qqguild/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,26 @@ export const adaptGuild = (guild: QQGuild.Guild): Universal.Guild => ({
guildName: guild.name,
})

export const adaptChannel = (channel: QQGuild.Channel): Universal.Channel => ({
id: channel.id,
name: channel.name,
channelId: channel.id,
channelName: channel.name,
})

export const adaptUser = (user: QQGuild.User): Universal.User => ({
id: user.id,
name: user.username,
isBot: user.bot,
avatar: user.avatar,
})

export const decodeGuildMember = (member: QQGuild.Member): Universal.GuildMember => ({
user: adaptUser(member.user),
nickname: member.nick,
roles: member.roles,
})

export async function decodeMessage(bot: QQGuildBot, msg: QQGuild.Message, session: Partial<Session> = {}): Promise<Universal.Message> {
const { id: messageId, author, guild_id, channel_id, timestamp } = msg
session.type = 'message'
Expand Down

0 comments on commit 806599d

Please sign in to comment.