UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

135 lines (134 loc) 5.68 kB
import { i as formatErrorMessage } from "./errors-BXgSefBE.js"; import { s as stringEnum } from "./typebox-DCO1JbMn.js"; import "./error-runtime-C8vbtAJt.js"; import "./channel-actions-BOfvC-Gl.js"; import "./setup-core-kty7gX4X.js"; import { n as parseZalouserOutboundTarget } from "./channel-CzqkEhsZ.js"; import "./security-audit-CCOPhPin.js"; import { i as listZaloFriendsMatching, n as getZaloUserInfo, s as listZaloGroupsMatching, t as checkZaloAuthenticated } from "./zalo-js-B1zE_Wyq.js"; import "./setup-surface-OF7ojirC.js"; import "./channel.setup-BIYqAlJI.js"; import { i as sendMessageZalouser, n as sendImageZalouser, r as sendLinkZalouser } from "./send-duv5hIXL.js"; import { Type } from "typebox"; //#region extensions/zalouser/src/tool.ts const ACTIONS = [ "send", "image", "link", "friends", "groups", "me", "status" ]; const ZalouserToolSchema = Type.Object({ action: stringEnum(ACTIONS, { description: `Action to perform: ${ACTIONS.join(", ")}` }), threadId: Type.Optional(Type.String({ description: "Thread ID for messaging" })), message: Type.Optional(Type.String({ description: "Message text" })), isGroup: Type.Optional(Type.Boolean({ description: "Is group chat" })), profile: Type.Optional(Type.String({ description: "Profile name" })), query: Type.Optional(Type.String({ description: "Search query" })), url: Type.Optional(Type.String({ description: "URL for media/link" })) }, { additionalProperties: false }); function json(payload) { return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }], details: payload }; } function resolveAmbientZalouserTarget(context) { const deliveryContext = context?.deliveryContext; const rawTarget = deliveryContext?.to; if ((deliveryContext?.channel === void 0 || deliveryContext.channel === "zalouser") && typeof rawTarget === "string" && rawTarget.trim()) try { return parseZalouserOutboundTarget(rawTarget); } catch {} if (deliveryContext?.channel && deliveryContext.channel !== "zalouser") return {}; const ambientThreadId = deliveryContext?.threadId; if (typeof ambientThreadId === "string" && ambientThreadId.trim()) return { threadId: ambientThreadId.trim() }; if (typeof ambientThreadId === "number" && Number.isFinite(ambientThreadId)) return { threadId: String(ambientThreadId) }; return {}; } function resolveZalouserSendTarget(params, context) { const explicitThreadId = typeof params.threadId === "string" ? params.threadId.trim() : ""; const ambientTarget = resolveAmbientZalouserTarget(context); return { threadId: explicitThreadId || ambientTarget.threadId, isGroup: typeof params.isGroup === "boolean" ? params.isGroup : ambientTarget.isGroup }; } async function executeZalouserTool(_toolCallId, params, _signal, _onUpdate, context) { try { switch (params.action) { case "send": { const target = resolveZalouserSendTarget(params, context); if (!target.threadId || !params.message) throw new Error("threadId and message required for send action"); const result = await sendMessageZalouser(target.threadId, params.message, { profile: params.profile, isGroup: target.isGroup }); if (!result.ok) throw new Error(result.error || "Failed to send message"); return json({ success: true, messageId: result.messageId }); } case "image": { const target = resolveZalouserSendTarget(params, context); if (!target.threadId) throw new Error("threadId required for image action"); if (!params.url) throw new Error("url required for image action"); const result = await sendImageZalouser(target.threadId, params.url, { profile: params.profile, caption: params.message, isGroup: target.isGroup }); if (!result.ok) throw new Error(result.error || "Failed to send image"); return json({ success: true, messageId: result.messageId }); } case "link": { const target = resolveZalouserSendTarget(params, context); if (!target.threadId || !params.url) throw new Error("threadId and url required for link action"); const result = await sendLinkZalouser(target.threadId, params.url, { profile: params.profile, caption: params.message, isGroup: target.isGroup }); if (!result.ok) throw new Error(result.error || "Failed to send link"); return json({ success: true, messageId: result.messageId }); } case "friends": return json(await listZaloFriendsMatching(params.profile, params.query)); case "groups": return json(await listZaloGroupsMatching(params.profile, params.query)); case "me": return json(await getZaloUserInfo(params.profile) ?? { error: "Not authenticated" }); case "status": { const authenticated = await checkZaloAuthenticated(params.profile); return json({ authenticated, output: authenticated ? "authenticated" : "not authenticated" }); } default: params.action; throw new Error(`Unknown action: ${String(params.action)}. Valid actions: send, image, link, friends, groups, me, status`); } } catch (err) { return json({ error: formatErrorMessage(err) }); } } function createZalouserTool(context) { return { name: "zalouser", label: "Zalo Personal", description: "Send messages and access data via Zalo personal account. Actions: send (text message), image (send image URL), link (send link), friends (list/search friends), groups (list groups), me (profile info), status (auth check).", parameters: ZalouserToolSchema, execute: async (toolCallId, params, signal, onUpdate) => await executeZalouserTool(toolCallId, params, signal, onUpdate, context) }; } //#endregion export { createZalouserTool as t };