@jackle.dev/zalox-plugin 1.0.18 → 1.0.19

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 +17 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackle.dev/zalox-plugin",
3
- "version": "1.0.18",
3
+ "version": "1.0.19",
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,12 @@ function cleanText(input: string): string {
22
22
  return input.replace(/<ctrl\d+>/gi, '').trim();
23
23
  }
24
24
 
25
+ function cleanThreadId(id: string): string {
26
+ if (!id) return '';
27
+ // Remove zalox: or zx: prefix commonly added by OpenClaw routing
28
+ return id.replace(/^(zalox|zx):/i, '').trim();
29
+ }
30
+
25
31
  async function withRetry<T>(fn: () => Promise<T>, retries = 3, delay = 1000): Promise<T> {
26
32
  let lastErr;
27
33
  for (let i = 0; i < retries; i++) {
@@ -41,7 +47,8 @@ export async function sendText(
41
47
  text: string,
42
48
  options: { profile: string; isGroup?: boolean } = { profile: 'default' },
43
49
  ): Promise<SendResult> {
44
- if (!threadId?.trim()) {
50
+ const cleanId = cleanThreadId(threadId);
51
+ if (!cleanId) {
45
52
  return { ok: false, error: 'No threadId provided' };
46
53
  }
47
54
 
@@ -58,11 +65,11 @@ export async function sendText(
58
65
  try {
59
66
  const type = options.isGroup ? ThreadType.Group : ThreadType.User;
60
67
 
61
- console.log(`[ZaloX] Sending text to ${threadId} (type=${type}): "${cleaned.slice(0, 50)}..."`);
68
+ console.log(`[ZaloX] Sending text to ${cleanId} (type=${type}): "${cleaned.slice(0, 50)}..."`);
62
69
 
63
70
  // Add retry logic
64
71
  const result = await withRetry(() =>
65
- cached.api.sendMessage(cleaned.slice(0, 2000), threadId.trim(), type)
72
+ cached.api.sendMessage(cleaned.slice(0, 2000), cleanId, type)
66
73
  );
67
74
 
68
75
  console.log(`[ZaloX] Send result:`, JSON.stringify(result));
@@ -80,7 +87,8 @@ export async function sendMedia(
80
87
  mediaUrl: string,
81
88
  options: { profile: string; isGroup?: boolean } = { profile: 'default' },
82
89
  ): Promise<SendResult> {
83
- if (!threadId?.trim()) {
90
+ const cleanId = cleanThreadId(threadId);
91
+ if (!cleanId) {
84
92
  return { ok: false, error: 'No threadId provided' };
85
93
  }
86
94
 
@@ -108,7 +116,7 @@ export async function sendMedia(
108
116
  const result = await withRetry(() =>
109
117
  cached.api.sendMessage(
110
118
  { msg: cleaned || '', attachments: [filePath!] },
111
- threadId.trim(),
119
+ cleanId,
112
120
  type,
113
121
  )
114
122
  );
@@ -135,7 +143,7 @@ export async function sendMedia(
135
143
  const result = await withRetry(() =>
136
144
  cached.api.sendMessage(
137
145
  { msg: cleaned || '', attachments: [tmpPath!] },
138
- threadId.trim(),
146
+ cleanId,
139
147
  type,
140
148
  )
141
149
  );
@@ -146,12 +154,12 @@ export async function sendMedia(
146
154
  console.error(`[ZaloX] Send attachment failed: ${sendErr}`);
147
155
  // Fallback: send text with URL as link
148
156
  const fullText = cleaned ? `${cleaned}\n${mediaUrl}` : mediaUrl;
149
- return sendText(threadId, fullText, options);
157
+ return sendText(cleanId, fullText, options);
150
158
  }
151
159
  } catch (dlErr: any) {
152
160
  // Fallback: send text with URL as link
153
161
  const fullText = cleaned ? `${cleaned}\n${mediaUrl}` : mediaUrl;
154
- return sendText(threadId, fullText, options);
162
+ return sendText(cleanId, fullText, options);
155
163
  } finally {
156
164
  if (tmpPath) try { unlinkSync(tmpPath); } catch {}
157
165
  }
@@ -159,7 +167,7 @@ export async function sendMedia(
159
167
 
160
168
  // Fallback: send text only
161
169
  const fullText = cleaned ? `${cleaned}\n${mediaUrl}` : mediaUrl;
162
- return sendText(threadId, fullText, options);
170
+ return sendText(cleanId, fullText, options);
163
171
  } catch (err: any) {
164
172
  return { ok: false, error: err.message || String(err) };
165
173
  }