zalo-agent-cli 1.0.26 → 1.0.28

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/README.md CHANGED
@@ -166,6 +166,7 @@ zalo-agent whoami
166
166
  | `msg send-card <threadId> <userId> [-t 0\|1] [--phone NUM]` | Send contact card |
167
167
  | `msg send-bank <threadId> <accountNum> -b BANK [-n name] [-t 0\|1]` | Send bank card |
168
168
  | `msg send-qr-transfer <threadId> <accountNum> -b BANK [-a amount] [-m content] [--template tpl]` | Send VietQR transfer image |
169
+ | `msg send-link <threadId> <url> [-m caption] [-t 0\|1]` | Send link with auto-preview |
169
170
  | `msg send-video <threadId> <videoUrl> --thumb <thumbUrl> [-m caption] [-d ms] [-W px] [-H px]` | Send video from URL |
170
171
  | `msg sticker <threadId> <keyword> [-t 0\|1]` | Search and send sticker |
171
172
  | `msg react <msgId> <threadId> <emoji> [-t 0\|1]` | React to a message |
@@ -220,6 +221,7 @@ zalo-agent msg send <threadId> "Hello World" --style 0:5:bold 6:5:italic
220
221
  |---------|-------------|
221
222
  | `group list` | List all groups |
222
223
  | `group create <name> <memberIds...>` | Create group |
224
+ | `group history <groupId> [-n count]` | Get chat history (normalized JSON) |
223
225
  | `group info <groupId>` | Group details |
224
226
  | `group members <groupId>` | List members |
225
227
  | `group add-member <groupId> <userIds...>` | Add members |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zalo-agent-cli",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "CLI tool for Zalo automation — multi-account, proxy support, bank transfers, QR payments",
5
5
  "type": "module",
6
6
  "bin": {
@@ -46,6 +46,64 @@ export function registerGroupCommands(program) {
46
46
  }
47
47
  });
48
48
 
49
+ group
50
+ .command("history <groupId>")
51
+ .description("Get group chat history (recent messages)")
52
+ .option("-n, --count <n>", "Number of messages to fetch", "20")
53
+ .action(async (groupId, opts) => {
54
+ try {
55
+ const result = await getApi().getGroupChatHistory(groupId, Number(opts.count));
56
+ const msgs = result?.groupMsgs || [];
57
+
58
+ // Normalize messages into clean, storage-friendly JSON
59
+ const normalized = msgs.map((m) => {
60
+ const d = m.data || m;
61
+ const content = typeof d.content === "string" ? d.content : d.content;
62
+ return {
63
+ msgId: d.msgId,
64
+ cliMsgId: d.cliMsgId,
65
+ fromUid: d.uidFrom,
66
+ groupId: d.idTo,
67
+ msgType: d.msgType,
68
+ content: typeof content === "string" ? content : content,
69
+ timestamp: Number(d.ts),
70
+ isoTime: new Date(Number(d.ts)).toISOString(),
71
+ isSelf: m.isSelf ?? false,
72
+ ...(d.mentions && { mentions: d.mentions }),
73
+ ...(d.quote && {
74
+ quote: {
75
+ ownerId: d.quote.ownerId,
76
+ msg: d.quote.msg,
77
+ msgId: d.quote.globalMsgId,
78
+ },
79
+ }),
80
+ };
81
+ });
82
+
83
+ const payload = {
84
+ groupId,
85
+ count: normalized.length,
86
+ hasMore: result?.more === 1,
87
+ messages: normalized,
88
+ };
89
+
90
+ output(payload, program.opts().json, () => {
91
+ info(`${normalized.length} message(s) in group ${groupId}`);
92
+ if (result?.more === 1) info("(more messages available)");
93
+ console.log();
94
+ for (const m of normalized) {
95
+ const time = new Date(m.timestamp).toLocaleTimeString();
96
+ const dir = m.isSelf ? "→" : "←";
97
+ const text =
98
+ typeof m.content === "string" ? m.content.slice(0, 80) : `[${m.msgType || "attachment"}]`;
99
+ console.log(` ${time} ${dir} ${m.fromUid}: ${text}`);
100
+ }
101
+ });
102
+ } catch (e) {
103
+ error(`Get history failed: ${e.message}`);
104
+ }
105
+ });
106
+
49
107
  group
50
108
  .command("members <groupId>")
51
109
  .description("List group members")
@@ -319,6 +319,20 @@ export function registerMsgCommands(program) {
319
319
  }
320
320
  });
321
321
 
322
+ msg.command("send-link <threadId> <url>")
323
+ .description("Send a link with auto-preview (title, description, thumbnail)")
324
+ .option("-t, --type <n>", "Thread type: 0=User, 1=Group", "0")
325
+ .option("-m, --caption <text>", "Caption text")
326
+ .action(async (threadId, url, opts) => {
327
+ try {
328
+ info(`Sending link: ${url}`);
329
+ const result = await getApi().sendLink({ link: url, msg: opts.caption }, threadId, Number(opts.type));
330
+ output(result, program.opts().json, () => success(`Link sent to ${threadId}`));
331
+ } catch (e) {
332
+ error(`Send link failed: ${e.message}`);
333
+ }
334
+ });
335
+
322
336
  msg.command("send-video <threadId> <videoUrl>")
323
337
  .description("Send a video from URL")
324
338
  .requiredOption("--thumb <url>", "Thumbnail image URL")