Skip to content

Commit

Permalink
feat(satori): implement new protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Sep 11, 2023
1 parent cae2070 commit 2a24e77
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 45 deletions.
38 changes: 17 additions & 21 deletions adapters/discord/src/bot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Bot, Context, defineProperty, Fragment, h, isNullable, Logger, Quester, Schema, SendOptions, Universal } from '@satorijs/satori'
import { decodeChannel, decodeGuild, decodeMessage, decodeRole, decodeUser, encodeRole } from './utils'
import * as Discord from './utils'
import { DiscordMessageEncoder } from './message'
import { Internal, Webhook } from './types'
Expand Down Expand Up @@ -67,7 +66,7 @@ export class DiscordBot extends Bot<DiscordBot.Config> {

async getSelf() {
const data = await this.internal.getCurrentUser()
return decodeUser(data)
return Discord.decodeUser(data)
}

async deleteMessage(channelId: string, messageId: string) {
Expand All @@ -88,37 +87,34 @@ export class DiscordBot extends Bot<DiscordBot.Config> {

async getMessage(channelId: string, messageId: string) {
const data = await this.internal.getChannelMessage(channelId, messageId)
return await decodeMessage(this, data)
return await Discord.decodeMessage(this, data)
}

async getMessageList(channelId: string, before?: string) {
const messages = await this.internal.getChannelMessages(channelId, { before, limit: 100 })
const data = await Promise.all(messages.reverse().map(data => decodeMessage(this, data, {}, false)))
const data = await Promise.all(messages.reverse().map(data => Discord.decodeMessage(this, data, {}, false)))
return { data, next: data[0]?.messageId }
}

async getUser(userId: string) {
const data = await this.internal.getUser(userId)
return decodeUser(data)
return Discord.decodeUser(data)
}

async getGuildMemberList(guildId: string, after?: string) {
const users = await this.internal.listGuildMembers(guildId, { after, limit: 1000 })
const data = users.map(v => decodeUser(v.user))
return { data, next: data[999]?.userId }
const data = users.map(v => Discord.decodeGuildMember(v))
return { data, next: data[999]?.user.id }
}

async getChannel(channelId: string) {
const data = await this.internal.getChannel(channelId)
return decodeChannel(data)
return Discord.decodeChannel(data)
}

async getGuildMember(guildId: string, userId: string) {
const member = await this.internal.getGuildMember(guildId, userId)
return {
...decodeUser(member.user),
nickname: member.nick,
}
return Discord.decodeGuildMember(member)
}

async kickGuildMember(guildId: string, userId: string) {
Expand All @@ -127,18 +123,18 @@ export class DiscordBot extends Bot<DiscordBot.Config> {

async getGuild(guildId: string) {
const data = await this.internal.getGuild(guildId)
return decodeGuild(data)
return Discord.decodeGuild(data)
}

async getGuildList(after?: string) {
const guilds = await this.internal.getCurrentUserGuilds({ after, limit: 200 })
const data = guilds.map(decodeGuild)
const data = guilds.map(Discord.decodeGuild)
return { data, next: data[199]?.id }
}

async getChannelList(guildId: string) {
const channels = await this.internal.getGuildChannels(guildId)
return { data: channels.map(decodeChannel) }
return { data: channels.map(Discord.decodeChannel) }
}

createReaction(channelId: string, messageId: string, emoji: string) {
Expand All @@ -163,7 +159,7 @@ export class DiscordBot extends Bot<DiscordBot.Config> {

async getReactionList(channelId: string, messageId: string, emoji: string, after?: string) {
const data = await this.internal.getReactions(channelId, messageId, emoji, { after, limit: 100 })
return { data: data.map(decodeUser), next: data[99]?.id }
return { data: data.map(Discord.decodeUser), next: data[99]?.id }
}

setGuildMemberRole(guildId: string, userId: string, roleId: string) {
Expand All @@ -176,16 +172,16 @@ export class DiscordBot extends Bot<DiscordBot.Config> {

async getGuildRoleList(guildId: string) {
const data = await this.internal.getGuildRoles(guildId)
return { data: data.map(decodeRole) }
return { data: data.map(Discord.decodeRole) }
}

async createGuildRole(guildId: string, data: Partial<Universal.Role>) {
const role = await this.internal.createGuildRole(guildId, encodeRole(data))
async createGuildRole(guildId: string, data: Partial<Universal.GuildRole>) {
const role = await this.internal.createGuildRole(guildId, Discord.encodeRole(data))
return role.id
}

async modifyGuildRole(guildId: string, roleId: string, data: Partial<Universal.Role>) {
await this.internal.modifyGuildRole(guildId, roleId, encodeRole(data))
async modifyGuildRole(guildId: string, roleId: string, data: Partial<Universal.GuildRole>) {
await this.internal.modifyGuildRole(guildId, roleId, Discord.encodeRole(data))
}

deleteGuildRole(guildId: string, roleId: string) {
Expand Down
14 changes: 12 additions & 2 deletions adapters/discord/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,23 @@ export const sanitize = (val: string) =>
.replace(/@here/g, () => '\\@here')

export const decodeUser = (user: Discord.User): Universal.User => ({
id: user.id,
name: user.username,
userId: user.id,
avatar: `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png`,
username: user.username,
discriminator: user.discriminator,
isBot: user.bot || false,
})

export const decodeGuildMember = (member: Discord.GuildMember): Universal.GuildMember => ({
...decodeUser(member.user),
user: decodeUser(member.user),
nickname: member.nick,
roles: member.roles,
avatar: member.user.avatar,
})

export const decodeGuild = (data: Discord.Guild): Universal.Guild => ({
id: data.id,
name: data.name,
Expand All @@ -37,12 +47,12 @@ export const decodeAuthor = (author: Discord.User): Universal.Author => ({
nickname: author.username,
})

export const decodeRole = (role: Discord.Role): Universal.Role => ({
export const decodeRole = (role: Discord.Role): Universal.GuildRole => ({
...role,
permissions: BigInt(role.permissions),
})

export const encodeRole = (role: Partial<Universal.Role>): Partial<Discord.Role> => ({
export const encodeRole = (role: Partial<Universal.GuildRole>): Partial<Discord.Role> => ({
...role,
permissions: role.permissions && '' + role.permissions,
})
Expand Down
8 changes: 4 additions & 4 deletions adapters/kook/src/bot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Bot, Context, Fragment, h, Quester, Schema, SendOptions, Universal } from '@satorijs/satori'
import { adaptAuthor, adaptGroup, adaptMessage, adaptUser, decodeRole, encodeRole } from './utils'
import { adaptGroup, adaptMessage, adaptUser, decodeGuildMember, decodeRole, encodeRole } from './utils'
import * as Kook from './types'
import FormData from 'form-data'
import { WsClient } from './ws'
Expand Down Expand Up @@ -94,7 +94,7 @@ export class KookBot<T extends KookBot.Config = KookBot.Config> extends Bot<T> {

async getGuildMemberList(guild_id: string) {
const { items } = await this.request<Kook.GuildUserList>('GET', '/guild/user-list', { guild_id })
return { data: items.map(adaptAuthor) }
return { data: items.map(decodeGuildMember) }
}

async setGroupNickname(guild_id: string, user_id: string, nickname: string) {
Expand Down Expand Up @@ -153,15 +153,15 @@ export class KookBot<T extends KookBot.Config = KookBot.Config> extends Bot<T> {
return { data: items.map(decodeRole) }
}

async createGuildRole(guildId: string, data: Partial<Universal.Role>) {
async createGuildRole(guildId: string, data: Partial<Universal.GuildRole>) {
const role = await this.internal.createGuildRole({
guild_id: guildId,
...data,
})
return role.role_id.toString()
}

async modifyGuildRole(guildId: string, roleId: string, data: Partial<Universal.Role>) {
async modifyGuildRole(guildId: string, roleId: string, data: Partial<Universal.GuildRole>) {
await this.internal.updateGuildRole({
guild_id: guildId,
...encodeRole(data),
Expand Down
12 changes: 10 additions & 2 deletions adapters/kook/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,26 @@ export const adaptGroup = (data: Kook.Guild): Universal.Guild => ({
})

export const adaptUser = (user: Kook.User): Universal.User => ({
id: user.id,
name: user.username,
userId: user.id,
avatar: user.avatar,
username: user.username,
discriminator: user.identify_num,
})

export const decodeGuildMember = (member: Kook.Author): Universal.GuildMember => ({
...adaptUser(member),
user: adaptUser(member),
nickname: member.nickname,
})

export const adaptAuthor = (author: Kook.Author): Universal.Author => ({
...adaptUser(author),
nickname: author.nickname,
})

export const decodeRole = (role: Kook.GuildRole): Universal.Role => ({
export const decodeRole = (role: Kook.GuildRole): Universal.GuildRole => ({
...role,
id: '' + role.role_id,
permissions: BigInt(role.permissions),
Expand All @@ -34,7 +42,7 @@ function encodeBit(value: boolean) {
return isNullable(value) ? value : value ? 1 : 0
}

export const encodeRole = (role: Partial<Universal.Role>): Partial<Kook.GuildRole> => ({
export const encodeRole = (role: Partial<Universal.GuildRole>): Partial<Kook.GuildRole> => ({
...role,
role_id: +role.id,
permissions: role.permissions && Number(role.permissions),
Expand Down
11 changes: 9 additions & 2 deletions adapters/line/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export class LineBot extends Bot<LineBot.Config> {
async getSelf() {
const { userId, displayName, pictureUrl } = await this.internal.getBotInfo()
return {
id: userId,
name: displayName,
userId,
nickname: displayName,
avatar: pictureUrl,
Expand All @@ -57,7 +59,7 @@ export class LineBot extends Bot<LineBot.Config> {
start,
limit: 1000,
})
return { data: userIds.map(v => ({ userId: v })), next }
return { data: userIds.map(v => ({ id: v, userId: v })), next }
}

async getGuild(guildId: string) {
Expand All @@ -72,12 +74,17 @@ export class LineBot extends Bot<LineBot.Config> {

async getGuildMemberList(guildId: string, start?: string) {
const { memberIds, next } = await this.internal.getGroupMembersIds(guildId, { start })
return { data: memberIds.map(v => ({ userId: v })), next }
return { data: memberIds.map(id => ({ user: { id }, userId: id })), next }
}

async getGuildMember(guildId: string, userId: string) {
const res = await this.internal.getGroupMemberProfile(guildId, userId)
return {
user: {
id: res.userId,
name: res.displayName,
avatar: res.pictureUrl,
},
userId: res.userId,
nickname: res.displayName,
avatar: res.pictureUrl,
Expand Down
6 changes: 6 additions & 0 deletions adapters/matrix/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ export class MatrixBot extends Bot<MatrixBot.Config> {
let avatar: string
if (profile.avatar_url) avatar = this.internal.getAssetUrl(profile.avatar_url)
return {
id: userId,
name: profile.displayname,
userId,
avatar,
username: userId,
Expand Down Expand Up @@ -111,6 +113,10 @@ export class MatrixBot extends Bot<MatrixBot.Config> {
.map(event => {
const content = event.content as Matrix.M_ROOM_MEMBER
return {
user: {
id: event.state_key,
name: event.state_key,
},
userId: event.state_key,
username: event.state_key,
nickname: content.displayname,
Expand Down
2 changes: 1 addition & 1 deletion adapters/onebot/src/bot/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class OneBotMessageEncoder extends MessageEncoder<BaseBot> {
this.stack[1].children.push({
type: 'node',
data: {
name: author.nickname || author.username || this.bot.nickname || this.bot.username,
name: author.nickname || author.username || this.bot.username,
uin: author.userId || this.bot.userId,
content: this.children as any,
time: `${Math.floor((+author.time || Date.now()) / 1000)}`,
Expand Down
19 changes: 13 additions & 6 deletions adapters/onebot/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,38 @@ export * from './types'
const logger = new Logger('onebot')

export const adaptUser = (user: OneBot.AccountInfo): Universal.User => ({
id: user.tiny_id || user.user_id.toString(),
name: user.nickname,
userId: user.tiny_id || user.user_id.toString(),
avatar: user.user_id ? `http://q.qlogo.cn/headimg_dl?dst_uin=${user.user_id}&spec=640` : undefined,
username: user.nickname,
})

export const adaptGuildMember = (user: OneBot.SenderInfo): Universal.GuildMember => ({
...adaptUser(user),
user: adaptUser(user),
nickname: user.card,
roles: [user.role],
})

export const adaptQQGuildMemberInfo = (user: OneBot.GuildMemberInfo): Universal.GuildMember => ({
userId: user.tiny_id,
username: user.nickname,
user: {
id: user.tiny_id,
name: user.nickname,
isBot: user.role_name === '机器人',
},
nickname: user.nickname,
roles: user.role_name ? [user.role_name] : [],
isBot: user.role_name === '机器人',
})

export const adaptQQGuildMemberProfile = (user: OneBot.GuildMemberProfile): Universal.GuildMember => ({
userId: user.tiny_id,
username: user.nickname,
user: {
id: user.tiny_id,
name: user.nickname,
isBot: user.roles?.some(r => r.role_name === '机器人'),
},
nickname: user.nickname,
roles: user.roles?.map(r => r.role_name) || [],
isBot: user.roles?.some(r => r.role_name === '机器人'),
})

export const adaptAuthor = (user: OneBot.SenderInfo, anonymous?: OneBot.AnonymousInfo): Universal.Author => ({
Expand Down
3 changes: 2 additions & 1 deletion adapters/qqguild/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ export const adaptGuild = (guild: QQGuild.Guild): Universal.Guild => ({
})

export const adaptUser = (user: QQGuild.User): Universal.User => ({
id: user.id,
name: user.username,
isBot: user.bot,
avatar: user.avatar,
userId: user.id,
username: user.username,
nickname: user.username,
})
8 changes: 5 additions & 3 deletions adapters/slack/src/bot.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Bot, Context, Fragment, Quester, Schema, SendOptions } from '@satorijs/satori'
import { WsClient } from './ws'
import { HttpServer } from './http'
import { adaptChannel, adaptGuild, adaptMessage, adaptUser } from './utils'
import { adaptChannel, adapteGuildMember, adaptGuild, adaptMessage, adaptUser } from './utils'
import { SlackMessageEncoder } from './message'
import { GenericMessageEvent, SlackChannel, SlackTeam, SlackUser } from './types'
import FormData from 'form-data'
Expand Down Expand Up @@ -42,6 +42,8 @@ export class SlackBot<T extends SlackBot.Config = SlackBot.Config> extends Bot<T
async getSelf() {
const data = await this.internal.authTest(Token.BOT)
return {
id: data.user_id,
name: data.user,
userId: data.user_id,
avatar: null,
username: data.user,
Expand Down Expand Up @@ -89,7 +91,7 @@ export class SlackBot<T extends SlackBot.Config = SlackBot.Config> extends Bot<T
async getGuildMemberList(guildId: string) {
// users:read
const { members } = await this.request<{ members: SlackUser[] }>('POST', '/users.list')
return { data: members.map(adaptUser) }
return { data: members.map(adapteGuildMember) }
}

async getChannel(channelId: string, guildId?: string) {
Expand Down Expand Up @@ -122,7 +124,7 @@ export class SlackBot<T extends SlackBot.Config = SlackBot.Config> extends Bot<T
user: userId,
})
return {
...adaptUser(user),
...adapteGuildMember(user),
nickname: user.profile.display_name,
}
}
Expand Down
Loading

0 comments on commit 2a24e77

Please sign in to comment.