66 lines
2.4 KiB
TypeScript
66 lines
2.4 KiB
TypeScript
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
|
|
function userIdFromToken(token: string): string | undefined {
|
|
try {
|
|
const segment = token.split(".")[0];
|
|
const padded = segment + "=".repeat((4 - (segment.length % 4)) % 4);
|
|
return Buffer.from(padded, "base64").toString("utf8");
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
export function resolveDiscordUserId(api: OpenClawPluginApi, accountId: string): string | undefined {
|
|
const root = (api.config as Record<string, unknown>) || {};
|
|
const channels = (root.channels as Record<string, unknown>) || {};
|
|
const discord = (channels.discord as Record<string, unknown>) || {};
|
|
const accounts = (discord.accounts as Record<string, Record<string, unknown>>) || {};
|
|
const acct = accounts[accountId];
|
|
if (!acct?.token || typeof acct.token !== "string") return undefined;
|
|
return userIdFromToken(acct.token);
|
|
}
|
|
|
|
export type ModeratorMessageResult =
|
|
| { ok: true; status: number; channelId: string; messageId?: string }
|
|
| { ok: false; status?: number; channelId: string; error: string };
|
|
|
|
export async function sendModeratorMessage(
|
|
token: string,
|
|
channelId: string,
|
|
content: string,
|
|
logger: { info: (msg: string) => void; warn: (msg: string) => void },
|
|
): Promise<ModeratorMessageResult> {
|
|
try {
|
|
const r = await fetch(`https://discord.com/api/v10/channels/${channelId}/messages`, {
|
|
method: "POST",
|
|
headers: {
|
|
Authorization: `Bot ${token}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ content }),
|
|
});
|
|
|
|
const text = await r.text();
|
|
let json: Record<string, unknown> | null = null;
|
|
try {
|
|
json = text ? (JSON.parse(text) as Record<string, unknown>) : null;
|
|
} catch {
|
|
json = null;
|
|
}
|
|
|
|
if (!r.ok) {
|
|
const error = `discord api error (${r.status}): ${text || "<empty response>"}`;
|
|
logger.warn(`dirigent: moderator send failed channel=${channelId} ${error}`);
|
|
return { ok: false, status: r.status, channelId, error };
|
|
}
|
|
|
|
const messageId = typeof json?.id === "string" ? json.id : undefined;
|
|
logger.info(`dirigent: moderator message sent to channel=${channelId} messageId=${messageId ?? "unknown"}`);
|
|
return { ok: true, status: r.status, channelId, messageId };
|
|
} catch (err) {
|
|
const error = String(err);
|
|
logger.warn(`dirigent: moderator send error channel=${channelId}: ${error}`);
|
|
return { ok: false, channelId, error };
|
|
}
|
|
}
|