Skip to content

Commit

Permalink
feat(discord): support reaction events
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Jul 4, 2021
1 parent 173ce85 commit 21d06f2
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 20 deletions.
60 changes: 43 additions & 17 deletions packages/adapter-discord/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const adaptAuthor = (author: DC.User): AuthorInfo => ({
nickname: author.username,
})

export async function adaptMessage(bot: DiscordBot, meta: DC.Message, session: Partial<Session> = {}) {
export function adaptMessage(bot: DiscordBot, meta: DC.Message, session: Partial<Session> = {}) {
if (meta.author) {
session.author = adaptAuthor(meta.author)
session.userId = meta.author.id
Expand Down Expand Up @@ -106,8 +106,8 @@ export async function adaptMessage(bot: DiscordBot, meta: DC.Message, session: P
return session
}

async function adaptMessageSession(bot: DiscordBot, meta: DC.Message, session: Partial<Session> = {}) {
await adaptMessage(bot, meta, session)
function adaptMessageSession(bot: DiscordBot, meta: DC.Message, session: Partial<Session> = {}) {
adaptMessage(bot, meta, session)
session.messageId = meta.id
session.timestamp = new Date(meta.timestamp).valueOf() || Date.now()
// 遇到过 cross post 的消息在这里不会传消息 id
Expand All @@ -118,38 +118,64 @@ async function adaptMessageSession(bot: DiscordBot, meta: DC.Message, session: P
return session
}

function prepareMessageSession(session: Partial<Session>, data: DC.Message) {
session.groupId = data.guild_id
session.subtype = data.guild_id ? 'group' : 'private'
session.channelId = data.channel_id
}

function prepareReactionSession(session: Partial<Session>, data: any) {
session.userId = data.user_id
session.messageId = data.message_id
session.groupId = data.guild_id
session.channelId = data.channel_id
session.subtype = data.guild_id ? 'group' : 'private'
if (!data.emoji) return
const { id, name } = data.emoji
session.content = id ? `${name}:${id}` : name
}

export async function adaptSession(bot: DiscordBot, input: DC.Payload) {
const session: Partial<Session> = {
selfId: bot.selfId,
platform: 'discord',
}
if (input.t === 'MESSAGE_CREATE') {
session.type = 'message'
const msg = input.d as DC.Message
session.groupId = msg.guild_id
session.subtype = msg.guild_id ? 'group' : 'private'
session.channelId = msg.channel_id
await adaptMessageSession(bot, input.d, session)
prepareMessageSession(session, input.d)
adaptMessageSession(bot, input.d, session)
// dc 情况特殊 可能有 embeds 但是没有消息主体
// if (!session.content) return
if (session.userId === bot.selfId) return
} else if (input.t === 'MESSAGE_UPDATE') {
session.type = 'message-updated'
const d = input.d as DC.Message
session.groupId = d.guild_id
session.subtype = d.guild_id ? 'group' : 'private'
session.channelId = d.channel_id
const msg = await bot.$getMessage(d.channel_id, d.id)
prepareMessageSession(session, input.d)
const msg = await bot.$getMessage(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#message-update
await adaptMessageSession(bot, msg, session)
adaptMessageSession(bot, msg, session)
// if (!session.content) return
if (session.userId === bot.selfId) return
} else if (input.t === 'MESSAGE_DELETE') {
session.type = 'message-deleted'
session.messageId = input.d.id
session.groupId = input.d.guild_id
session.channelId = input.d.channel_id
prepareMessageSession(session, input.d)
} else if (input.t === 'MESSAGE_REACTION_ADD') {
session.type = 'reaction-added'
prepareReactionSession(session, input.d)
} else if (input.t === 'MESSAGE_REACTION_REMOVE') {
session.type = 'reaction-deleted'
session.subtype = 'one'
prepareReactionSession(session, input.d)
} else if (input.t === 'MESSAGE_REACTION_REMOVE_ALL') {
session.type = 'reaction-deleted'
session.subtype = 'all'
prepareReactionSession(session, input.d)
} else if (input.t === 'MESSAGE_REACTION_REMOVE_EMOJI') {
session.type = 'reaction-deleted'
session.subtype = 'emoji'
prepareReactionSession(session, input.d)
} else {
return
}
return new Session(bot.app, session)
}
9 changes: 6 additions & 3 deletions packages/adapter-discord/src/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import WebSocket from 'ws'

const logger = new Logger('discord')

// https://discord.com/developers/docs/topics/gateway
/** https://discord.com/developers/docs/topics/gateway */
export default class WsClient extends Adapter.WsClient<'discord'> {
constructor(app: App) {
super(app, DiscordBot, app.options.discord)
Expand Down Expand Up @@ -59,10 +59,13 @@ export default class WsClient extends Adapter.WsClient<'discord'> {
token: bot.token,
properties: {},
compress: false,
intents: (1 << 9) + (1 << 12),
// https://discord.com/developers/docs/topics/gateway#gateway-intents
intents: (1 << 9) + (1 << 10) + (1 << 12) + (1 << 13),
},
}))
} else if (parsed.op === Opcode.Dispatch) {
}

if (parsed.op === Opcode.Dispatch) {
if (parsed.t === 'READY') {
bot._sessionId = parsed.d.session_id
const self: any = adaptUser(parsed.d.user)
Expand Down

0 comments on commit 21d06f2

Please sign in to comment.