zalo-agent-cli 1.0.7 → 1.0.8
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/msg.js +46 -8
package/package.json
CHANGED
package/src/commands/msg.js
CHANGED
|
@@ -13,7 +13,10 @@ 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(
|
|
16
|
+
.option(
|
|
17
|
+
"--react <icon>",
|
|
18
|
+
"Auto-react to sent message. Codes: :> (haha), /-heart (heart), /-strong (like), :o (wow), :-(( (cry), :-h (angry)",
|
|
19
|
+
)
|
|
17
20
|
.action(async (threadId, message, opts) => {
|
|
18
21
|
try {
|
|
19
22
|
// Capture clientId before send — zca-js uses Date.now() internally
|
|
@@ -204,9 +207,14 @@ export function registerMsgCommands(program) {
|
|
|
204
207
|
});
|
|
205
208
|
|
|
206
209
|
msg.command("react <msgId> <threadId> <reaction>")
|
|
207
|
-
.description(
|
|
210
|
+
.description(
|
|
211
|
+
"React to a message. Reaction codes: :> (haha), /-heart (heart), /-strong (like), :o (wow), :-(( (cry), :-h (angry)",
|
|
212
|
+
)
|
|
208
213
|
.option("-t, --type <n>", "Thread type: 0=User, 1=Group", "0")
|
|
209
|
-
.option(
|
|
214
|
+
.option(
|
|
215
|
+
"-c, --cli-msg-id <id>",
|
|
216
|
+
"Client message ID (required for reaction to appear, get from msg listen --json)",
|
|
217
|
+
)
|
|
210
218
|
.action(async (msgId, threadId, reaction, opts) => {
|
|
211
219
|
try {
|
|
212
220
|
// zca-js addReaction(icon, dest) — dest needs msgId + cliMsgId
|
|
@@ -223,14 +231,28 @@ export function registerMsgCommands(program) {
|
|
|
223
231
|
});
|
|
224
232
|
|
|
225
233
|
msg.command("listen")
|
|
226
|
-
.description(
|
|
227
|
-
|
|
234
|
+
.description(
|
|
235
|
+
"Listen for incoming messages in real-time via WebSocket. Outputs msgId + cliMsgId needed for react. Use --json for machine parsing.",
|
|
236
|
+
)
|
|
237
|
+
.option("-f, --filter <type>", "Filter messages: user (DM only), group (groups only), all (default)", "all")
|
|
238
|
+
.option("-w, --webhook <url>", "POST each message as JSON to this URL (for n8n, Make, etc.)")
|
|
239
|
+
.option("--no-self", "Exclude messages sent by this account")
|
|
240
|
+
.action(async (opts) => {
|
|
228
241
|
try {
|
|
229
242
|
const api = getApi();
|
|
243
|
+
const jsonMode = program.opts().json;
|
|
230
244
|
info("Listening for messages... Press Ctrl+C to stop.");
|
|
231
245
|
info("Note: Only one web listener per account. Browser Zalo will disconnect.");
|
|
246
|
+
if (opts.filter !== "all") info(`Filter: ${opts.filter} messages only`);
|
|
247
|
+
if (opts.webhook) info(`Webhook: POST to ${opts.webhook}`);
|
|
248
|
+
|
|
249
|
+
api.listener.on("message", async (msg) => {
|
|
250
|
+
// Filter by type: 0=User, 1=Group
|
|
251
|
+
if (opts.filter === "user" && msg.type !== 0) return;
|
|
252
|
+
if (opts.filter === "group" && msg.type !== 1) return;
|
|
253
|
+
// Filter self messages
|
|
254
|
+
if (!opts.self && msg.isSelf) return;
|
|
232
255
|
|
|
233
|
-
api.listener.on("message", (msg) => {
|
|
234
256
|
const content = typeof msg.data.content === "string" ? msg.data.content : "[non-text]";
|
|
235
257
|
const data = {
|
|
236
258
|
msgId: msg.data.msgId,
|
|
@@ -240,11 +262,27 @@ export function registerMsgCommands(program) {
|
|
|
240
262
|
isSelf: msg.isSelf,
|
|
241
263
|
content,
|
|
242
264
|
};
|
|
243
|
-
|
|
265
|
+
|
|
266
|
+
// Output to stdout
|
|
267
|
+
if (jsonMode) {
|
|
244
268
|
console.log(JSON.stringify(data));
|
|
245
269
|
} else {
|
|
246
270
|
const dir = msg.isSelf ? "→" : "←";
|
|
247
|
-
|
|
271
|
+
const typeLabel = msg.type === 0 ? "DM" : "GR";
|
|
272
|
+
console.log(` ${dir} [${typeLabel}] [${msg.threadId}] ${content} (msgId: ${msg.data.msgId})`);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// POST to webhook if configured
|
|
276
|
+
if (opts.webhook) {
|
|
277
|
+
try {
|
|
278
|
+
await fetch(opts.webhook, {
|
|
279
|
+
method: "POST",
|
|
280
|
+
headers: { "Content-Type": "application/json" },
|
|
281
|
+
body: JSON.stringify(data),
|
|
282
|
+
});
|
|
283
|
+
} catch {
|
|
284
|
+
// Silent webhook failure — don't block listener
|
|
285
|
+
}
|
|
248
286
|
}
|
|
249
287
|
});
|
|
250
288
|
|