feat(platform): Phase 490 bot span metadata (v0.8.453)
Add bot.token span, bot.verify span, and messageSent on bot.message. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -39,6 +39,8 @@ Expose a single `EventEmitter` API the UI drives over IPC (`apps/pearcord/index.
|
|||||||
|
|
||||||
**v0.8.430 (Phase 467):** `voice.leave` span `end` includes `leavingIsStage`; `screen.start` span `end` includes `label`. Bundle: `npm run test:phase467-voice-stage`. See [VOICE.md](../../docs/VOICE.md), [STAGE_CHANNELS.md](../../docs/STAGE_CHANNELS.md).
|
**v0.8.430 (Phase 467):** `voice.leave` span `end` includes `leavingIsStage`; `screen.start` span `end` includes `label`. Bundle: `npm run test:phase467-voice-stage`. See [VOICE.md](../../docs/VOICE.md), [STAGE_CHANNELS.md](../../docs/STAGE_CHANNELS.md).
|
||||||
|
|
||||||
|
**v0.8.453 (Phase 490):** `bot.token`/`bot.verify`/`bot.install`/`bot.message` span metadata extend. UI bot compositor + hints. Bundle: `npm run test:phase490-bots`. See [BOTS.md](../../docs/BOTS.md).
|
||||||
|
|
||||||
**v0.8.452 (Phase 489):** `slash.register` `customCount`; `slash.delete` `deleted`; `slash.invoke` `replyLen`/`commandFound`. UI slash compositor + hints. Bundle: `npm run test:phase489-slash`. See [SLASH_COMMANDS.md](../../docs/SLASH_COMMANDS.md).
|
**v0.8.452 (Phase 489):** `slash.register` `customCount`; `slash.delete` `deleted`; `slash.invoke` `replyLen`/`commandFound`. UI slash compositor + hints. Bundle: `npm run test:phase489-slash`. See [SLASH_COMMANDS.md](../../docs/SLASH_COMMANDS.md).
|
||||||
|
|
||||||
**v0.8.451 (Phase 488):** `webhook.create` `channelType`/`hasAvatar`; `webhook.execute` `messageSent`. UI webhook compositor split + hints. Bundle: `npm run test:phase488-webhooks`. See [WEBHOOKS.md](../../docs/WEBHOOKS.md).
|
**v0.8.451 (Phase 488):** `webhook.create` `channelType`/`hasAvatar`; `webhook.execute` `messageSent`. UI webhook compositor split + hints. Bundle: `npm run test:phase488-webhooks`. See [WEBHOOKS.md](../../docs/WEBHOOKS.md).
|
||||||
|
|||||||
@@ -9968,37 +9968,55 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
botId = null,
|
botId = null,
|
||||||
ttlMs = 7 * 86400000
|
ttlMs = 7 * 86400000
|
||||||
} = {}) {
|
} = {}) {
|
||||||
if (!this.guild?.guild) throw new Error('no guild')
|
const guildId = this.guild?.guild?.id || null
|
||||||
const user = this.identity.user
|
const span = this.log.time('bot.token', { guildId })
|
||||||
if (!user) throw new Error('register first')
|
try {
|
||||||
await this._assertStepUp()
|
if (!this.guild?.guild) throw new Error('no guild')
|
||||||
const roles = await this._memberRoles()
|
const user = this.identity.user
|
||||||
if (!roleHasPermission(roles, PERMISSION.MANAGE_GUILD)) {
|
if (!user) throw new Error('register first')
|
||||||
throw new Error('no permission to create bot install tokens')
|
await this._assertStepUp()
|
||||||
|
const roles = await this._memberRoles()
|
||||||
|
if (!roleHasPermission(roles, PERMISSION.MANAGE_GUILD)) {
|
||||||
|
throw new Error('no permission to create bot install tokens')
|
||||||
|
}
|
||||||
|
if (!this.botLimits) {
|
||||||
|
this.botLimits = new BotRateLimits({ storagePath: this.storagePath })
|
||||||
|
await this.botLimits.ready()
|
||||||
|
}
|
||||||
|
await this.botLimits.assertBotRegister(this.guild.guild.id)
|
||||||
|
const { token, payload } = createInstallToken({
|
||||||
|
keyPair: this.identity.keyPair,
|
||||||
|
guildId: this.guild.guild.id,
|
||||||
|
guildName: this.guild.guild.name,
|
||||||
|
guildTopic: this.guild.guild.topic,
|
||||||
|
botId: botId || id(),
|
||||||
|
name,
|
||||||
|
intents,
|
||||||
|
permissions,
|
||||||
|
botPublicKey,
|
||||||
|
issuedBy: user.id,
|
||||||
|
ttlMs
|
||||||
|
})
|
||||||
|
const bot = payloadToBotRow(payload, this.identity.snapshot().publicKey)
|
||||||
|
await this._ingestGuildBot(bot)
|
||||||
|
this.guild.gossipBotInstall(bot)
|
||||||
|
this.emit('bot', bot)
|
||||||
|
span.end({
|
||||||
|
guildId,
|
||||||
|
botId: bot.id,
|
||||||
|
botName: String(bot.name || '').slice(0, 32),
|
||||||
|
permissionMask: Number(bot.permissions) || 0,
|
||||||
|
tokenIssued: !!token
|
||||||
|
})
|
||||||
|
return { token, bot, expiresAt: payload.expiresAt }
|
||||||
|
} catch (err) {
|
||||||
|
this.log.error('bot.token error', {
|
||||||
|
guildId,
|
||||||
|
error: err?.message || String(err)
|
||||||
|
})
|
||||||
|
span.fail(err)
|
||||||
|
throw err
|
||||||
}
|
}
|
||||||
if (!this.botLimits) {
|
|
||||||
this.botLimits = new BotRateLimits({ storagePath: this.storagePath })
|
|
||||||
await this.botLimits.ready()
|
|
||||||
}
|
|
||||||
await this.botLimits.assertBotRegister(this.guild.guild.id)
|
|
||||||
const { token, payload } = createInstallToken({
|
|
||||||
keyPair: this.identity.keyPair,
|
|
||||||
guildId: this.guild.guild.id,
|
|
||||||
guildName: this.guild.guild.name,
|
|
||||||
guildTopic: this.guild.guild.topic,
|
|
||||||
botId: botId || id(),
|
|
||||||
name,
|
|
||||||
intents,
|
|
||||||
permissions,
|
|
||||||
botPublicKey,
|
|
||||||
issuedBy: user.id,
|
|
||||||
ttlMs
|
|
||||||
})
|
|
||||||
const bot = payloadToBotRow(payload, this.identity.snapshot().publicKey)
|
|
||||||
await this._ingestGuildBot(bot)
|
|
||||||
this.guild.gossipBotInstall(bot)
|
|
||||||
this.emit('bot', bot)
|
|
||||||
return { token, bot, expiresAt: payload.expiresAt }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async installBotFromToken (tokenInput) {
|
async installBotFromToken (tokenInput) {
|
||||||
@@ -10020,7 +10038,8 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
botId: bot.id,
|
botId: bot.id,
|
||||||
guildId: bot.guildId,
|
guildId: bot.guildId,
|
||||||
botName: String(bot.name || '').slice(0, 32),
|
botName: String(bot.name || '').slice(0, 32),
|
||||||
permissionMask: Number(bot.permissions) || 0
|
permissionMask: Number(bot.permissions) || 0,
|
||||||
|
installed: true
|
||||||
})
|
})
|
||||||
return { bot, token: typeof tokenInput === 'string' ? tokenInput : null }
|
return { bot, token: typeof tokenInput === 'string' ? tokenInput : null }
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -10034,7 +10053,26 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async verifyBotToken (tokenInput) {
|
async verifyBotToken (tokenInput) {
|
||||||
return verifyInstallToken(tokenInput)
|
const guildId = this.guild?.guild?.id || null
|
||||||
|
const span = this.log.time('bot.verify', { guildId })
|
||||||
|
try {
|
||||||
|
const result = verifyInstallToken(tokenInput, {
|
||||||
|
expectedGuildId: guildId || undefined
|
||||||
|
})
|
||||||
|
span.end({
|
||||||
|
guildId,
|
||||||
|
ok: !!result.ok,
|
||||||
|
botId: result.payload?.botId || null
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
} catch (err) {
|
||||||
|
this.log.error('bot.verify error', {
|
||||||
|
guildId,
|
||||||
|
error: err?.message || String(err)
|
||||||
|
})
|
||||||
|
span.fail(err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendBotMessage ({ botId, content, channelId } = {}) {
|
async sendBotMessage ({ botId, content, channelId } = {}) {
|
||||||
@@ -10060,7 +10098,8 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
guildId,
|
guildId,
|
||||||
channelId: chId,
|
channelId: chId,
|
||||||
contentLength: String(content ?? '').length,
|
contentLength: String(content ?? '').length,
|
||||||
botId
|
botId,
|
||||||
|
messageSent: !!msg?.id
|
||||||
})
|
})
|
||||||
return msg
|
return msg
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Reference in New Issue
Block a user