feat(server): add pairing service and notify stub
This commit is contained in:
97
plugin/notifications/discord.ts
Normal file
97
plugin/notifications/discord.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user