# CHO CLAUDE ĐỌC: Bước 16. Lam Khuê trên Zalo

> Tài liệu này viết cho Claude Code của học viên. Người học chỉ cần dán câu lệnh bên dưới vào Claude, Claude đọc file này rồi làm.
> Thuộc hệ thống triển khai AI 20 bước của Trương Minh Kiên. Trang bước này: https://trienkhaizalo.truongminhkien.vn

## Việc cần làm

Cùng bộ não với Lam Khuê Lark, nhận lệnh qua một tài khoản Zalo riêng.

Câu lệnh học viên dán vào Claude:

```
Tải gói https://trienkhaizalo.truongminhkien.vn/lam-khue-zalo.zip, giải nén, đọc CHO-CLAUDE-DOC.md, mục Kênh Zalo trong README rồi cài Lam Khuê trên Zalo cho tôi
```

## Luật khi làm

1. Đọc hết file này, kể cả phần bẫy, trước khi chạy lệnh nào.
2. Việc cần mật khẩu, mã OTP, token hay thanh toán thì dừng lại để học viên tự làm, không nhập hộ.
3. Không xoá dữ liệu, bản ghi DNS hay file cũ của học viên. Chỉ thêm.
4. Khoá bí mật chỉ nằm trong `.env` (đã có trong `.gitignore`), không ghi vào mã, wiki hay kết quả.
5. Xong mỗi bước thì kiểm tra thật (chạy thử, đọc lại) rồi mới báo xong.
6. Gói này chạy trên máy của học viên, không phải máy người soạn. Mọi đường dẫn tính từ thư mục giải nén hoặc thư mục vault của học viên; hỏi học viên nếu cần. Skill nào nhắc tới file `output/...` hay trang `wiki/...` mà vault học viên chưa có thì đó chỉ là nguồn tham khảo của người soạn: bỏ qua, dùng nội dung ngay trong skill. Riêng `wiki/concepts/bo-mau-thuong-hieu.md`: nếu chưa có, chép từ `mau/bo-mau-thuong-hieu.md` trong gói rồi hỏi học viên để điền.

## Skill trong gói

- `zalo-agent`

Cách cài skill: chép từng thư mục trong `.claude/skills/` của gói vào `.claude/skills/` của vault Obsidian (bước 1). Tên thư mục phải trùng tên skill, file chính tên `SKILL.md`.

## Cách cài đặt từng bước (làm theo thứ tự)

### CHO CLAUDE ĐỌC — trợ lý Zalo: gửi tin theo lịch, chuỗi 5 tối sau khi khách nhận sách 0đ

> Bạn là Claude Code trên máy một người mới. Họ vừa dán: *"Đọc repo trên rồi cài trợ lý Zalo cho
> tôi, dựng chuỗi 5 tin tự gửi sau khi khách nhận sách 0đ"*. Kết quả cuối: `zalo-agent status` đăng
> nhập; một tin thử đã tới máy họ; 6 tin (tối 0 → 5) đã soạn, duyệt, và đặt lịch 20h30 bằng Task
> Scheduler. **Người bấm gửi lần đầu, máy gửi các lần sau** — không tự nhắn cho người lạ.

## 0. Nói thẳng giới hạn trước khi làm

`zalo-agent-cli` (mã nguồn mở, PhucMPham) điều khiển **tài khoản Zalo cá nhân** của người dùng qua
giao thức không chính thức. Ba điều phải nói với họ:
1. Zalo có thể **rớt đăng nhập bất chợt** (đã rớt sau 1 ngày, cầu nối thử lại 5.967 lần) → phải
   quét QR lại. Kiểm `zalo-agent status` trước mỗi đợt gửi.
2. Gửi hàng loạt cho người lạ = spam, dễ khoá tài khoản. Chuỗi 5 tối chỉ gửi cho người **đã tự để
   lại số / đã vào nhóm**, và trang thu phải nói rõ *"Năm tối sau, mỗi tối một tin. Nhắn 'dừng' là
   tôi thôi."*
3. Bot **nói được, nghe không chắc**: chế độ nghe (`listen`) bỏ tin dạng thẻ chia sẻ, `--filter user`
   không nghe nhóm. Gói này chỉ làm phần **gửi**; phần "nghe và trả lời" để sau, có lớp lọc chủ.

## 1. Cài và đăng nhập

```
npm install -g zalo-agent-cli
zalo-agent --version
```
Đăng nhập bằng QR — chạy **nền, cửa sổ có tiêu đề**: `zalo-agent login --qr-url` → in link
`http://localhost:18927/qr` → người dùng mở link trên máy tính, mở **Zalo trên điện thoại › QR
Scanner** (không phải camera) quét. QR hết hạn **60 giây**; hết thì chạy lại. Xong: `zalo-agent status`.

Chép `.claude/skills/zalo-agent/` vào `~/.claude/skills/` để phiên sau tra lệnh.

## 2. Lấy threadId

- Chính người dùng (để thử): `zalo-agent friend list --json` hoặc `zalo-agent me` → `userId`.
- Nhóm: `zalo-agent group list --json` → `groupId`; gửi nhóm dùng `-t 1`.
- Một khách: `zalo-agent friend find "<số điện thoại>"` — chỉ tìm được nếu họ cho phép tìm bằng số.

## 3. Gửi thử một tin cho chính họ

Viết `tin/thu.txt` ("Tin thử từ trợ lý Zalo — nhận được thì ok.") rồi:
```
node gui-tin.mjs tin/thu.txt <userId-của-họ> 0
```
Thành công khi dòng log có `OK msgId …`. Không có `msgId` = **chưa gửi**, dù không báo lỗi (bẫy 1).

## 4. Soạn chuỗi 6 tin cùng người dùng

Khuôn ở `tin/tin-0.mau.txt` (lúc vừa nhận sách) và `tin/tin-1.mau.txt` (mỗi tối). Hỏi: sách 0đ tên
gì, 5 việc nhỏ nào rút từ sách (mỗi tối một việc, làm trên giấy trong 5 phút), buổi mời ở tối 5 là
gì (zoom/nhóm/buổi gặp). Viết `tin/tin-0.txt` → `tin/tin-5.txt`, mỗi tin ≤ 120 chữ, kết bằng một
dòng `↳` mời trả lời.

**Ba luật của chuỗi:** không bán gì trong 5 tối (lời mời duy nhất ở tối 5) · không in ngày tháng
(chỉ "tối nay", "tối mai") · tin không được trả lời thì không nhắc lại; ai nhắn "dừng" thì dừng ngay.
Người dùng duyệt **từng tin** trước khi đặt lịch.

## 5. Đặt lịch

Với từng người (hoặc nhóm), 5 task một lần, 20h30 các ngày kế tiếp:
```
schtasks /Create /SC ONCE /SD 25/09/2026 /ST 20:30 /TN "Zalo-<ten>-tin1" /TR "cmd /c cd /d <thư-mục> && node gui-tin.mjs tin/tin-1.txt <threadId> 0 >> lich.log 2>&1" /F
```
(Định dạng `/SD` theo máy: kiểm `schtasks /?`.) Nhóm thì `-t 1` và gửi theo tuần. Mỗi task ghi vào
`gui-tin.log`; sáng hôm sau đọc log — dòng nào `LOI` thì thường là **rớt đăng nhập** → quét QR lại
rồi `schtasks /Run`.

## 6. Bẫy đã trả giá

| # | Bẫy | Cách xử |
|---|---|---|
| 1 | Lệnh chạy xong, không lỗi, nhưng tin không đi | Chỉ tin `msgId` trong kết quả `--json` (script đã kiểm) |
| 2 | Rớt đăng nhập lặng lẽ, tiến trình nghe thử lại hàng nghìn lần/ngày | `zalo-agent status` trước mỗi đợt; log có `LOI` → QR lại |
| 3 | Đường dẫn Windows `\` trong chuỗi JS bị heredoc/bash nuốt | Dùng `/` trong `.mjs` và trong tệp tin |
| 4 | `listen --filter user` không nghe nhóm; tin dạng thẻ link bị bỏ | Gói này không dựa vào nghe |
| 5 | Cầu nối "nghe rồi gọi Claude" chạy `bypassPermissions` → ai trong nhóm cũng ra lệnh được máy | Nếu sau này làm phần nghe: **giữ lớp lọc `uidFrom === ownerUid`**, không bao giờ mở cho nhóm |
| 6 | Quét QR bằng camera điện thoại | Phải dùng Zalo › QR Scanner |
| 7 | Gửi cho người chưa cho phép | Chỉ gửi cho người trong sổ lead đã đồng ý; trang thu ghi rõ nhịp tin |

## 7. Báo cáo cuối (khuôn)

```
✅ zalo-agent <phiên bản> · đăng nhập: <tên Zalo> · tin thử OK msgId …
📝 6 tin (tối 0→5) đã duyệt, lưu tin/tin-0..5.txt
⏰ Lịch: <n> task Zalo-* 20:30 · log: gui-tin.log
⚠️ Nhắc: kiểm status mỗi sáng; rớt QR thì quét lại
```


## Hướng dẫn chi tiết và các bẫy đã gặp

(Bản đầy đủ có hình và nút bấm: https://trienkhaizalo.truongminhkien.vn)

Yêu cầu trước khi bắt đầu

- Đã xong [Bước 2: Cài Claude AI](https://trienkhaiclaude.truongminhkien.vn/)
- **1 tài khoản Zalo riêng dành cho bot** — không dùng tài khoản Zalo cá nhân chính của bạn (xem lý do ở mục bẫy bên dưới)

## Cách hoạt động (nói với Claude AI để nó tự dựng)

1

### Cài công cụ điều khiển Zalo (đã có sẵn code thật)

Đây cũng là mã nguồn mở có sẵn — đưa thẳng link cho Claude AI:

https://github.com/PhucMPham/zalo-agent-cli.git

Nói: *"Đọc repo ở link trên rồi cài cho tôi."* Cài xong, đăng nhập bằng tài khoản Zalo RIÊNG (không phải tài khoản chính bạn nhắn tin cho khách hằng ngày).

2

### Lấy code cầu nối thật (cùng repo với Lam Khuê bên Lark)

Kênh Zalo dùng chung 1 repo với kênh Lark (Bước 15) — nếu đã làm bước đó thì đã có sẵn, chưa thì đưa link này cho Claude AI:

https://trienkhailamkhue.truongminhkien.vn/lam-khue-lark.zip

Nói: *"Đọc repo ở link trên, phần README mục 'Kênh điều khiển thứ 2: Zalo', rồi cài cho tôi."* File cầu nối là `scripts/zalo-bridge.mjs` (độc lập hoàn toàn với `lark-voice-bridge.mjs` — nhớ đệm riêng, session riêng): lắng nghe tin gửi tới tài khoản Zalo bot → tự chạy Claude Code trả lời → gửi lại qua Zalo. Cùng file `.env` với Lark, điền thêm `ZALO_OWNER_UID` (chạy `node zalo-whoami.mjs` để lấy) và `ZALO_AGENT_JS` (đường dẫn tới `index.js` thật của zalo-agent-cli — bắt buộc, gọi qua file `.cmd` bọc ngoài trên Windows bị lỗi).

3

### Đặt lịch chạy 24/7 + gắn watchdog — đã có sẵn trong repo

Đăng ký `node scripts/zalo-bridge.mjs` chạy khi khởi động máy, cộng thêm `scripts/zalo-watchdog.mjs` (đã viết sẵn, canh nhịp tim quá 35 phút không cập nhật thì tự kill + khởi động lại) — độc lập hoàn toàn với watchdog bên Lark, không dùng chung tiến trình.

## Điền 1 lần, dán khối lệnh cho Claude AI

Điền các ô lấy được ở Bước 1-2 phía trên, khối lệnh bên dưới tự ghép lại — copy rồi dán thẳng vào Claude AI.

ZALO_OWNER_UID bắt buộc Chạy `node zalo-whoami.mjs`, tự nhắn 1 tin từ tài khoản chính sang tài khoản "trợ lý" — nó tự in ra `uidFrom`.

ZALO_CONTROL_THREAD_ID tuỳ chọn Không bắt buộc điền tay — bridge tự khoá vào đúng đoạn chat khi nhận tin đầu tiên từ bạn.

ZALO_AGENT_JS bắt buộc trên Windows Trỏ đúng vào file `index.js` thật của `zalo-agent-cli` vừa cài — để trống dễ gặp lỗi `spawn EINVAL` khi gọi qua file `.cmd` bọc ngoài trên Windows.

Mọi giá trị bạn gõ chỉ nằm trong trình duyệt — trang không gửi đi đâu, không lưu lại. Đóng tab là mất.

Ẩn khi chia sẻ màn hình

Xoá hết

Khối lệnh — dán vào Claude AI

Sao chép khối lệnh

Chưa điền ô nào — khối lệnh đang ở dạng mẫu.

## ⚠ Bẫy đã gặp thật + cách gỡ

1\. Dùng tài khoản Zalo chính của mình làm bot thì bot không nhận được tin gì cả

Zalo (kênh không chính thức) không đẩy sự kiện tin nhắn về cho chính chủ tài khoản gửi cho mình — nếu bạn tự nhắn cho chính tài khoản của mình, script sẽ không bao giờ "thấy" tin nhắn đó.

**Cách gỡ:** luôn dùng 1 tài khoản Zalo THỨ HAI, độc lập, chỉ để làm bot — bạn nhắn từ tài khoản chính sang tài khoản bot, script mới nhận được sự kiện.

2\. Gửi tin nhắn báo lỗi "spawn EINVAL" trên Windows

Nếu script gọi thẳng file lệnh dạng `.cmd` (file khởi chạy kiểu Windows) mà không đi qua đúng cơ chế, Windows từ chối khởi chạy tiến trình với lỗi `spawn EINVAL`.

**Cách gỡ:** gọi thẳng chương trình chạy nền (ví dụ `node.exe`) kèm đường dẫn file mã nguồn thật, thay vì gọi qua file `.cmd` bọc ngoài.

3\. Cùng lỗi "canh gác im lặng" và "tưởng sống mà đã chết" như bên Lark

Áp dụng đúng 2 cách gỡ đã ghi ở trang [Bước 15](https://trienkhailamkhue.truongminhkien.vn/): đặt thời hạn lặp rất lớn cho lịch canh gác, và đo "còn sống" bằng nhịp tim thật (chỉ cập nhật khi thực sự có sự kiện xảy ra) chứ không phải bộ đếm giờ độc lập.

Bước tiếp theo

Đã có 2 kênh trợ lý AI (Lark + Zalo), sang bước kế tiếp: tự động cắt video dài thành nhiều đoạn ngắn để có đủ nội dung đăng.

[Sang bước 17: Cài Viral Short Studio →](https://trienkhaivideo.truongminhkien.vn/)

