@jackle.dev/zalox-plugin 1.0.13 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/send.ts +35 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackle.dev/zalox-plugin",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "OpenClaw channel plugin for Zalo via zca-js (in-process, single login)",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
package/src/send.ts CHANGED
@@ -22,6 +22,20 @@ function cleanText(input: string): string {
22
22
  return input.replace(/<ctrl\d+>/gi, '').trim();
23
23
  }
24
24
 
25
+ async function withRetry<T>(fn: () => Promise<T>, retries = 3, delay = 1000): Promise<T> {
26
+ let lastErr;
27
+ for (let i = 0; i < retries; i++) {
28
+ try {
29
+ return await fn();
30
+ } catch (err) {
31
+ lastErr = err;
32
+ console.warn(`[ZaloX] Send failed (attempt ${i+1}/${retries}): ${err}`);
33
+ await new Promise(r => setTimeout(r, delay * (i + 1)));
34
+ }
35
+ }
36
+ throw lastErr;
37
+ }
38
+
25
39
  export async function sendText(
26
40
  threadId: string,
27
41
  text: string,
@@ -44,15 +58,18 @@ export async function sendText(
44
58
  try {
45
59
  const type = options.isGroup ? ThreadType.Group : ThreadType.User;
46
60
 
47
- // Group support handled by zca-js automatically via threadId format usually,
48
- // but ThreadType is explicit here.
49
61
  console.log(`[ZaloX] Sending text to ${threadId} (type=${type}): "${cleaned.slice(0, 50)}..."`);
50
- const result = await cached.api.sendMessage(cleaned.slice(0, 2000), threadId.trim(), type);
51
- console.log(`[ZaloX] Send result:`, JSON.stringify(result));
52
62
 
63
+ // Add retry logic
64
+ const result = await withRetry(() =>
65
+ cached.api.sendMessage(cleaned.slice(0, 2000), threadId.trim(), type)
66
+ );
67
+
68
+ console.log(`[ZaloX] Send result:`, JSON.stringify(result));
53
69
  const msgId = result?.message?.msgId ? String(result.message.msgId) : undefined;
54
70
  return { ok: true, messageId: msgId };
55
71
  } catch (err: any) {
72
+ console.error(`[ZaloX] Final send error: ${err}`);
56
73
  return { ok: false, error: err.message || String(err) };
57
74
  }
58
75
  }
@@ -87,11 +104,13 @@ export async function sendMedia(
87
104
  }
88
105
 
89
106
  if (filePath) {
90
- // Send with local file attachment
91
- const result = await cached.api.sendMessage(
92
- { msg: cleaned || '', attachments: [filePath] },
93
- threadId.trim(),
94
- type,
107
+ // Send with local file attachment (with retry)
108
+ const result = await withRetry(() =>
109
+ cached.api.sendMessage(
110
+ { msg: cleaned || '', attachments: [filePath!] },
111
+ threadId.trim(),
112
+ type,
113
+ )
95
114
  );
96
115
  const msgId = result?.message?.msgId ? String(result.message.msgId) : undefined;
97
116
  return { ok: true, messageId: msgId };
@@ -112,10 +131,13 @@ export async function sendMedia(
112
131
  writeFileSync(tmpPath, buffer);
113
132
 
114
133
  try {
115
- const result = await cached.api.sendMessage(
116
- { msg: cleaned || '', attachments: [tmpPath] },
117
- threadId.trim(),
118
- type,
134
+ // Send attachment with retry
135
+ const result = await withRetry(() =>
136
+ cached.api.sendMessage(
137
+ { msg: cleaned || '', attachments: [tmpPath!] },
138
+ threadId.trim(),
139
+ type,
140
+ )
119
141
  );
120
142
 
121
143
  const msgId = result?.message?.msgId ? String(result.message.msgId) : undefined;