feat(automations): APP_EVENT fanout and createAppListener
Wire pearcord-app-events on guild open: bridge bot payloads, fanout channel permission and custom-role changes, gossip APP_EVENT to mesh, and expose view.appEvents snapshot for debugging. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -19,6 +19,11 @@ const { VoiceCaptureFeed } = require('pearcord-voice-capture')
|
|||||||
const { PearcordSlashRegistry, parseSlashInvocation } = require('pearcord-commands')
|
const { PearcordSlashRegistry, parseSlashInvocation } = require('pearcord-commands')
|
||||||
const { PearcordEmojiRegistry, buildEmojiSlotSnapshot } = require('pearcord-emoji')
|
const { PearcordEmojiRegistry, buildEmojiSlotSnapshot } = require('pearcord-emoji')
|
||||||
const { BotEventFanout, BOT_EVENTS } = require('pearcord-bot-events')
|
const { BotEventFanout, BOT_EVENTS } = require('pearcord-bot-events')
|
||||||
|
const {
|
||||||
|
AppEventBridge,
|
||||||
|
APP_EVENTS,
|
||||||
|
APP_EVENT_CATEGORIES
|
||||||
|
} = require('pearcord-app-events')
|
||||||
const { INTENTS } = require('pearcord-bot-sdk')
|
const { INTENTS } = require('pearcord-bot-sdk')
|
||||||
const { BotRateLimits } = require('pearcord-bot-limits')
|
const { BotRateLimits } = require('pearcord-bot-limits')
|
||||||
const { PearcordStepUp } = require('pearcord-step-up')
|
const { PearcordStepUp } = require('pearcord-step-up')
|
||||||
@@ -210,6 +215,7 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
this.channelPermissions = null
|
this.channelPermissions = null
|
||||||
this._recentSoundPlays = []
|
this._recentSoundPlays = []
|
||||||
this.botEvents = null
|
this.botEvents = null
|
||||||
|
this.appEvents = null
|
||||||
this.discovery = null
|
this.discovery = null
|
||||||
this.contacts = null
|
this.contacts = null
|
||||||
this.botLimits = null
|
this.botLimits = null
|
||||||
@@ -1354,19 +1360,33 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
guildInstance.on('guild-member-roles', (payload) => {
|
guildInstance.on('guild-member-roles', (payload) => {
|
||||||
this.guildRoles?.ingestMemberRolesGossip(payload).catch(() => {})
|
this.guildRoles?.ingestMemberRolesGossip(payload).catch(() => {})
|
||||||
this.emit('guild-member-roles', payload)
|
this.emit('guild-member-roles', payload)
|
||||||
|
this._fanoutAppEvent(APP_EVENTS.MEMBER_ROLE_UPDATE, { memberRoles: payload }).catch(
|
||||||
|
() => {}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
guildInstance.on('channel-overwrite', (row) => {
|
guildInstance.on('channel-overwrite', (row) => {
|
||||||
this.channelPermissions?.ingestOverwriteGossip(row).catch(() => {})
|
this.channelPermissions?.ingestOverwriteGossip(row).catch(() => {})
|
||||||
this.emit('channel-overwrite', row)
|
this.emit('channel-overwrite', row)
|
||||||
|
this._fanoutAppEvent(APP_EVENTS.CHANNEL_PERMISSION_UPDATE, { overwrite: row }).catch(
|
||||||
|
() => {}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
guildInstance.on('channel-overwrite-delete', (payload) => {
|
guildInstance.on('channel-overwrite-delete', (payload) => {
|
||||||
this.channelPermissions?.ingestOverwriteDelete(payload).catch(() => {})
|
this.channelPermissions?.ingestOverwriteDelete(payload).catch(() => {})
|
||||||
this.emit('channel-overwrite-delete', payload)
|
this.emit('channel-overwrite-delete', payload)
|
||||||
|
this._fanoutAppEvent(APP_EVENTS.CHANNEL_PERMISSION_DELETE, { delete: payload }).catch(
|
||||||
|
() => {}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
guildInstance.on('bot-event', (payload) => {
|
guildInstance.on('bot-event', (payload) => {
|
||||||
this.botEvents?.ingest(payload)
|
this.botEvents?.ingest(payload)
|
||||||
|
this.appEvents?.bridgeFromBot(payload)
|
||||||
this.emit('bot-event', payload)
|
this.emit('bot-event', payload)
|
||||||
})
|
})
|
||||||
|
guildInstance.on('app-event', (payload) => {
|
||||||
|
this.appEvents?.ingest(payload)
|
||||||
|
this.emit('app-event', payload)
|
||||||
|
})
|
||||||
guildInstance.on('bot-install', (bot) => {
|
guildInstance.on('bot-install', (bot) => {
|
||||||
this._ingestGuildBot(bot).catch(() => {})
|
this._ingestGuildBot(bot).catch(() => {})
|
||||||
this.emit('bot', bot)
|
this.emit('bot', bot)
|
||||||
@@ -1870,6 +1890,7 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
)
|
)
|
||||||
this.guild.gossipMemberCustomRoles(link)
|
this.guild.gossipMemberCustomRoles(link)
|
||||||
this.emit('guild-member-roles', link)
|
this.emit('guild-member-roles', link)
|
||||||
|
await this._fanoutAppEvent(APP_EVENTS.MEMBER_ROLE_UPDATE, { memberRoles: link })
|
||||||
this.emit('member', await this.db.get(COLLECTIONS.MEMBERS, {
|
this.emit('member', await this.db.get(COLLECTIONS.MEMBERS, {
|
||||||
guildId: this.guild.guild.id,
|
guildId: this.guild.guild.id,
|
||||||
userId
|
userId
|
||||||
@@ -2019,6 +2040,7 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
this.guild.gossipChannelOverwriteUpsert(row)
|
this.guild.gossipChannelOverwriteUpsert(row)
|
||||||
await this._audit('channel.overwrite', { guildId: this.guild.guild.id, targetId: chId })
|
await this._audit('channel.overwrite', { guildId: this.guild.guild.id, targetId: chId })
|
||||||
this.emit('channel-overwrite', row)
|
this.emit('channel-overwrite', row)
|
||||||
|
await this._fanoutAppEvent(APP_EVENTS.CHANNEL_PERMISSION_UPDATE, { overwrite: row })
|
||||||
return row
|
return row
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2044,6 +2066,9 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.emit('channel-overwrite-delete', { channelId: chId, targetType, targetId })
|
this.emit('channel-overwrite-delete', { channelId: chId, targetType, targetId })
|
||||||
|
await this._fanoutAppEvent(APP_EVENTS.CHANNEL_PERMISSION_DELETE, {
|
||||||
|
delete: { channelId: chId, targetType, targetId }
|
||||||
|
})
|
||||||
return prev
|
return prev
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2204,6 +2229,13 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _initAppEvents (guildId) {
|
||||||
|
this.appEvents = new AppEventBridge({
|
||||||
|
guildId,
|
||||||
|
categories: APP_EVENT_CATEGORIES.ALL
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async _fanoutBotEvent (type, data) {
|
async _fanoutBotEvent (type, data) {
|
||||||
if (!this.botEvents || !this.guild?.guild) return null
|
if (!this.botEvents || !this.guild?.guild) return null
|
||||||
if (!this.botLimits) {
|
if (!this.botLimits) {
|
||||||
@@ -2214,11 +2246,21 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
if (!allowed) return null
|
if (!allowed) return null
|
||||||
const payload = this.botEvents.createPayload(type, data)
|
const payload = this.botEvents.createPayload(type, data)
|
||||||
this.botEvents.deliverLocal(payload)
|
this.botEvents.deliverLocal(payload)
|
||||||
|
this.appEvents?.bridgeFromBot(payload)
|
||||||
this.guild.gossipBotEvent(payload)
|
this.guild.gossipBotEvent(payload)
|
||||||
this.emit('bot-event', payload)
|
this.emit('bot-event', payload)
|
||||||
return payload
|
return payload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _fanoutAppEvent (type, data) {
|
||||||
|
if (!this.appEvents || !this.guild?.guild) return null
|
||||||
|
const payload = this.appEvents.createPayload(type, data)
|
||||||
|
this.appEvents.deliverLocal(payload)
|
||||||
|
if (this.guild.gossipAppEvent) this.guild.gossipAppEvent(payload)
|
||||||
|
this.emit('app-event', payload)
|
||||||
|
return payload
|
||||||
|
}
|
||||||
|
|
||||||
async _initGuildVoice (guildId) {
|
async _initGuildVoice (guildId) {
|
||||||
const user = this.identity.user
|
const user = this.identity.user
|
||||||
if (!user) return
|
if (!user) return
|
||||||
@@ -2228,6 +2270,7 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
await this._initSoundboardRegistry(guildId)
|
await this._initSoundboardRegistry(guildId)
|
||||||
await this._initGuildRoles(guildId)
|
await this._initGuildRoles(guildId)
|
||||||
await this._initBotEvents(guildId)
|
await this._initBotEvents(guildId)
|
||||||
|
await this._initAppEvents(guildId)
|
||||||
this.voice = new PearcordVoice({
|
this.voice = new PearcordVoice({
|
||||||
storagePath: this.storagePath,
|
storagePath: this.storagePath,
|
||||||
guildId,
|
guildId,
|
||||||
@@ -3882,6 +3925,18 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
return listener
|
return listener
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createAppListener (categories = APP_EVENT_CATEGORIES.ALL) {
|
||||||
|
if (!this.guild?.guild) throw new Error('no guild')
|
||||||
|
const listener = new AppEventBridge({
|
||||||
|
guildId: this.guild.guild.id,
|
||||||
|
categories: categories ?? APP_EVENT_CATEGORIES.ALL
|
||||||
|
})
|
||||||
|
const onRemote = (payload) => listener.ingest(payload)
|
||||||
|
this.guild.on('app-event', onRemote)
|
||||||
|
listener._unwire = () => this.guild.removeListener('app-event', onRemote)
|
||||||
|
return listener
|
||||||
|
}
|
||||||
|
|
||||||
async executeSlashCommand (content, opts = {}) {
|
async executeSlashCommand (content, opts = {}) {
|
||||||
if (!this.slashCommands || !this.messages) throw new Error('no channel')
|
if (!this.slashCommands || !this.messages) throw new Error('no channel')
|
||||||
const inv = parseSlashInvocation(content)
|
const inv = parseSlashInvocation(content)
|
||||||
@@ -5353,6 +5408,7 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
? await this.emojiRegistry.reactionGlyphs()
|
? await this.emojiRegistry.reactionGlyphs()
|
||||||
: ['👍', '❤️', '😂'],
|
: ['👍', '❤️', '😂'],
|
||||||
botEvents: this.botEvents?.snapshot() || null,
|
botEvents: this.botEvents?.snapshot() || null,
|
||||||
|
appEvents: this.appEvents?.snapshot() || null,
|
||||||
bots: this.guild
|
bots: this.guild
|
||||||
? (await this.db.find(COLLECTIONS.GUILD_BOTS, { guildId: this.guild.id })).map((b) => ({
|
? (await this.db.find(COLLECTIONS.GUILD_BOTS, { guildId: this.guild.id })).map((b) => ({
|
||||||
...b,
|
...b,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"pearcord-activity": "file:../pearcord-activity",
|
"pearcord-activity": "file:../pearcord-activity",
|
||||||
"pearcord-announcement-hub": "file:../pearcord-announcement-hub",
|
"pearcord-announcement-hub": "file:../pearcord-announcement-hub",
|
||||||
"pearcord-announcements": "file:../pearcord-announcements",
|
"pearcord-announcements": "file:../pearcord-announcements",
|
||||||
|
"pearcord-app-events": "file:../pearcord-app-events",
|
||||||
"pearcord-attachments": "file:../pearcord-attachments",
|
"pearcord-attachments": "file:../pearcord-attachments",
|
||||||
"pearcord-automod": "file:../pearcord-automod",
|
"pearcord-automod": "file:../pearcord-automod",
|
||||||
"pearcord-boosts": "file:../pearcord-boosts",
|
"pearcord-boosts": "file:../pearcord-boosts",
|
||||||
|
|||||||
Reference in New Issue
Block a user