diff --git a/adapters/dingtalk/src/bot.ts b/adapters/dingtalk/src/bot.ts index 742e473d..d213a8cf 100644 --- a/adapters/dingtalk/src/bot.ts +++ b/adapters/dingtalk/src/bot.ts @@ -37,8 +37,9 @@ export class DingtalkBot extends Bot { return this.toJSON() } - async stop() { + stop() { clearTimeout(this.refreshTokenTimer) + return super.stop() } public token: string diff --git a/adapters/dingtalk/src/http.ts b/adapters/dingtalk/src/http.ts index a09c8b11..0c58400d 100644 --- a/adapters/dingtalk/src/http.ts +++ b/adapters/dingtalk/src/http.ts @@ -6,6 +6,7 @@ import { decodeMessage } from './utils' export class HttpServer extends Adapter.Server { logger = new Logger('dingtalk') + constructor(ctx: Context, bot: DingtalkBot) { super() } @@ -13,6 +14,7 @@ export class HttpServer extends Adapter.Server { async start(bot: DingtalkBot) { await bot.refreshToken() await bot.getLogin() + // https://open.dingtalk.com/document/orgapp/receive-message bot.ctx.router.post('/dingtalk', async (ctx) => { const timestamp = ctx.get('timestamp') diff --git a/adapters/dingtalk/src/utils.ts b/adapters/dingtalk/src/utils.ts index 83264b79..27298a74 100644 --- a/adapters/dingtalk/src/utils.ts +++ b/adapters/dingtalk/src/utils.ts @@ -16,14 +16,14 @@ export async function decodeMessage(bot: DingtalkBot, body: Message): Promise { const url = await this.getUrl() const result = await this.bot.http.post(url, data, { headers }) const session = this.bot.session() - const message = await decodeMessage(this.bot, result, session.data.message = {}, session.data) + const message = await decodeMessage(this.bot, result, session.body.message = {}, session.body) session.app.emit(session, 'send', session) this.results.push(session) diff --git a/adapters/discord/src/utils.ts b/adapters/discord/src/utils.ts index b8e4189e..7bdc600b 100644 --- a/adapters/discord/src/utils.ts +++ b/adapters/discord/src/utils.ts @@ -182,7 +182,7 @@ export async function adaptSession(bot: DiscordBot, input: Discord.Gateway.Paylo } catch (e) {} } session.type = 'message' - await decodeMessage(bot, input.d, session.data.message = {}, session.data) + await decodeMessage(bot, input.d, session.body.message = {}, session.body) // dc 情况特殊 可能有 embeds 但是没有消息主体 // if (!session.content) return } else if (input.t === 'MESSAGE_UPDATE') { @@ -190,7 +190,7 @@ export async function adaptSession(bot: DiscordBot, input: Discord.Gateway.Paylo const message = await bot.internal.getChannelMessage(input.d.channel_id, input.d.id) // Unlike creates, message updates may contain only a subset of the full message object payload // https://discord.com/developers/docs/topics/gateway-events#message-update - await decodeMessage(bot, message, session.data.message = {}, session.data) + await decodeMessage(bot, message, session.body.message = {}, session.body) const channel = await bot.internal.getChannel(input.d.channel_id) setupMessageGuildId(session, channel.guild_id) // if (!session.content) return @@ -218,12 +218,12 @@ export async function adaptSession(bot: DiscordBot, input: Discord.Gateway.Paylo session.type = 'guild-role-added' session.guildId = input.d.guild_id session.roleId = input.d.role.id - session.data.role = decodeRole(input.d.role) + session.body.role = decodeRole(input.d.role) } else if (input.t === 'GUILD_ROLE_UPDATE') { session.type = 'guild-role-updated' session.guildId = input.d.guild_id session.roleId = input.d.role.id - session.data.role = decodeRole(input.d.role) + session.body.role = decodeRole(input.d.role) } else if (input.t === 'GUILD_ROLE_DELETE') { session.type = 'guild-role-added' session.guildId = input.d.guild_id @@ -243,7 +243,7 @@ export async function adaptSession(bot: DiscordBot, input: Discord.Gateway.Paylo session.userId = session.isDirect ? input.d.user.id : input.d.member.user.id session.messageId = input.d.id session.content = '' - session.data.argv = decodeArgv(data, command) + session.body.argv = decodeArgv(data, command) } else if (input.t === 'CHANNEL_UPDATE') { session.type = 'channel-updated' session.guildId = input.d.guild_id diff --git a/adapters/discord/src/ws.ts b/adapters/discord/src/ws.ts index efaf4289..b13f93e2 100644 --- a/adapters/discord/src/ws.ts +++ b/adapters/discord/src/ws.ts @@ -74,7 +74,7 @@ export class WsClient extends Adapter.WsClient { } if (parsed.op === Gateway.Opcode.DISPATCH) { - this.bot.ctx.emit('discord/' + parsed.t.toLowerCase().replace(/_/g, '-') as any, parsed) + this.bot.ctx.emit('satori/internal', 'discord/' + parsed.t.toLowerCase().replace(/_/g, '-'), parsed) if (parsed.t === 'READY') { this._sessionId = parsed.d.session_id this._resumeUrl = parsed.d.resume_gateway_url diff --git a/adapters/kook/src/message.ts b/adapters/kook/src/message.ts index 2fa103a3..e1cdbe2b 100644 --- a/adapters/kook/src/message.ts +++ b/adapters/kook/src/message.ts @@ -50,7 +50,7 @@ export class KookMessageEncoder extends MessageEncoder { }) const { url } = await this.bot.request('POST', '/asset/create', payload, payload.getHeaders()) return url - } else if (!attrs.url.includes('kaiheila')) { + } else if (!attrs.url.includes('kookapp.cn')) { const res = await this.bot.ctx.http.get(attrs.url, { headers: { accept: type + '/*' }, responseType: 'stream', diff --git a/adapters/kook/src/utils.ts b/adapters/kook/src/utils.ts index a224c234..cf6e0f7e 100644 --- a/adapters/kook/src/utils.ts +++ b/adapters/kook/src/utils.ts @@ -128,16 +128,13 @@ function adaptMessageCreate(data: Kook.Data, meta: Kook.MessageExtra, session: P session.isDirect = true session.channelId = meta.code } - session.data.channel.name = meta.channel_name - // if (!meta.author) { - console.log(data, meta) - // } - adaptMessageSession(data, meta, session.data.message = {}, session.data) + session.body.channel.name = meta.channel_name + adaptMessageSession(data, meta, session.body.message = {}, session.body) } function adaptMessageModify(data: Kook.Data, meta: Kook.NoticeBody, session: Session) { session.channelId = meta.channel_id - adaptMessageSession(data, meta, session.data.message = {}, session.data) + adaptMessageSession(data, meta, session.body.message = {}, session.body) } function adaptReaction(body: Kook.NoticeBody, session: Partial) { @@ -149,10 +146,13 @@ function adaptReaction(body: Kook.NoticeBody, session: Partial) { export function adaptSession(bot: Bot, input: any) { const session = bot.session() - defineProperty(session, 'kook', Object.assign(Object.create(bot.internal), input)) + session.body._data = input + const internal = Object.create(bot.internal) + Object.assign(internal, input) + defineProperty(session, 'kook', internal) if (input.type === Kook.Type.system) { const { type, body } = input.extra as Kook.Notice - bot.ctx.emit('kook/' + type.replace(/_/g, '-') as any, input.body) + bot.ctx.emit('satori/internal', 'kook/' + type.replace(/_/g, '-'), input.body) switch (type) { case 'updated_message': case 'updated_private_message': @@ -222,7 +222,7 @@ export function adaptSession(bot: Bot, input: any) { }[type] session.guildId = input.target_id session.roleId = '' + body.role_id - session.data.role = decodeRole(body) + session.body.role = decodeRole(body) break case 'added_block_list': case 'deleted_block_list': diff --git a/adapters/lark/src/utils.ts b/adapters/lark/src/utils.ts index 7b88e8d9..5a5468e1 100644 --- a/adapters/lark/src/utils.ts +++ b/adapters/lark/src/utils.ts @@ -71,9 +71,9 @@ export function adaptMessage(bot: FeishuBot, data: Events['im.message.receive_v1 export function adaptSession(bot: FeishuBot, body: AllEvents): Session { const session = bot.session() + session.body._data = body const internal = Object.create(bot.internal) Object.assign(internal, body) - defineProperty(session, 'feishu', internal) defineProperty(session, 'lark', internal) switch (body.type) { diff --git a/adapters/mail/src/utils.ts b/adapters/mail/src/utils.ts index 5bbe9f94..19d665f6 100644 --- a/adapters/mail/src/utils.ts +++ b/adapters/mail/src/utils.ts @@ -125,7 +125,7 @@ export async function adaptMessage( export async function dispatchSession(bot: MailBot, mail: ParsedMail) { const session = bot.session() session.type = 'message' - if (!await adaptMessage(bot, mail, session.data.message = {}, session.data)) { + if (!await adaptMessage(bot, mail, session.body.message = {}, session.body)) { return null } defineProperty(session, 'mail', mail) diff --git a/adapters/matrix/src/utils.ts b/adapters/matrix/src/utils.ts index 8d8506c2..f2896a9d 100644 --- a/adapters/matrix/src/utils.ts +++ b/adapters/matrix/src/utils.ts @@ -71,7 +71,7 @@ export async function adaptSession(bot: MatrixBot, event: Matrix.ClientEvent): P } else { session.type = 'message' } - if (!await adaptMessage(bot, event, session.data.message = {}, session.data)) return null + if (!await adaptMessage(bot, event, session.body.message = {}, session.body)) return null return session } session.userId = event.sender @@ -140,8 +140,8 @@ export async function dispatchSession(bot: MatrixBot, event: Matrix.ClientEvent) const session = await adaptSession(bot, event) if (!session) return - defineProperty(session, 'matrix', Object.create(bot.internal)) - Object.assign(session.matrix, event) + const internal = Object.create(bot.internal) + defineProperty(session, 'matrix', Object.assign(internal, event)) bot.dispatch(session) } diff --git a/adapters/onebot/src/utils.ts b/adapters/onebot/src/utils.ts index c5b54d2e..f9226d05 100644 --- a/adapters/onebot/src/utils.ts +++ b/adapters/onebot/src/utils.ts @@ -151,8 +151,8 @@ export async function dispatchSession(bot: BaseBot, data: OneBot.Payload) { const session = await adaptSession(bot, data) if (!session) return - defineProperty(session, 'onebot', Object.create(bot.internal)) - Object.assign(session.onebot, data) + const internal = Object.create(bot.internal) + defineProperty(session, 'onebot', Object.assign(internal, data)) bot.dispatch(session) } @@ -162,7 +162,7 @@ export async function adaptSession(bot: BaseBot, data: OneBot.Payload) { session.type = data.post_type if (data.post_type === 'message' || data.post_type === 'message_sent') { - await adaptMessage(bot, data, session.data.message = {}, session.data) + await adaptMessage(bot, data, session.body.message = {}, session.body) if (data.post_type === 'message_sent' && !session.guildId) { session.channelId = 'private:' + data.target_id } diff --git a/adapters/qq/src/message.ts b/adapters/qq/src/message.ts index bf78e99e..f19a553b 100644 --- a/adapters/qq/src/message.ts +++ b/adapters/qq/src/message.ts @@ -80,7 +80,7 @@ export class QQMessageEncoder extends MessageEncoder { this.bot.ctx.logger('qq').debug(require('util').inspect(r, false, null, true)) const session = this.bot.session() session.type = 'send' - await decodeMessage(this.bot, r, session.data.message = {}, session.data) + await decodeMessage(this.bot, r, session.body.message = {}, session.body) if (this.session.isDirect) { session.guildId = this.session.guildId session.channelId = this.session.channelId diff --git a/adapters/qq/src/utils.ts b/adapters/qq/src/utils.ts index c34d3a86..56565a93 100644 --- a/adapters/qq/src/utils.ts +++ b/adapters/qq/src/utils.ts @@ -82,7 +82,7 @@ export async function adaptSession(bot: QQBot, input: QQ.DispatchPayload) { if (input.t === 'MESSAGE_CREATE' || input.t === 'AT_MESSAGE_CREATE' || input.t === 'DIRECT_MESSAGE_CREATE') { if (bot.config.type === 'private' && input.t === 'AT_MESSAGE_CREATE') return session.type = 'message' - await decodeMessage(bot, input.d, session.data.message = {}, session.data) + await decodeMessage(bot, input.d, session.body.message = {}, session.body) } else if (input.t === 'MESSAGE_REACTION_ADD') { if (input.d.target.type !== 'ReactionTargetType_MSG') return setupReaction(session, input.d) @@ -98,14 +98,14 @@ export async function adaptSession(bot: QQBot, input: QQ.DispatchPayload) { CHANNEL_DELETE: 'channel-deleted', }[input.t] session.guildId = input.d.guild_id - session.data.channel = decodeChannel(input.d) + session.body.channel = decodeChannel(input.d) } else if (input.t === 'GUILD_CREATE' || input.t === 'GUILD_UPDATE' || input.t === 'GUILD_DELETE') { session.type = { GUILD_CREATE: 'guild-added', GUILD_UPDATE: 'guild-updated', GUILD_DELETE: 'guild-deleted', }[input.t] - session.data.guild = decodeGuild(input.d) + session.body.guild = decodeGuild(input.d) } else if (input.t === 'DIRECT_MESSAGE_DELETE' || input.t === 'MESSAGE_DELETE' || input.t === 'PUBLIC_MESSAGE_DELETE') { if (bot.config.type === 'private' && input.t === 'PUBLIC_MESSAGE_DELETE') return session.type = 'message-deleted' diff --git a/adapters/qq/src/ws.ts b/adapters/qq/src/ws.ts index a7d62233..ceca955f 100644 --- a/adapters/qq/src/ws.ts +++ b/adapters/qq/src/ws.ts @@ -56,7 +56,7 @@ export class WsClient extends Adapter.WsClient { logger.warn('offline: server request reconnect') this.bot.socket?.close() } else if (parsed.op === Opcode.DISPATCH) { - this.bot.ctx.emit('qq/' + parsed.t.toLowerCase().replace(/_/g, '-') as any, parsed) + this.bot.ctx.emit('satori/internal', 'qq/' + parsed.t.toLowerCase().replace(/_/g, '-'), parsed) this._s = parsed.s if (parsed.t === 'READY') { this._sessionId = parsed.d.session_id diff --git a/adapters/satori/src/bot.ts b/adapters/satori/src/bot.ts index 88ffff82..ab8b59ae 100644 --- a/adapters/satori/src/bot.ts +++ b/adapters/satori/src/bot.ts @@ -4,7 +4,10 @@ import { WsClient } from './ws' export function transformKey(source: any, callback: (key: string) => string) { if (!source || typeof source !== 'object') return source if (Array.isArray(source)) return source.map(value => transformKey(value, callback)) - return Object.fromEntries(Object.entries(source).map(([key, value]) => [callback(key), transformKey(value, callback)])) + return Object.fromEntries(Object.entries(source).map(([key, value]) => { + if (key.startsWith('_')) return [key, value] + return [callback(key), transformKey(value, callback)] + })) } export class SatoriBot extends Bot { diff --git a/adapters/slack/src/message.ts b/adapters/slack/src/message.ts index abb15612..116fba94 100644 --- a/adapters/slack/src/message.ts +++ b/adapters/slack/src/message.ts @@ -38,7 +38,7 @@ export class SlackMessageEncoder extends MessageEncoder { }) if (!r.ok) throw new Error(r['error']) const session = this.bot.session() - await adaptMessage(this.bot, r.message, session.data.message = {}, session.data) + await adaptMessage(this.bot, r.message, session.body.message = {}, session.body) session.channelId = this.channelId session.app.emit(session, 'send', session) this.results.push(session) diff --git a/adapters/slack/src/utils.ts b/adapters/slack/src/utils.ts index 1dcfa80c..1d385802 100644 --- a/adapters/slack/src/utils.ts +++ b/adapters/slack/src/utils.ts @@ -137,7 +137,7 @@ export function adaptMessageDeleted(bot: SlackBot, event: MessageDeletedEvent, s session.messageId = event.previous_message.ts session.timestamp = Math.floor(Number(event.previous_message.ts) * 1000) - adaptMessage(bot, event.previous_message, session.data.message = {}, session.data) + adaptMessage(bot, event.previous_message, session.body.message = {}, session.body) } export function adaptSentAsset(file: File, session: Session) { @@ -169,7 +169,7 @@ export async function adaptSession(bot: SlackBot, payload: EnvelopedEvent { async addResult(result: Telegram.Message) { const session = this.bot.session() - await Telegram.decodeMessage(this.bot, result, session.data.message = {}, session.data) + await Telegram.decodeMessage(this.bot, result, session.body.message = {}, session.body) this.results.push(session) session.app.emit(session, 'send', session) } diff --git a/adapters/telegram/src/utils.ts b/adapters/telegram/src/utils.ts index aa9ad708..5fe61d15 100644 --- a/adapters/telegram/src/utils.ts +++ b/adapters/telegram/src/utils.ts @@ -9,7 +9,7 @@ const logger = new Logger('telegram') export const decodeUser = (data: Telegram.User): Universal.User => ({ id: data.id.toString(), name: data.username, - nick: data.first_name + (data.last_name ? ' ' + data.last_name : ''), + nickname: data.first_name + (data.last_name ? ' ' + data.last_name : ''), isBot: data.is_bot, userId: data.id.toString(), username: data.username, @@ -22,9 +22,17 @@ export const decodeGuildMember = (data: Telegram.ChatMember): Universal.GuildMem export async function handleUpdate(update: Telegram.Update, bot: TelegramBot) { logger.debug('receive %s', JSON.stringify(update)) + // Internal event: get update type from field name. + const subtype = Object.keys(update).filter(v => v !== 'update_id')[0] + if (subtype) { + bot.ctx.emit('satori/internal', `telegram/${subtype.replace(/_/g, '-')}`, update[subtype]) + } + const session = bot.session() - defineProperty(session, 'telegram', Object.create(bot.internal)) + session.body._data = update + const internal = Object.create(bot.internal) Object.assign(session.telegram, update) + defineProperty(session, 'telegram', internal) const message = update.message || update.edited_message || update.channel_post || update.edited_channel_post const isBotCommand = update.message && update.message.entities?.[0].type === 'bot_command' @@ -41,11 +49,11 @@ export async function handleUpdate(update: Telegram.Update, bot: TelegramBot) { if (isBotCommand) { session.type = 'interaction/command' - await decodeMessage(bot, message, session.data.message = {}, session.data) + await decodeMessage(bot, message, session.body.message = {}, session.body) session.content = session.content.slice(1) } else if (message) { session.type = update.message || update.channel_post ? 'message' : 'message-updated' - await decodeMessage(bot, message, session.data.message = {}, session.data) + await decodeMessage(bot, message, session.body.message = {}, session.body) } else if (update.chat_join_request) { session.timestamp = update.chat_join_request.date * 1000 session.type = 'guild-member-request' @@ -69,12 +77,6 @@ export async function handleUpdate(update: Telegram.Update, bot: TelegramBot) { } } - // Internal event: get update type from field name. - const subtype = Object.keys(update).filter(v => v !== 'update_id')[0] - if (subtype) { - bot.ctx.emit(`telegram/${subtype.replace(/_/g, '-')}`, update[subtype]) - } - bot.dispatch(session) } diff --git a/adapters/whatsapp/src/message.ts b/adapters/whatsapp/src/message.ts index 4b1540cc..47aa29f7 100644 --- a/adapters/whatsapp/src/message.ts +++ b/adapters/whatsapp/src/message.ts @@ -61,7 +61,7 @@ export class WhatsAppMessageEncoder extends MessageEncoder { session.channelId = this.channelId session.guildId = this.channelId session.isDirect = true - session.data.user = this.bot.user + session.body.user = this.bot.user session.timestamp = Date.now() session.app.emit(session, 'send', session) this.results.push(session) diff --git a/adapters/whatsapp/src/utils.ts b/adapters/whatsapp/src/utils.ts index 95a2e23d..aff8a10d 100644 --- a/adapters/whatsapp/src/utils.ts +++ b/adapters/whatsapp/src/utils.ts @@ -13,7 +13,7 @@ export async function decodeMessage(bot: WhatsAppBot, entry: Entry) { session.channelId = message.from session.guildId = message.from session.messageId = message.id - session.data.user = { + session.body.user = { id: message.from, name: change.value.contacts[0].profile.name, } diff --git a/packages/core/src/bot.ts b/packages/core/src/bot.ts index c7d06ce3..178efd2e 100644 --- a/packages/core/src/bot.ts +++ b/packages/core/src/bot.ts @@ -116,18 +116,18 @@ export abstract class Bot implements Login { return `${this.platform}:${this.selfId}` } - session(payload: Partial = {}) { - return new Session(this, payload) + session(data: Partial = {}) { + return new Session(this, data) } dispatch(session: Session) { if (!this.ctx.lifecycle.isActive) return - this.context.emit('internal/session', session) + this.context.emit('satori/session', session) const events: string[] = [session.type] - if (session.data.subtype) { - events.unshift(events[0] + '/' + session.data.subtype) - if (session.data.subsubtype) { - events.unshift(events[0] + '/' + session.data.subsubtype) + if (session.body.subtype) { + events.unshift(events[0] + '/' + session.body.subtype) + if (session.body.subsubtype) { + events.unshift(events[0] + '/' + session.body.subsubtype) } } for (const event of events) { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 0046178d..2dde9d30 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -87,7 +87,8 @@ Quester.createConfig = function createConfig(this, endpoint) { type EventCallback = (this: Session, session: Session, ...args: R) => T export interface Events extends cordis.Events, Record { - 'internal/session'(session: Session): void + 'satori/session'(session: Session): void + 'satori/internal'(type: string, data: any): void 'before-send': EventCallback, [SendOptions]> 'bot-added'(client: Bot): void 'bot-removed'(client: Bot): void diff --git a/packages/core/src/internal.ts b/packages/core/src/internal.ts index bc337216..67621998 100644 --- a/packages/core/src/internal.ts +++ b/packages/core/src/internal.ts @@ -24,6 +24,9 @@ export class Internal { constructor(private root: Context) { defineProperty(this, Context.current, root) + root.on('satori/internal', (type, data) => { + root.emit(type, data) + }) } protected get caller() { diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts index d42ecf8f..e71ff56b 100644 --- a/packages/core/src/session.ts +++ b/packages/core/src/session.ts @@ -33,14 +33,14 @@ export class Session { public id: number public bot: Bot public app: Context['root'] - public data: Omit + public body: Omit public locales: string[] = [] constructor(bot: Bot, payload: Partial) { payload.selfId ??= bot.selfId payload.platform ??= bot.platform payload.timestamp ??= Date.now() - this.data = payload as EventData + this.body = payload as EventData this.id = ++Session.counter Object.assign(this, payload) for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(payload))) { @@ -56,54 +56,64 @@ export class Session { initialize() {} + /** @deprecated */ + get data() { + return this.body + } + get isDirect() { - return this.data.channel.type === Channel.Type.DIRECT + return this.body.channel.type === Channel.Type.DIRECT } set isDirect(value) { - (this.data.channel ??= {} as Channel).type = value ? Channel.Type.DIRECT : Channel.Type.TEXT + (this.body.channel ??= {} as Channel).type = value ? Channel.Type.DIRECT : Channel.Type.TEXT } - /** @deprecated use `session.member` and `session.user` instead */ get author(): GuildMember & User { - return { user: this.data.user, ...this.data.user, ...this.data.member } + return { + ...this.body.user, + ...this.body.member, + userId: this.body.user?.id, + username: this.body.user?.name, + nickname: this.body.member?.name, + } } get uid() { - return `${this.data.platform}:${this.userId}` + return `${this.body.platform}:${this.userId}` } get gid() { - return `${this.data.platform}:${this.guildId}` + return `${this.body.platform}:${this.guildId}` } get cid() { - return `${this.data.platform}:${this.channelId}` + return `${this.body.platform}:${this.channelId}` } get fid() { - return `${this.data.platform}:${this.channelId}:${this.userId}` + return `${this.body.platform}:${this.channelId}:${this.userId}` } get sid() { - return `${this.data.platform}:${this.data.selfId}` + return `${this.body.platform}:${this.body.selfId}` } get elements() { - return this.data.message?.elements + return this.body.message?.elements } set elements(value) { - this.data.message ??= {} - this.data.message.elements = value + this.body.message ??= {} + this.body.message.elements = value } get content(): string | undefined { - return this.data.message?.elements?.join('') + return this.body.message?.elements?.join('') } set content(value: string | undefined) { - (this.data.message ??= {}).elements = isNullable(value) ? value : h.parse(value) + (this.body.message ??= {}).elements = isNullable(value) ? value : h.parse(value) } async transform(elements: h[]): Promise { @@ -114,7 +124,7 @@ export class Session { } toJSON(): EventData { - return { ...this.data, id: this.id } + return { ...this.body, id: this.id } } static accessor(name: string, keys: string[]) { @@ -140,7 +150,9 @@ Session.accessor('platform', ['platform']) Session.accessor('timestamp', ['timestamp']) Session.accessor('userId', ['user', 'id']) Session.accessor('channelId', ['channel', 'id']) +Session.accessor('channelName', ['channel', 'name']) Session.accessor('guildId', ['guild', 'id']) +Session.accessor('guildName', ['guild', 'name']) Session.accessor('messageId', ['message', 'id']) Session.accessor('operatorId', ['operator', 'id']) Session.accessor('roleId', ['role', 'id']) diff --git a/packages/protocol/src/index.ts b/packages/protocol/src/index.ts index b67f4744..8109067c 100644 --- a/packages/protocol/src/index.ts +++ b/packages/protocol/src/index.ts @@ -134,6 +134,7 @@ export namespace Channel { export interface Guild { id: string name?: string + avatar?: string } export interface GuildRole { @@ -149,11 +150,12 @@ export interface GuildRole { export interface User { id: string name?: string - nick?: string /** @deprecated */ userId?: string /** @deprecated */ username?: string + /** @deprecated */ + nickname?: string avatar?: string discriminator?: string isBot?: boolean @@ -165,6 +167,7 @@ export interface GuildMember { avatar?: string title?: string roles?: string[] + joinedAt?: number } export interface Login { @@ -260,6 +263,8 @@ export interface EventData { operator?: User role?: GuildRole user?: User + _type?: string + _data?: any /** @deprecated */ subtype?: string /** @deprecated */ diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 230c2380..9e3e9133 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -141,7 +141,7 @@ export function apply(ctx: Context, config: Config) { })) } - ctx.on('internal/session', (session) => { + ctx.on('satori/session', (session) => { for (const socket of layer.clients) { if (!socket[kClient]?.authorized) continue dispatch(socket, session)