feat(v0.8.60): audit filters, hook failure digest, worker release hints
- listAuditLog(filter), getHookFailureDigest, announceWorkerRelease - WORKER_RELEASE_ANNOUNCE gossip ingest + GUILD_SYNC.workerReleaseHint - appVersion constructor option for update-available comparison - view: hookFailureDigest, workerReleaseHint, auditLogFilterOptions Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -38,13 +38,17 @@ const {
|
||||
dryRunHook,
|
||||
dryRunHooks,
|
||||
buildDeliveryMetrics,
|
||||
buildHookFailureDigest,
|
||||
buildHookFailureAlert,
|
||||
AUDIT_FILTER,
|
||||
filterAuditEntries,
|
||||
HookFailureAlertStore
|
||||
} = require('pearcord-delivery-receipts')
|
||||
const {
|
||||
listWorkerTemplates,
|
||||
buildWorkerLaunchScript,
|
||||
getWorkerTemplate
|
||||
getWorkerTemplate,
|
||||
WorkerReleaseHintStore
|
||||
} = require('pearcord-integration-worker')
|
||||
const { PearcordIntegrationWorker } = require('./integration-worker')
|
||||
const { ACTION_TYPE_LIST, CATEGORY_OPTIONS } = require('pearcord-automation-export')
|
||||
@@ -244,6 +248,8 @@ class PearcordPlatform extends EventEmitter {
|
||||
this.deliveryReceipts = null
|
||||
this.hookDispatcher = null
|
||||
this.hookFailureAlerts = null
|
||||
this.workerReleaseHints = null
|
||||
this.appVersion = opts.appVersion || process.env.PEARCORD_APP_VERSION || '0.0.0'
|
||||
this.discovery = null
|
||||
this.contacts = null
|
||||
this.botLimits = null
|
||||
@@ -1148,6 +1154,17 @@ class PearcordPlatform extends EventEmitter {
|
||||
hookFailurePrefs = await this.deliveryReceipts.exportFailurePrefsSlice()
|
||||
}
|
||||
const auditRecent = await this._exportAuditSyncSlice(guild.id)
|
||||
let workerReleaseHint = null
|
||||
await this._initWorkerReleaseHints()
|
||||
const hintRow = await this.workerReleaseHints.getHint(guild.id)
|
||||
if (hintRow) {
|
||||
workerReleaseHint = {
|
||||
workerVersion: hintRow.workerVersion,
|
||||
pearUri: hintRow.pearUri,
|
||||
publishedAt: hintRow.publishedAt,
|
||||
publishedBy: hintRow.publishedBy
|
||||
}
|
||||
}
|
||||
let automodConfig = null
|
||||
await this._ensureGuildModules()
|
||||
if (this.automod) automodConfig = await this.automod.getConfig()
|
||||
@@ -1177,6 +1194,7 @@ class PearcordPlatform extends EventEmitter {
|
||||
receiptRetention,
|
||||
hookFailurePrefs,
|
||||
auditRecent,
|
||||
workerReleaseHint,
|
||||
automodConfig: automodConfig
|
||||
? {
|
||||
enabled: !!automodConfig.enabled,
|
||||
@@ -1284,6 +1302,12 @@ class PearcordPlatform extends EventEmitter {
|
||||
})
|
||||
}
|
||||
}
|
||||
if (payload.workerReleaseHint?.workerVersion) {
|
||||
await this._onWorkerReleaseHintGossip({
|
||||
guildId: payload.guildId,
|
||||
...payload.workerReleaseHint
|
||||
})
|
||||
}
|
||||
if (payload.automodConfig && this.automod) {
|
||||
await this.automod.ingestGossip({
|
||||
...payload.automodConfig,
|
||||
@@ -1515,6 +1539,9 @@ class PearcordPlatform extends EventEmitter {
|
||||
guildInstance.on('hook-failure', (alert) => {
|
||||
this._onHookFailureAlertGossip(alert).catch(() => {})
|
||||
})
|
||||
guildInstance.on('worker-release-hint', (payload) => {
|
||||
this._onWorkerReleaseHintGossip(payload).catch(() => {})
|
||||
})
|
||||
guildInstance.on('audit', async (p) => {
|
||||
if (p?.guildId && p?.id) {
|
||||
const existing = await this.db.get(COLLECTIONS.AUDIT_LOG, { id: p.id })
|
||||
@@ -1823,12 +1850,13 @@ class PearcordPlatform extends EventEmitter {
|
||||
return this.notifications.markAllRead()
|
||||
}
|
||||
|
||||
async listAuditLog (limit = 50) {
|
||||
async listAuditLog (limit = 50, opts = {}) {
|
||||
const guildId = this.guild?.guild?.id
|
||||
if (!guildId) return []
|
||||
const rows = await this.db.find(COLLECTIONS.AUDIT_LOG, { guildId })
|
||||
rows.sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0))
|
||||
const slice = rows.slice(0, limit)
|
||||
const filtered = filterAuditEntries(rows, opts.filter || AUDIT_FILTER.ALL)
|
||||
const slice = filtered.slice(0, limit)
|
||||
const out = []
|
||||
for (const row of slice) {
|
||||
const actor = await this.db.get(COLLECTIONS.USERS, { id: row.actorId })
|
||||
@@ -4329,6 +4357,78 @@ class PearcordPlatform extends EventEmitter {
|
||||
return buildDeliveryMetrics(rows, { windowMs: windowMs || 24 * 60 * 60 * 1000 })
|
||||
}
|
||||
|
||||
async getHookFailureDigest (windowMs) {
|
||||
if (!this.guild?.guild) {
|
||||
return buildHookFailureDigest([], [], { windowMs })
|
||||
}
|
||||
await this._initDeliveryReceipts(this.guild.guild.id)
|
||||
const alerts = await this.hookFailureAlerts.listRecent(64)
|
||||
const receipts = await this.deliveryReceipts.listRecent(512)
|
||||
return buildHookFailureDigest(alerts, receipts, {
|
||||
windowMs: windowMs || 24 * 60 * 60 * 1000
|
||||
})
|
||||
}
|
||||
|
||||
async _initWorkerReleaseHints () {
|
||||
if (!this.workerReleaseHints) {
|
||||
this.workerReleaseHints = new WorkerReleaseHintStore({
|
||||
storagePath: this.storagePath
|
||||
})
|
||||
await this.workerReleaseHints.ready()
|
||||
}
|
||||
return this.workerReleaseHints
|
||||
}
|
||||
|
||||
async getWorkerReleaseHint () {
|
||||
if (!this.guild?.guild) {
|
||||
return {
|
||||
localVersion: this.appVersion,
|
||||
remoteVersion: null,
|
||||
updateAvailable: false,
|
||||
pearUri: null
|
||||
}
|
||||
}
|
||||
await this._initWorkerReleaseHints()
|
||||
return this.workerReleaseHints.buildViewHint(this.guild.guild.id, this.appVersion)
|
||||
}
|
||||
|
||||
async announceWorkerRelease ({ workerVersion, pearUri } = {}) {
|
||||
if (!this.guild?.guild) throw new Error('no guild')
|
||||
const roles = await this._memberRoles()
|
||||
if (!roleHasPermission(roles, PERMISSION.MANAGE_GUILD)) {
|
||||
throw new Error('no permission to announce worker release')
|
||||
}
|
||||
const version = workerVersion || this.appVersion
|
||||
await this._initWorkerReleaseHints()
|
||||
const row = await this.workerReleaseHints.setHint({
|
||||
guildId: this.guild.guild.id,
|
||||
workerVersion: version,
|
||||
pearUri: pearUri || null,
|
||||
publishedBy: this.identity.user?.id || null
|
||||
})
|
||||
const payload = {
|
||||
guildId: this.guild.guild.id,
|
||||
workerVersion: row.workerVersion,
|
||||
pearUri: row.pearUri,
|
||||
publishedAt: row.publishedAt,
|
||||
publishedBy: row.publishedBy
|
||||
}
|
||||
if (this.guild.gossipWorkerReleaseAnnounce) {
|
||||
this.guild.gossipWorkerReleaseAnnounce(payload)
|
||||
}
|
||||
this.emit('worker-release-hint', payload)
|
||||
return this.getWorkerReleaseHint()
|
||||
}
|
||||
|
||||
async _onWorkerReleaseHintGossip (payload) {
|
||||
if (!payload?.guildId || !payload?.workerVersion) return null
|
||||
if (this.guild?.guild?.id !== payload.guildId) return null
|
||||
await this._initWorkerReleaseHints()
|
||||
const row = await this.workerReleaseHints.ingestGossip(payload)
|
||||
if (row) this.emit('worker-release-hint', row)
|
||||
return row
|
||||
}
|
||||
|
||||
async _assertAutomod (content) {
|
||||
if (this.mode !== 'guild' || !this.guild?.guild) return
|
||||
await this._ensureGuildModules()
|
||||
@@ -5802,6 +5902,18 @@ class PearcordPlatform extends EventEmitter {
|
||||
hookFailurePrefs = await this.getHookFailurePrefs()
|
||||
hookFailureAlerts = await this.listHookFailureAlerts(8)
|
||||
}
|
||||
let hookFailureDigest = null
|
||||
let workerReleaseHint = null
|
||||
if (guild) {
|
||||
hookFailureDigest = await this.getHookFailureDigest()
|
||||
workerReleaseHint = await this.getWorkerReleaseHint()
|
||||
}
|
||||
const auditLogFilterOptions = [
|
||||
{ id: AUDIT_FILTER.ALL, label: 'All' },
|
||||
{ id: AUDIT_FILTER.AUTOMOD, label: 'Automod' },
|
||||
{ id: AUDIT_FILTER.AUTOMATION, label: 'Automation' },
|
||||
{ id: AUDIT_FILTER.MODERATION, label: 'Moderation' }
|
||||
]
|
||||
let announcementCrosspostTargets = []
|
||||
let announcementCrosspostByChannel = {}
|
||||
let announcementFollowing = false
|
||||
@@ -5956,6 +6068,10 @@ class PearcordPlatform extends EventEmitter {
|
||||
automationReceiptRetention,
|
||||
hookFailurePrefs,
|
||||
hookFailureAlerts,
|
||||
hookFailureDigest,
|
||||
workerReleaseHint,
|
||||
auditLogFilterOptions,
|
||||
appVersion: this.appVersion,
|
||||
automationHookMeta,
|
||||
integrationWorkerTemplates,
|
||||
announcementCrosspostTargets,
|
||||
|
||||
Reference in New Issue
Block a user