zalo-agent-cli 1.0.5 → 1.0.7
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.
- package/package.json +1 -1
- package/src/commands/friend.js +3 -1
- package/src/commands/msg.js +66 -2
package/package.json
CHANGED
package/src/commands/friend.js
CHANGED
|
@@ -52,7 +52,9 @@ export function registerFriendCommands(program) {
|
|
|
52
52
|
try {
|
|
53
53
|
const result = await getApi().findUser(query);
|
|
54
54
|
if (!result || (!result.uid && !result?.data?.uid)) {
|
|
55
|
-
error(
|
|
55
|
+
error(
|
|
56
|
+
`No Zalo user found for "${query}". User may not exist, has disabled phone search, or phone is not registered on Zalo.`,
|
|
57
|
+
);
|
|
56
58
|
return;
|
|
57
59
|
}
|
|
58
60
|
output(result, program.opts().json, () => {
|
package/src/commands/msg.js
CHANGED
|
@@ -13,10 +13,26 @@ export function registerMsgCommands(program) {
|
|
|
13
13
|
msg.command("send <threadId> <message>")
|
|
14
14
|
.description("Send a text message")
|
|
15
15
|
.option("-t, --type <n>", "Thread type: 0=User, 1=Group", "0")
|
|
16
|
+
.option("--react <icon>", "Auto-react to the sent message (e.g. :> for haha)")
|
|
16
17
|
.action(async (threadId, message, opts) => {
|
|
17
18
|
try {
|
|
19
|
+
// Capture clientId before send — zca-js uses Date.now() internally
|
|
20
|
+
const cliMsgId = String(Date.now());
|
|
18
21
|
const result = await getApi().sendMessage(message, threadId, Number(opts.type));
|
|
22
|
+
// Include cliMsgId in output for later use with react command
|
|
23
|
+
result.cliMsgId = cliMsgId;
|
|
19
24
|
output(result, program.opts().json, () => success("Message sent"));
|
|
25
|
+
|
|
26
|
+
// Auto-react if --react flag provided
|
|
27
|
+
if (opts.react && result.message?.msgId) {
|
|
28
|
+
const dest = {
|
|
29
|
+
data: { msgId: String(result.message.msgId), cliMsgId },
|
|
30
|
+
threadId,
|
|
31
|
+
type: Number(opts.type),
|
|
32
|
+
};
|
|
33
|
+
await getApi().addReaction(opts.react, dest);
|
|
34
|
+
success(`Auto-reacted with '${opts.react}'`);
|
|
35
|
+
}
|
|
20
36
|
} catch (e) {
|
|
21
37
|
error(e.message);
|
|
22
38
|
}
|
|
@@ -190,12 +206,60 @@ export function registerMsgCommands(program) {
|
|
|
190
206
|
msg.command("react <msgId> <threadId> <reaction>")
|
|
191
207
|
.description("React to a message with an emoji")
|
|
192
208
|
.option("-t, --type <n>", "Thread type: 0=User, 1=Group", "0")
|
|
209
|
+
.option("-c, --cli-msg-id <id>", "Client message ID (defaults to msgId)")
|
|
193
210
|
.action(async (msgId, threadId, reaction, opts) => {
|
|
194
211
|
try {
|
|
195
|
-
|
|
212
|
+
// zca-js addReaction(icon, dest) — dest needs msgId + cliMsgId
|
|
213
|
+
const dest = {
|
|
214
|
+
data: { msgId, cliMsgId: opts.cliMsgId || msgId },
|
|
215
|
+
threadId,
|
|
216
|
+
type: Number(opts.type),
|
|
217
|
+
};
|
|
218
|
+
const result = await getApi().addReaction(reaction, dest);
|
|
196
219
|
output(result, program.opts().json, () => success(`Reacted with '${reaction}'`));
|
|
197
220
|
} catch (e) {
|
|
198
|
-
error(e.message);
|
|
221
|
+
error(`React failed: ${e.message}`);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
msg.command("listen")
|
|
226
|
+
.description("Listen for incoming messages (Ctrl+C to stop)")
|
|
227
|
+
.action(async () => {
|
|
228
|
+
try {
|
|
229
|
+
const api = getApi();
|
|
230
|
+
info("Listening for messages... Press Ctrl+C to stop.");
|
|
231
|
+
info("Note: Only one web listener per account. Browser Zalo will disconnect.");
|
|
232
|
+
|
|
233
|
+
api.listener.on("message", (msg) => {
|
|
234
|
+
const content = typeof msg.data.content === "string" ? msg.data.content : "[non-text]";
|
|
235
|
+
const data = {
|
|
236
|
+
msgId: msg.data.msgId,
|
|
237
|
+
cliMsgId: msg.data.cliMsgId,
|
|
238
|
+
threadId: msg.threadId,
|
|
239
|
+
type: msg.type,
|
|
240
|
+
isSelf: msg.isSelf,
|
|
241
|
+
content,
|
|
242
|
+
};
|
|
243
|
+
if (program.opts().json) {
|
|
244
|
+
console.log(JSON.stringify(data));
|
|
245
|
+
} else {
|
|
246
|
+
const dir = msg.isSelf ? "→" : "←";
|
|
247
|
+
console.log(` ${dir} [${msg.threadId}] ${content} (msgId: ${msg.data.msgId})`);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
api.listener.start();
|
|
252
|
+
|
|
253
|
+
// Keep alive until Ctrl+C
|
|
254
|
+
await new Promise((resolve) => {
|
|
255
|
+
process.on("SIGINT", () => {
|
|
256
|
+
api.listener.stop();
|
|
257
|
+
info("Listener stopped.");
|
|
258
|
+
resolve();
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
} catch (e) {
|
|
262
|
+
error(`Listen failed: ${e.message}`);
|
|
199
263
|
}
|
|
200
264
|
});
|
|
201
265
|
|