zalo-agent-cli 1.0.19 → 1.0.20

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
@@ -111,7 +111,26 @@ zalo-agent msg send <THREAD_ID> "Hello group!" -t 1
111
111
  zalo-agent friend list
112
112
  ```
113
113
 
114
- #### 4. Check status
114
+ #### 5. Manage your profile
115
+
116
+ ```bash
117
+ # View your profile
118
+ zalo-agent profile me
119
+
120
+ # Change avatar
121
+ zalo-agent profile avatar /path/to/photo.jpg
122
+
123
+ # Update bio
124
+ zalo-agent profile bio "Phụ tùng ô tô chính hãng"
125
+
126
+ # View privacy settings
127
+ zalo-agent profile settings
128
+
129
+ # Update a setting (e.g. hide online status)
130
+ zalo-agent profile set online-status 0
131
+ ```
132
+
133
+ #### 6. Check status
115
134
 
116
135
  ```bash
117
136
  zalo-agent status
@@ -197,6 +216,19 @@ zalo-agent whoami
197
216
  | `conv unread <threadId> [-t 0\|1]` | Mark as unread |
198
217
  | `conv delete <threadId> [-t 0\|1]` | Delete conversation |
199
218
 
219
+ #### Profile (`profile`)
220
+
221
+ | Command | Description |
222
+ |---------|-------------|
223
+ | `profile me` | Show your profile (name, phone, avatar, etc.) |
224
+ | `profile avatar <imagePath>` | Change profile avatar |
225
+ | `profile bio [text]` | View or update bio/status |
226
+ | `profile update [-n name] [-d YYYY-MM-DD] [-g 0\|1]` | Update name, birthday, gender |
227
+ | `profile settings` | View privacy settings |
228
+ | `profile set <setting> <value>` | Update a privacy setting |
229
+
230
+ **Privacy settings:** `online-status`, `seen-status`, `birthday`, `receive-msg`, `accept-call`, `add-by-phone`, `add-by-qr`, `add-by-group`, `recommend`
231
+
200
232
  #### Accounts (`account`)
201
233
 
202
234
  | Command | Description |
@@ -417,6 +449,25 @@ zalo-agent msg send <THREAD_ID> "Xin chào nhóm!" -t 1
417
449
  zalo-agent friend list
418
450
  ```
419
451
 
452
+ #### 5. Quản lý hồ sơ cá nhân
453
+
454
+ ```bash
455
+ # Xem hồ sơ
456
+ zalo-agent profile me
457
+
458
+ # Đổi ảnh đại diện
459
+ zalo-agent profile avatar /đường/dẫn/ảnh.jpg
460
+
461
+ # Cập nhật tiểu sử
462
+ zalo-agent profile bio "Phụ tùng ô tô chính hãng"
463
+
464
+ # Xem cài đặt quyền riêng tư
465
+ zalo-agent profile settings
466
+
467
+ # Thay đổi cài đặt (VD: ẩn trạng thái online)
468
+ zalo-agent profile set online-status 0
469
+ ```
470
+
420
471
  ### Danh sách lệnh
421
472
 
422
473
  Xem đầy đủ tại [phần tiếng Anh](#command-reference) phía trên. Tất cả lệnh đều giống nhau.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zalo-agent-cli",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "CLI tool for Zalo automation — multi-account, proxy support, bank transfers, QR payments",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Profile commands — view/update profile, avatar, bio, and privacy settings.
3
+ */
4
+
5
+ import { resolve } from "path";
6
+ import { getApi } from "../core/zalo-client.js";
7
+ import { success, error, info, output } from "../utils/output.js";
8
+
9
+ /** Valid privacy setting keys and their human-readable labels + value descriptions. */
10
+ const SETTING_MAP = {
11
+ "online-status": {
12
+ key: "show_online_status",
13
+ label: "Show online status",
14
+ values: { 0: "hidden", 1: "visible" },
15
+ },
16
+ "seen-status": {
17
+ key: "display_seen_status",
18
+ label: "Display seen status",
19
+ values: { 0: "hidden", 1: "visible" },
20
+ },
21
+ "birthday": {
22
+ key: "view_birthday",
23
+ label: "Birthday visibility",
24
+ values: { 0: "hidden", 1: "full (day/month/year)", 2: "partial (day/month)" },
25
+ },
26
+ "receive-msg": {
27
+ key: "receive_message",
28
+ label: "Receive messages from",
29
+ values: { 1: "everyone", 2: "friends only" },
30
+ },
31
+ "accept-call": {
32
+ key: "accept_stranger_call",
33
+ label: "Accept calls from",
34
+ values: { 2: "friends only", 3: "everyone", 4: "friends + contacted" },
35
+ },
36
+ "add-by-phone": {
37
+ key: "add_friend_via_phone",
38
+ label: "Find by phone number",
39
+ values: { 0: "disabled", 1: "enabled" },
40
+ },
41
+ "add-by-qr": {
42
+ key: "add_friend_via_qr",
43
+ label: "Find by QR code",
44
+ values: { 0: "disabled", 1: "enabled" },
45
+ },
46
+ "add-by-group": {
47
+ key: "add_friend_via_group",
48
+ label: "Find via group",
49
+ values: { 0: "disabled", 1: "enabled" },
50
+ },
51
+ "recommend": {
52
+ key: "display_on_recommend_friend",
53
+ label: "Show in friend recommendations",
54
+ values: { 0: "disabled", 1: "enabled" },
55
+ },
56
+ };
57
+
58
+ export function registerProfileCommands(program) {
59
+ const profile = program.command("profile").description("View and update your Zalo profile and settings");
60
+
61
+ profile
62
+ .command("me")
63
+ .description("Show current account profile")
64
+ .action(async () => {
65
+ try {
66
+ const result = await getApi().fetchAccountInfo();
67
+ const p = result?.profile || {};
68
+ output(result, program.opts().json, () => {
69
+ info(`Name: ${p.displayName || p.zaloName || "?"}`);
70
+ info(`User ID: ${p.userId || "?"}`);
71
+ info(`Phone: ${p.phoneNumber || "?"}`);
72
+ info(`Gender: ${p.gender === 0 ? "Male" : p.gender === 1 ? "Female" : "?"}`);
73
+ info(`DOB: ${p.sdob || "?"}`);
74
+ info(`Status: ${p.status || "(none)"}`);
75
+ info(`Avatar: ${p.avatar || "?"}`);
76
+ });
77
+ } catch (e) {
78
+ error(e.message);
79
+ }
80
+ });
81
+
82
+ profile
83
+ .command("avatar <imagePath>")
84
+ .description("Change your profile avatar")
85
+ .action(async (imagePath) => {
86
+ try {
87
+ const absPath = resolve(imagePath);
88
+ const result = await getApi().changeAccountAvatar(absPath);
89
+ output(result, program.opts().json, () => success("Avatar updated"));
90
+ } catch (e) {
91
+ error(`Avatar update failed: ${e.message}`);
92
+ }
93
+ });
94
+
95
+ profile
96
+ .command("bio [text]")
97
+ .description("View or update your profile bio/status")
98
+ .action(async (text) => {
99
+ try {
100
+ if (text === undefined) {
101
+ const result = await getApi().fetchAccountInfo();
102
+ const bio = result?.profile?.status || "(empty)";
103
+ output({ bio }, program.opts().json, () => info(`Bio: ${bio}`));
104
+ } else {
105
+ const result = await getApi().updateProfileBio(text);
106
+ output(result, program.opts().json, () => success(`Bio updated to: "${text}"`));
107
+ }
108
+ } catch (e) {
109
+ error(`Bio update failed: ${e.message}`);
110
+ }
111
+ });
112
+
113
+ profile
114
+ .command("update")
115
+ .description("Update profile name, birthday, or gender")
116
+ .option("-n, --name <name>", "Display name")
117
+ .option("-d, --dob <YYYY-MM-DD>", "Date of birth")
118
+ .option("-g, --gender <0|1>", "Gender: 0=Male, 1=Female")
119
+ .action(async (opts) => {
120
+ try {
121
+ if (!opts.name && !opts.dob && !opts.gender) {
122
+ error("Provide at least one: --name, --dob, or --gender");
123
+ return;
124
+ }
125
+ // Fetch current profile to fill missing fields (API requires all 3)
126
+ const current = await getApi().fetchAccountInfo();
127
+ const p = current?.profile || {};
128
+ const payload = {
129
+ profile: {
130
+ name: opts.name || p.displayName || p.zaloName,
131
+ dob: opts.dob || p.sdob || "2000-01-01",
132
+ gender: opts.gender !== undefined ? Number(opts.gender) : p.gender ?? 0,
133
+ },
134
+ };
135
+ const result = await getApi().updateProfile(payload);
136
+ output(result, program.opts().json, () => success("Profile updated"));
137
+ } catch (e) {
138
+ error(`Profile update failed: ${e.message}`);
139
+ }
140
+ });
141
+
142
+ profile
143
+ .command("settings")
144
+ .description("View current privacy settings")
145
+ .action(async () => {
146
+ try {
147
+ const result = await getApi().getSettings();
148
+ output(result, program.opts().json, () => {
149
+ info("Privacy settings:");
150
+ console.log();
151
+ for (const [slug, meta] of Object.entries(SETTING_MAP)) {
152
+ const raw = result[meta.key];
153
+ // Normalize booleans to 0/1 (API returns bool for some settings)
154
+ const val = raw === true ? 1 : raw === false ? 0 : raw;
155
+ const label = meta.values[val] || String(val);
156
+ console.log(` ${meta.label.padEnd(30)} ${label} (${slug}=${val})`);
157
+ }
158
+ console.log();
159
+ info("Update: zalo-agent profile set <setting> <value>");
160
+ info("Example: zalo-agent profile set online-status 0");
161
+ });
162
+ } catch (e) {
163
+ error(e.message);
164
+ }
165
+ });
166
+
167
+ profile
168
+ .command("set <setting> <value>")
169
+ .description("Update a privacy setting (use 'profile settings' to see options)")
170
+ .action(async (setting, value) => {
171
+ try {
172
+ const meta = SETTING_MAP[setting];
173
+ if (!meta) {
174
+ error(`Unknown setting: "${setting}". Valid: ${Object.keys(SETTING_MAP).join(", ")}`);
175
+ return;
176
+ }
177
+ const numVal = Number(value);
178
+ if (!(numVal in meta.values)) {
179
+ error(
180
+ `Invalid value for ${setting}. Valid: ${Object.entries(meta.values).map(([k, v]) => `${k}=${v}`).join(", ")}`,
181
+ );
182
+ return;
183
+ }
184
+ const result = await getApi().updateSettings(meta.key, numVal);
185
+ output(result, program.opts().json, () =>
186
+ success(`${meta.label}: ${meta.values[numVal]} (${numVal})`),
187
+ );
188
+ } catch (e) {
189
+ error(`Setting update failed: ${e.message}`);
190
+ }
191
+ });
192
+ }
package/src/index.js CHANGED
@@ -18,6 +18,7 @@ import { registerFriendCommands } from "./commands/friend.js";
18
18
  import { registerGroupCommands } from "./commands/group.js";
19
19
  import { registerConvCommands } from "./commands/conv.js";
20
20
  import { registerAccountCommands } from "./commands/account.js";
21
+ import { registerProfileCommands } from "./commands/profile.js";
21
22
  import { registerListenCommand } from "./commands/listen.js";
22
23
  import { autoLogin } from "./core/zalo-client.js";
23
24
  import { checkForUpdates, selfUpdate } from "./utils/update-check.js";
@@ -69,6 +70,7 @@ registerFriendCommands(program);
69
70
  registerGroupCommands(program);
70
71
  registerConvCommands(program);
71
72
  registerAccountCommands(program);
73
+ registerProfileCommands(program);
72
74
  registerListenCommand(program);
73
75
 
74
76
  program.parse();