@ardennguyen/zalo-agent-cli 2.1.1 → 2.2.0
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/.env.example +6 -1
- package/README.md +8 -6
- package/package.json +1 -1
- package/src/commands/listen.js +3 -1
- package/src/commands/mcp.js +3 -1
- package/src/core/accounts.js +25 -2
- package/src/index.js +24 -1
package/.env.example
CHANGED
|
@@ -21,10 +21,15 @@
|
|
|
21
21
|
# ZALO_OA_DIR=
|
|
22
22
|
|
|
23
23
|
# ----------------------------------------------------------------------------
|
|
24
|
-
# Runtime &
|
|
24
|
+
# Runtime & Account Options (Optional)
|
|
25
25
|
# ----------------------------------------------------------------------------
|
|
26
|
+
# Pin a default registered account ID for this environment without changing
|
|
27
|
+
# the global active entry in accounts.json (equivalent to --account <ID>):
|
|
28
|
+
# ZALO_ACCOUNT=
|
|
29
|
+
|
|
26
30
|
# Set to any value (e.g. 1) to disable the background npm update check:
|
|
27
31
|
# ZALO_AGENT_NO_UPDATE_CHECK=1
|
|
28
32
|
|
|
29
33
|
# Protocol version announced to Zalo (default: 691; set 685 to roll back):
|
|
30
34
|
# ZALO_API_VERSION=691
|
|
35
|
+
|
package/README.md
CHANGED
|
@@ -47,12 +47,13 @@ Xây dựng trên [zca-js](https://github.com/RFS-ADRENO/zca-js).
|
|
|
47
47
|
> **MCP Server (AI Agent Integration)** — Model Context Protocol cho Claude Code và các MCP client:
|
|
48
48
|
> ```bash
|
|
49
49
|
> zalo-agent mcp start # stdio (local Claude Code)
|
|
50
|
+
> zalo-agent mcp start --account <ID> # Ghim tài khoản (chạy nhiều tài khoản live cùng lúc)
|
|
50
51
|
> zalo-agent mcp start --http 3847 --auth your-secret # HTTP (VPS)
|
|
51
52
|
> ```
|
|
52
53
|
> 14 tools: `zalo_get_messages` · `zalo_send_message` · `zalo_list_threads` · `zalo_search_threads` · `zalo_mark_read` · `zalo_get_history` · `zalo_view_media` · `zalo_react` · `zalo_undo` · `zalo_get_group_members` · `zalo_list_conversations` · `zalo_coverage` · `zalo_sync` · `zalo_sync_status`
|
|
53
54
|
|
|
54
|
-
[Sync qua MCP
|
|
55
|
-
> Auto-reconnect · thread filter · noise reduction · tự tải media · thông báo qua nhóm Zalo
|
|
55
|
+
[Sync qua MCP](docs/mcp-sync.vi.md) · [Ghim đa tài khoản live](docs/account-pinning.vi.md).
|
|
56
|
+
> Auto-reconnect · thread filter · noise reduction · tự tải media · thông báo qua nhóm Zalo · chạy song song nhiều tài khoản (`--account <ID>`)
|
|
56
57
|
> Xem [MCP Guide](skill/references/mcp-guide.md) · [INSTALLATION.md](INSTALLATION.md)
|
|
57
58
|
|
|
58
59
|
---
|
|
@@ -133,7 +134,7 @@ Xem thêm: [Đa tài khoản & Proxy](https://github.com/ardennguyen/zalo-agent-
|
|
|
133
134
|
## Tính năng
|
|
134
135
|
|
|
135
136
|
- Đăng nhập QR qua HTTP server tự động (browser + terminal), báo ngay khi bị **từ chối trên điện thoại** thay vì treo tới hết 60s
|
|
136
|
-
- Đa tài khoản với proxy riêng biệt (1:1), device fingerprint riêng cho từng tài khoản
|
|
137
|
+
- Đa tài khoản với proxy riêng biệt (1:1), device fingerprint riêng cho từng tài khoản; chạy **nhiều tài khoản live đồng thời** (mỗi tài khoản một tiến trình `mcp start` hoặc `listen` kèm `--account <ID>`, và truyền `--account <ID>` / `ZALO_ACCOUNT` trên mọi lệnh CLI mà không ghi đè `accounts.json`)
|
|
137
138
|
- **190 lệnh** phủ hết tính năng Zalo cá nhân
|
|
138
139
|
- **Zalo Official Account (OA) API v3.0** — OAuth login, gửi tin nhắn, follower, tag, bài viết, cửa hàng, webhook listener, multi-OA
|
|
139
140
|
- **MCP server** (stdio + HTTP) — 14 tools cho Claude Code và các MCP client: đọc, gửi (kể cả vào My Documents, đánh dấu Quan trọng/Khẩn cấp), thả cảm xúc, thu hồi tin, xem thành viên nhóm, liệt kê hội thoại gần đây và kiểm tra độ đầy đủ của cache
|
|
@@ -211,12 +212,13 @@ CLI tool for Zalo automation — multi-account, proxy support, bank transfers, Q
|
|
|
211
212
|
> **MCP Server (AI Agent Integration)** — Model Context Protocol support for Claude Code and MCP clients:
|
|
212
213
|
> ```bash
|
|
213
214
|
> zalo-agent mcp start # stdio (local Claude Code)
|
|
215
|
+
> zalo-agent mcp start --account <ID> # Pin account (run multiple live accounts at once)
|
|
214
216
|
> zalo-agent mcp start --http 3847 --auth your-secret # HTTP (VPS)
|
|
215
217
|
> ```
|
|
216
218
|
> 14 tools: `zalo_get_messages` · `zalo_send_message` · `zalo_list_threads` · `zalo_search_threads` · `zalo_mark_read` · `zalo_get_history` · `zalo_view_media` · `zalo_react` · `zalo_undo` · `zalo_get_group_members` · `zalo_list_conversations` · `zalo_coverage` · `zalo_sync` · `zalo_sync_status`
|
|
217
219
|
|
|
218
|
-
[MCP sync
|
|
219
|
-
> Auto-reconnect · thread filter · noise reduction · media auto-download · Zalo-group notifications
|
|
220
|
+
[MCP sync](docs/mcp-sync.md) · [Multi-account pinning](docs/account-pinning.md).
|
|
221
|
+
> Auto-reconnect · thread filter · noise reduction · media auto-download · Zalo-group notifications · concurrent multi-account (`--account <ID>`)
|
|
220
222
|
> See [MCP Guide](skill/references/mcp-guide.md) · [INSTALLATION.md](INSTALLATION.md)
|
|
221
223
|
|
|
222
224
|
### Quick Start
|
|
@@ -261,7 +263,7 @@ See also: [Multi-Account & Proxy](https://github.com/ardennguyen/zalo-agent-cli/
|
|
|
261
263
|
### Features
|
|
262
264
|
|
|
263
265
|
- QR login over an auto-started HTTP server (browser + terminal), reporting a **decline on the phone** immediately instead of hanging until the 60s timeout
|
|
264
|
-
- Multi-account with a dedicated proxy (1:1) and a per-account device fingerprint
|
|
266
|
+
- Multi-account with a dedicated proxy (1:1) and a per-account device fingerprint; run **multiple live accounts simultaneously** (one `mcp start` or `listen` process per account with `--account <ID>`, plus `--account <ID>` / `ZALO_ACCOUNT` on any CLI command without mutating `accounts.json`)
|
|
265
267
|
- **190 commands** covering the personal-account Zalo surface
|
|
266
268
|
- **Zalo Official Account (OA) API v3.0** — OAuth login, messaging, followers, tags, articles, store, webhook listener, multi-OA
|
|
267
269
|
- **MCP server** (stdio + HTTP) — 14 tools for Claude Code and other MCP clients: read, send (to My Documents too, marked Important/Urgent), react, recall, list a group's members, list recent conversations, and check how complete the cache is
|
package/package.json
CHANGED
package/src/commands/listen.js
CHANGED
|
@@ -84,7 +84,9 @@ export function registerListenCommand(program) {
|
|
|
84
84
|
.action(async (opts) => {
|
|
85
85
|
let activeAcc;
|
|
86
86
|
try {
|
|
87
|
-
|
|
87
|
+
const requestedAccount =
|
|
88
|
+
opts.account ?? program.opts().account ?? (process.env.ZALO_ACCOUNT?.trim() || undefined);
|
|
89
|
+
activeAcc = selectDaemonAccount(requestedAccount);
|
|
88
90
|
} catch (e) {
|
|
89
91
|
error(e.message);
|
|
90
92
|
process.exit(1);
|
package/src/commands/mcp.js
CHANGED
|
@@ -143,7 +143,9 @@ export function registerMCPCommands(program) {
|
|
|
143
143
|
// Select once; acquire the selected account's lock before authentication.
|
|
144
144
|
let activeAcc;
|
|
145
145
|
try {
|
|
146
|
-
|
|
146
|
+
const requestedAccount =
|
|
147
|
+
opts.account ?? program.opts().account ?? (process.env.ZALO_ACCOUNT?.trim() || undefined);
|
|
148
|
+
activeAcc = selectDaemonAccount(requestedAccount);
|
|
147
149
|
} catch (e) {
|
|
148
150
|
console.error("[mcp] Account selection failed:", e.message);
|
|
149
151
|
process.exit(1);
|
package/src/core/accounts.js
CHANGED
|
@@ -33,14 +33,37 @@ function save(accounts) {
|
|
|
33
33
|
chmodSync(file, 0o600);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
let _pinnedAccountId = null;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Pin this process's target account ID without modifying accounts.json on disk.
|
|
40
|
+
* Used when `--account <id>` or `ZALO_ACCOUNT` is passed to a CLI command.
|
|
41
|
+
* @param {string|null|undefined} ownId
|
|
42
|
+
*/
|
|
43
|
+
export function setPinnedAccount(ownId) {
|
|
44
|
+
_pinnedAccountId = ownId ? String(ownId) : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Return the process-pinned account ID if set, or null.
|
|
49
|
+
* @returns {string|null}
|
|
50
|
+
*/
|
|
51
|
+
export function getPinnedAccountId() {
|
|
52
|
+
return _pinnedAccountId;
|
|
53
|
+
}
|
|
54
|
+
|
|
36
55
|
/** List all registered accounts. */
|
|
37
56
|
export function listAccounts() {
|
|
38
57
|
return load();
|
|
39
58
|
}
|
|
40
59
|
|
|
41
|
-
/** Get currently active account or null. */
|
|
60
|
+
/** Get currently active (or process-pinned) account or null. */
|
|
42
61
|
export function getActive() {
|
|
43
|
-
|
|
62
|
+
const accounts = load();
|
|
63
|
+
if (_pinnedAccountId !== null) {
|
|
64
|
+
return accounts.find((a) => a.ownId === _pinnedAccountId) || null;
|
|
65
|
+
}
|
|
66
|
+
return accounts.find((a) => a.active) || null;
|
|
44
67
|
}
|
|
45
68
|
|
|
46
69
|
/** Set an account as active (deactivates others). Returns false if not found. */
|
package/src/index.js
CHANGED
|
@@ -30,7 +30,8 @@ import { registerOACommands } from "./commands/oa.js";
|
|
|
30
30
|
import { registerMCPCommands } from "./commands/mcp.js";
|
|
31
31
|
import { registerSyncCommands } from "./commands/sync.js";
|
|
32
32
|
import { autoLogin } from "./core/zalo-client.js";
|
|
33
|
-
import { getActive } from "./core/accounts.js";
|
|
33
|
+
import { getActive, setPinnedAccount } from "./core/accounts.js";
|
|
34
|
+
import { parseAccountId, selectDaemonAccount } from "./core/daemon-account.js";
|
|
34
35
|
import { configureStoragePaths } from "./core/credentials.js";
|
|
35
36
|
import { logoutNeedsSession } from "./core/logout.js";
|
|
36
37
|
import { checkForUpdates, selfUpdate } from "./utils/update-check.js";
|
|
@@ -47,6 +48,11 @@ program
|
|
|
47
48
|
.description("CLI tool for Zalo automation — multi-account, proxy, bank transfers, QR payments")
|
|
48
49
|
.version(pkg.version)
|
|
49
50
|
.option("--json", "Output results as JSON (machine-readable)")
|
|
51
|
+
.option(
|
|
52
|
+
"--account <id>",
|
|
53
|
+
"Pin this command to an exact registered account ID without changing the active account (env: ZALO_ACCOUNT)",
|
|
54
|
+
parseAccountId,
|
|
55
|
+
)
|
|
50
56
|
.option("--env-file <path>", "Load environment variables from a .env file (env: ZALO_ENV_FILE)")
|
|
51
57
|
.option("--config-dir <dir>", "Config directory (default: ~/.zalo-agent-cli, env: ZALO_CONFIG_DIR)")
|
|
52
58
|
.option(
|
|
@@ -79,6 +85,23 @@ program
|
|
|
79
85
|
warning(DISCLAIMER);
|
|
80
86
|
console.log();
|
|
81
87
|
}
|
|
88
|
+
// Pin the target account for this invocation when --account or ZALO_ACCOUNT is set,
|
|
89
|
+
// without changing the global active entry in accounts.json. Daemons (`listen`, `mcp`)
|
|
90
|
+
// perform their own selection and lock acquisition inside their command actions.
|
|
91
|
+
const envAccount = process.env.ZALO_ACCOUNT?.trim() || undefined;
|
|
92
|
+
const requestedAccount = actionCommand.opts()?.account ?? globalOpts.account ?? envAccount;
|
|
93
|
+
if (
|
|
94
|
+
requestedAccount !== undefined &&
|
|
95
|
+
!["mcp", "listen", "oa", "update", "help", "version", "login"].includes(cmdName)
|
|
96
|
+
) {
|
|
97
|
+
try {
|
|
98
|
+
const pinned = selectDaemonAccount(requestedAccount);
|
|
99
|
+
setPinnedAccount(pinned.ownId);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
error(e.message);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
82
105
|
// Auto-login before any command that needs it (skip for login/account/oa
|
|
83
106
|
// commands, and for a logout that will not call Zalo at all).
|
|
84
107
|
// Daemons authenticate their pinned identity after acquiring its lock.
|