Integrates presence updates directly into the Discord channel integration:
- Added presence config schema (channels.discord.presence):
- enabled: Toggle presence updates
- showTokenUsage: Show cumulative token count
- format: Custom format string with placeholders ({tokens}, {model}, etc.)
- activityType: Playing, Watching, Listening, Competing (NOT Custom - bots can't use it)
- status: online, idle, dnd, invisible
- Created PresenceManager in src/discord/monitor/presence-manager.ts:
- Tracks cumulative token usage per session
- Formats status text with configurable placeholders
- Interfaces with Carbon GatewayPlugin.updatePresence()
- Created presence registry (src/discord/presence-registry.ts):
- Shared registry for presence managers across accounts
- Exported via plugin-sdk for extension access
- Wired up message_sent hook in Discord extension:
- Hook triggers after each reply is delivered
- Updates bot presence with session token counts
Config example:
```json5
channels: {
discord: {
presence: {
enabled: true,
showTokenUsage: true,
format: "📊 {tokens} tokens",
activityType: "Watching", // Shows: "Watching 📊 1,234 tokens"
status: "online"
}
}
}
```
Note: Discord API limitation - bots cannot use Custom activity type (type 4).
Available types: Playing, Watching, Listening, Competing.
48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk";
|
|
import { emptyPluginConfigSchema, getPresenceManager } from "clawdbot/plugin-sdk";
|
|
|
|
import { discordPlugin } from "./src/channel.js";
|
|
import { setDiscordRuntime } from "./src/runtime.js";
|
|
|
|
const plugin = {
|
|
id: "discord",
|
|
name: "Discord",
|
|
description: "Discord channel plugin",
|
|
configSchema: emptyPluginConfigSchema(),
|
|
register(api: ClawdbotPluginApi) {
|
|
setDiscordRuntime(api.runtime);
|
|
api.registerChannel({ plugin: discordPlugin });
|
|
|
|
// Register message_sent hook for presence updates
|
|
api.registerHook({
|
|
hookName: "message_sent",
|
|
priority: 5,
|
|
handler: async (event, ctx) => {
|
|
// Only handle Discord channel
|
|
if (ctx.channelId !== "discord") {
|
|
return;
|
|
}
|
|
|
|
// Find the presence manager for this account
|
|
const accountId = ctx.accountId ?? "default";
|
|
const manager = getPresenceManager(accountId);
|
|
if (!manager) {
|
|
return;
|
|
}
|
|
|
|
// Update presence with usage info
|
|
manager.updatePresence({
|
|
sessionKey: ctx.sessionKey,
|
|
tokens: event.usage?.totalTokens,
|
|
inputTokens: event.usage?.inputTokens,
|
|
outputTokens: event.usage?.outputTokens,
|
|
model: event.usage?.model,
|
|
provider: event.usage?.provider,
|
|
});
|
|
},
|
|
});
|
|
},
|
|
};
|
|
|
|
export default plugin;
|