import type { ClawdbotConfig } from "openclaw/plugin-sdk"; import type { PopoConfig, PopoSendResult } from "./types.js"; import { popoRequest } from "./client.js"; import { normalizePopoTarget, detectReceiverType } from "./targets.js"; export type SendPopoMessageParams = { cfg: ClawdbotConfig; to: string; text: string; atUids?: string[]; isAtAll?: boolean; }; /** * Send a text message to POPO. */ export async function sendMessagePopo(params: SendPopoMessageParams): Promise { const { cfg, to, text, atUids, isAtAll } = params; const popoCfg = cfg.channels?.popo as PopoConfig | undefined; if (!popoCfg) { throw new Error("POPO channel not configured"); } const receiver = normalizePopoTarget(to); if (!receiver) { throw new Error(`Invalid POPO target: ${to}`); } const receiverType = detectReceiverType(receiver); const receiverKey = receiverType === "email" ? "receiver" : "groupId"; const message: Record = { content: text, }; if (atUids && atUids.length > 0) { message.atUids = atUids; } if (isAtAll) { message.isAtAll = true; } const response = await popoRequest<{ msgId?: string }>({ cfg: popoCfg, method: "POST", path: "/im/send-msg", body: { [receiverKey]: receiver, msgType: "text", message, }, }); if (response.code !== 200) { throw new Error(`POPO send failed: ${response.message || `code ${response.code}`}`); } return { messageId: response.result?.msgId, sessionId: receiver, }; } export type SendPopoRichTextParams = { cfg: ClawdbotConfig; to: string; content: Array<{ tag: string; text?: string; href?: string; userId?: string }>; }; /** * Send a rich text message to POPO. */ export async function sendRichTextPopo(params: SendPopoRichTextParams): Promise { const { cfg, to, content } = params; const popoCfg = cfg.channels?.popo as PopoConfig | undefined; if (!popoCfg) { throw new Error("POPO channel not configured"); } const receiver = normalizePopoTarget(to); if (!receiver) { throw new Error(`Invalid POPO target: ${to}`); } const receiverType = detectReceiverType(receiver); const receiverKey = receiverType === "email" ? "receiver" : "groupId"; const response = await popoRequest<{ msgId?: string }>({ cfg: popoCfg, method: "POST", path: "/im/send-msg", body: { [receiverKey]: receiver, msgType: "rich_text", message: { content }, }, }); if (response.code !== 200) { throw new Error(`POPO rich text send failed: ${response.message || `code ${response.code}`}`); } return { messageId: response.result?.msgId, sessionId: receiver, }; } export type SendPopoCardParams = { cfg: ClawdbotConfig; to: string; templateUuid: string; instanceUuid: string; publicVariableMap?: Record; }; /** * Send a card message to POPO. */ export async function sendCardPopo(params: SendPopoCardParams): Promise { const { cfg, to, templateUuid, instanceUuid, publicVariableMap } = params; const popoCfg = cfg.channels?.popo as PopoConfig | undefined; if (!popoCfg) { throw new Error("POPO channel not configured"); } const receiver = normalizePopoTarget(to); if (!receiver) { throw new Error(`Invalid POPO target: ${to}`); } const receiverType = detectReceiverType(receiver); const receiverKey = receiverType === "email" ? "receiver" : "groupId"; const response = await popoRequest<{ msgId?: string }>({ cfg: popoCfg, method: "POST", path: "/im/send-msg", body: { [receiverKey]: receiver, msgType: "card", message: { templateUuid, instanceUuid, publicVariableMap: publicVariableMap ?? {}, }, }, }); if (response.code !== 200) { throw new Error(`POPO card send failed: ${response.message || `code ${response.code}`}`); } return { messageId: response.result?.msgId, sessionId: receiver, }; } /** * Convert markdown-like text to POPO rich text content array. */ export function textToRichTextContent( text: string ): Array<{ tag: string; text?: string }> { // For now, just wrap the entire text in a single text element // More sophisticated parsing could handle bold, links, etc. return [{ tag: "text", text }]; }