Files
Yonexus.Server/plugin/notifications/discord.ts

98 lines
3.2 KiB
TypeScript

/**
* Yonexus Server - Discord Notification Service
*
* Sends pairing notifications to the configured admin user via Discord DM.
*/
import type { PairingRequest } from "../services/pairing.js";
export interface DiscordNotificationService {
/**
* Send a pairing code notification to the admin user.
* @returns Whether the notification was sent successfully
*/
sendPairingNotification(request: PairingRequest): Promise<boolean>;
}
export interface DiscordNotificationConfig {
botToken: string;
adminUserId: string;
}
/**
* Create a Discord notification service.
*
* Note: This is a framework stub. Full implementation requires:
* - Discord bot client integration (e.g., using discord.js)
* - DM channel creation/fetching
* - Error handling for blocked DMs, invalid tokens, etc.
*
* For v1, this provides the interface and a mock implementation
* that logs to console. Production deployments should replace
* this with actual Discord bot integration.
*/
export function createDiscordNotificationService(
config: DiscordNotificationConfig
): DiscordNotificationService {
return {
async sendPairingNotification(request: PairingRequest): Promise<boolean> {
const message = formatPairingMessage(request);
// Log to console (visible in OpenClaw logs)
console.log("[Yonexus.Server] Pairing notification (Discord DM stub):");
console.log(message);
// TODO: Replace with actual Discord bot integration
// Example with discord.js:
// const client = new Client({ intents: [GatewayIntentBits.DirectMessages] });
// await client.login(config.botToken);
// const user = await client.users.fetch(config.adminUserId);
// await user.send(message);
// For now, return true to allow pairing flow to continue
// In production, this should return false if DM fails
return true;
}
};
}
/**
* Format a pairing request as a Discord DM message.
*/
function formatPairingMessage(request: PairingRequest): string {
const expiresDate = new Date(request.expiresAt * 1000);
const expiresStr = expiresDate.toISOString();
return [
"🔐 **Yonexus Pairing Request**",
"",
`**Identifier:** \`${request.identifier}\``,
`**Pairing Code:** \`${request.pairingCode}\``,
`**Expires At:** ${expiresStr}`,
`**TTL:** ${request.ttlSeconds} seconds`,
"",
"Please relay this pairing code to the client operator via a trusted out-of-band channel.",
"Do not share this code over the Yonexus WebSocket connection."
].join("\n");
}
/**
* Create a mock notification service for testing.
* Returns success/failure based on configuration.
*/
export function createMockNotificationService(
options: { shouldSucceed?: boolean } = {}
): DiscordNotificationService {
const shouldSucceed = options.shouldSucceed ?? true;
return {
async sendPairingNotification(request: PairingRequest): Promise<boolean> {
console.log("[Yonexus.Server] Mock pairing notification:");
console.log(` Identifier: ${request.identifier}`);
console.log(` Pairing Code: ${request.pairingCode}`);
console.log(` Success: ${shouldSucceed}`);
return shouldSucceed;
}
};
}