mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 10:47:41 +00:00
feat(zalouser): migrate runtime to native zca-js
This commit is contained in:
@@ -1,104 +1,15 @@
|
||||
import { runZca } from "./zca.js";
|
||||
import type { ZaloSendOptions, ZaloSendResult } from "./types.js";
|
||||
import { sendZaloLink, sendZaloTextMessage } from "./zalo-js.js";
|
||||
|
||||
export type ZalouserSendOptions = {
|
||||
profile?: string;
|
||||
mediaUrl?: string;
|
||||
caption?: string;
|
||||
isGroup?: boolean;
|
||||
};
|
||||
|
||||
export type ZalouserSendResult = {
|
||||
ok: boolean;
|
||||
messageId?: string;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
function resolveProfile(options: ZalouserSendOptions): string {
|
||||
return options.profile || process.env.ZCA_PROFILE || "default";
|
||||
}
|
||||
|
||||
function appendCaptionAndGroupFlags(args: string[], options: ZalouserSendOptions): void {
|
||||
if (options.caption) {
|
||||
args.push("-m", options.caption.slice(0, 2000));
|
||||
}
|
||||
if (options.isGroup) {
|
||||
args.push("-g");
|
||||
}
|
||||
}
|
||||
|
||||
async function runSendCommand(
|
||||
args: string[],
|
||||
profile: string,
|
||||
fallbackError: string,
|
||||
): Promise<ZalouserSendResult> {
|
||||
try {
|
||||
const result = await runZca(args, { profile });
|
||||
if (result.ok) {
|
||||
return { ok: true, messageId: extractMessageId(result.stdout) };
|
||||
}
|
||||
return { ok: false, error: result.stderr || fallbackError };
|
||||
} catch (err) {
|
||||
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
||||
}
|
||||
}
|
||||
export type ZalouserSendOptions = ZaloSendOptions;
|
||||
export type ZalouserSendResult = ZaloSendResult;
|
||||
|
||||
export async function sendMessageZalouser(
|
||||
threadId: string,
|
||||
text: string,
|
||||
options: ZalouserSendOptions = {},
|
||||
): Promise<ZalouserSendResult> {
|
||||
const profile = resolveProfile(options);
|
||||
|
||||
if (!threadId?.trim()) {
|
||||
return { ok: false, error: "No threadId provided" };
|
||||
}
|
||||
|
||||
// Handle media sending
|
||||
if (options.mediaUrl) {
|
||||
return sendMediaZalouser(threadId, options.mediaUrl, {
|
||||
...options,
|
||||
caption: text || options.caption,
|
||||
});
|
||||
}
|
||||
|
||||
// Send text message
|
||||
const args = ["msg", "send", threadId.trim(), text.slice(0, 2000)];
|
||||
if (options.isGroup) {
|
||||
args.push("-g");
|
||||
}
|
||||
|
||||
return runSendCommand(args, profile, "Failed to send message");
|
||||
}
|
||||
|
||||
async function sendMediaZalouser(
|
||||
threadId: string,
|
||||
mediaUrl: string,
|
||||
options: ZalouserSendOptions = {},
|
||||
): Promise<ZalouserSendResult> {
|
||||
const profile = resolveProfile(options);
|
||||
|
||||
if (!threadId?.trim()) {
|
||||
return { ok: false, error: "No threadId provided" };
|
||||
}
|
||||
|
||||
if (!mediaUrl?.trim()) {
|
||||
return { ok: false, error: "No media URL provided" };
|
||||
}
|
||||
|
||||
// Determine media type from URL
|
||||
const lowerUrl = mediaUrl.toLowerCase();
|
||||
let command: string;
|
||||
if (lowerUrl.match(/\.(mp4|mov|avi|webm)$/)) {
|
||||
command = "video";
|
||||
} else if (lowerUrl.match(/\.(mp3|wav|ogg|m4a)$/)) {
|
||||
command = "voice";
|
||||
} else {
|
||||
command = "image";
|
||||
}
|
||||
|
||||
const args = ["msg", command, threadId.trim(), "-u", mediaUrl.trim()];
|
||||
appendCaptionAndGroupFlags(args, options);
|
||||
return runSendCommand(args, profile, `Failed to send ${command}`);
|
||||
return await sendZaloTextMessage(threadId, text, options);
|
||||
}
|
||||
|
||||
export async function sendImageZalouser(
|
||||
@@ -106,10 +17,10 @@ export async function sendImageZalouser(
|
||||
imageUrl: string,
|
||||
options: ZalouserSendOptions = {},
|
||||
): Promise<ZalouserSendResult> {
|
||||
const profile = resolveProfile(options);
|
||||
const args = ["msg", "image", threadId.trim(), "-u", imageUrl.trim()];
|
||||
appendCaptionAndGroupFlags(args, options);
|
||||
return runSendCommand(args, profile, "Failed to send image");
|
||||
return await sendZaloTextMessage(threadId, options.caption ?? "", {
|
||||
...options,
|
||||
mediaUrl: imageUrl,
|
||||
});
|
||||
}
|
||||
|
||||
export async function sendLinkZalouser(
|
||||
@@ -117,25 +28,5 @@ export async function sendLinkZalouser(
|
||||
url: string,
|
||||
options: ZalouserSendOptions = {},
|
||||
): Promise<ZalouserSendResult> {
|
||||
const profile = resolveProfile(options);
|
||||
const args = ["msg", "link", threadId.trim(), url.trim()];
|
||||
if (options.isGroup) {
|
||||
args.push("-g");
|
||||
}
|
||||
|
||||
return runSendCommand(args, profile, "Failed to send link");
|
||||
}
|
||||
|
||||
function extractMessageId(stdout: string): string | undefined {
|
||||
// Try to extract message ID from output
|
||||
const match = stdout.match(/message[_\s]?id[:\s]+(\S+)/i);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
// Return first word if it looks like an ID
|
||||
const firstWord = stdout.trim().split(/\s+/)[0];
|
||||
if (firstWord && /^[a-zA-Z0-9_-]+$/.test(firstWord)) {
|
||||
return firstWord;
|
||||
}
|
||||
return undefined;
|
||||
return await sendZaloLink(threadId, url, options);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user