Skip to content

Commit

Permalink
feat(satori): support satori/internal emits
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Sep 29, 2023
1 parent d979005 commit b39dbce
Show file tree
Hide file tree
Showing 28 changed files with 108 additions and 79 deletions.
3 changes: 2 additions & 1 deletion adapters/dingtalk/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ export class DingtalkBot extends Bot<DingtalkBot.Config> {
return this.toJSON()
}

async stop() {
stop() {
clearTimeout(this.refreshTokenTimer)
return super.stop()
}

public token: string
Expand Down
2 changes: 2 additions & 0 deletions adapters/dingtalk/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { decodeMessage } from './utils'

export class HttpServer extends Adapter.Server<DingtalkBot> {
logger = new Logger('dingtalk')

constructor(ctx: Context, bot: DingtalkBot) {
super()
}

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')
Expand Down
6 changes: 3 additions & 3 deletions adapters/dingtalk/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ export async function decodeMessage(bot: DingtalkBot, body: Message): Promise<Se
session.channelId = body.conversationId
}
if (body.conversationTitle) {
session.data.channel.name = body.conversationTitle
session.body.channel.name = body.conversationTitle
}

session.data.user = {
session.body.user = {
id: body.senderStaffId,
name: body.senderNick,
}
session.data.member = {
session.body.member = {
roles: body.isAdmin ? ['admin'] : [],
}
session.timestamp = +body.createAt
Expand Down
2 changes: 1 addition & 1 deletion adapters/discord/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class DiscordMessageEncoder extends MessageEncoder<DiscordBot> {
const url = await this.getUrl()
const result = await this.bot.http.post<Message>(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)

Expand Down
10 changes: 5 additions & 5 deletions adapters/discord/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,15 @@ 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') {
session.type = 'message-updated'
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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion adapters/discord/src/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class WsClient extends Adapter.WsClient<DiscordBot> {
}

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
Expand Down
2 changes: 1 addition & 1 deletion adapters/kook/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class KookMessageEncoder extends MessageEncoder<KookBot> {
})
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<internal.Readable>(attrs.url, {
headers: { accept: type + '/*' },
responseType: 'stream',
Expand Down
18 changes: 9 additions & 9 deletions adapters/kook/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Session>) {
Expand All @@ -149,10 +146,13 @@ function adaptReaction(body: Kook.NoticeBody, session: Partial<Session>) {

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':
Expand Down Expand Up @@ -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':
Expand Down
2 changes: 1 addition & 1 deletion adapters/lark/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion adapters/mail/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions adapters/matrix/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}

Expand Down
6 changes: 3 additions & 3 deletions adapters/onebot/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion adapters/qq/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export class QQMessageEncoder extends MessageEncoder<QQBot> {
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
Expand Down
6 changes: 3 additions & 3 deletions adapters/qq/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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'
Expand Down
2 changes: 1 addition & 1 deletion adapters/qq/src/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class WsClient extends Adapter.WsClient<QQBot> {
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
Expand Down
5 changes: 4 additions & 1 deletion adapters/satori/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<SatoriBot.Config> {
Expand Down
2 changes: 1 addition & 1 deletion adapters/slack/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class SlackMessageEncoder extends MessageEncoder<SlackBot> {
})
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)
Expand Down
6 changes: 3 additions & 3 deletions adapters/slack/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -169,7 +169,7 @@ export async function adaptSession(bot: SlackBot, payload: EnvelopedEvent<SlackE
if (input.user === bot.selfId) return
if (!input.subtype) {
session.type = 'message'
await adaptMessage(bot, input as GenericMessageEvent, session.data.message = {}, session.data)
await adaptMessage(bot, input as GenericMessageEvent, session.body.message = {}, session.body)
} else if (input.subtype === 'message_deleted') {
adaptMessageDeleted(bot, input, session)
} else if (input.subtype === 'message_changed') {
Expand All @@ -178,7 +178,7 @@ export async function adaptSession(bot: SlackBot, payload: EnvelopedEvent<SlackE
session.type = 'message-updated'
// @ts-ignore
session.guildId = payload.team_id
await adaptMessage(bot, evt.message, session.data.message = {}, session.data)
await adaptMessage(bot, evt.message, session.body.message = {}, session.body)
} else {
return
}
Expand Down
2 changes: 1 addition & 1 deletion adapters/telegram/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class TelegramMessageEncoder extends MessageEncoder<TelegramBot> {

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)
}
Expand Down
22 changes: 12 additions & 10 deletions adapters/telegram/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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'
Expand All @@ -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'
Expand All @@ -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)
}

Expand Down
2 changes: 1 addition & 1 deletion adapters/whatsapp/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class WhatsAppMessageEncoder extends MessageEncoder<WhatsAppBot> {
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)
Expand Down
2 changes: 1 addition & 1 deletion adapters/whatsapp/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
Loading

0 comments on commit b39dbce

Please sign in to comment.