WeCom (WeCom doanh nghiệp)
Kết nối Hermes với WeCom (企业微信), nền tảng nhắn tin doanh nghiệp của Tencent. Bộ điều hợp sử dụng cổng AI Bot WebSocket của WeCom để liên lạc hai chiều theo thời gian thực — không cần điểm cuối công khai hoặc webhook.
Điều kiện tiên quyết
- Tài khoản tổ chức WeCom
- Bot AI được tạo trong Bảng điều khiển dành cho quản trị viên WeCom
- ID Bot và Bí mật từ trang thông tin đăng nhập của bot
- Gói Python:
aiohttpvàhttpx
Thiết lập
1. Tạo Bot AI
- Đăng nhập vào Bảng điều khiển dành cho quản trị viên WeCom
- Điều hướng đến Ứng dụng → Tạo ứng dụng → Bot AI
- Cấu hình tên và mô tả bot
- Sao chép Bot ID và Secret từ trang thông tin đăng nhập
2. Cấu hình Hermes
Chạy thiết lập tương tác:
hermes gateway setup
Chọn WeCom và nhập Bot ID và Bí mật của bạn.
Hoặc đặt biến môi trường trong ~/.hermes/.env :
WECOM_BOT_ID=your-bot-id
WECOM_SECRET=your-secret
# Optional: restrict access
WECOM_ALLOWED_USERS=user_id_1,user_id_2
# Optional: home channel for cron/notifications
WECOM_HOME_CHANNEL=chat_id
3. Khởi động cổng
hermes gateway
Tính năng
- WebSocket Transport — kết nối liên tục, không cần điểm cuối công cộng
- DM và nhắn tin nhóm — chính sách truy cập có thể định cấu hình
- Danh sách cho phép người gửi theo nhóm — kiểm soát chi tiết về những người có thể tương tác trong mỗi nhóm
- Hỗ trợ phương tiện — tải lên và tải xuống hình ảnh, tệp, giọng nói, video
- Phương tiện được mã hóa AES — giải mã tự động cho các tệp đính kèm gửi đến
- Bối cảnh trích dẫn — duy trì luồng trả lời
- Kết xuất Markdown — phản hồi văn bản đa dạng thức
- Truyền phát chế độ trả lời — tương quan các câu trả lời với ngữ cảnh tin nhắn gửi đến
- Tự động kết nối lại — thời gian chờ theo cấp số nhân khi kết nối bị giảm
Tùy chọn cấu hình
Đặt những thứ này trong config.yaml trong platforms.wecom.extra :
| Chìa khóa | Mặc định | Mô tả |
|---|---|---|
bot_id | — | ID Bot AI của WeCom (bắt buộc) |
secret | — | Bí mật Bot AI của WeCom (bắt buộc) |
websocket_url | wss://openws.work.weixin.qq.com | URL cổng WebSocket |
dm_policy | open | Quyền truy cập DM: open , allowlist , disabled , pairing |
group_policy | open | Truy cập nhóm: open , allowlist , disabled |
allow_from | [] | ID người dùng được phép cho DM (khi dm_policy=allowlist) |
group_allow_from | [] | ID nhóm được phép (khi group_policy=allowlist) |
groups | {} | Cấu hình mỗi nhóm (xem bên dưới) |
Chính sách truy cập
Chính sách DM
Kiểm soát ai có thể gửi tin nhắn trực tiếp tới bot:
| Giá trị | Hành vi |
|---|---|
open | Bất cứ ai cũng có thể DM bot (mặc định) |
allowlist | Chỉ ID người dùng trong allow_from mới có thể DM |
disabled | Tất cả DM đều bị bỏ qua |
pairing | Chế độ ghép nối (để thiết lập ban đầu) |
WECOM_DM_POLICY=allowlist
Chính sách nhóm
Kiểm soát những nhóm bot phản hồi trong:
| Giá trị | Hành vi |
|---|---|
open | Bot phản hồi trong tất cả các nhóm (mặc định) |
allowlist | Bot chỉ phản hồi trong ID nhóm được liệt kê trong group_allow_from |
disabled | Tất cả tin nhắn nhóm đều bị bỏ qua |
WECOM_GROUP_POLICY=allowlist
Danh sách cho phép người gửi trên mỗi nhómĐể kiểm soát chi tiết hơn, bạn có thể hạn chế người dùng nào được phép tương tác với bot trong các nhóm cụ thể. Điều này được định cấu hình trong config.yaml :
platforms:
wecom:
enabled: true
extra:
bot_id: "your-bot-id"
secret: "your-secret"
group_policy: "allowlist"
group_allow_from:
- "group_id_1"
- "group_id_2"
groups:
group_id_1:
allow_from:
- "user_alice"
- "user_bob"
group_id_2:
allow_from:
- "user_charlie"
"*":
allow_from:
- "user_admin"
Cách thức hoạt động:
- Các điều khiển
group_policyvàgroup_allow_fromxác định xem một nhóm có được phép hay không. - Nếu một nhóm vượt qua bước kiểm tra cấp cao nhất, danh sách
groups.<group_id>.allow_from(nếu có) sẽ hạn chế hơn nữa những người gửi nào trong nhóm đó có thể tương tác với bot. - Mục nhập nhóm ký tự đại diện
"*"đóng vai trò mặc định cho các nhóm không được liệt kê rõ ràng. - Các mục nhập trong danh sách cho phép hỗ trợ ký tự đại diện
*để cho phép tất cả người dùng và các mục nhập không phân biệt chữ hoa chữ thường. - Các mục nhập có thể tùy ý sử dụng định dạng tiền tố
wecom:user:hoặcwecom:group:— tiền tố sẽ tự động bị loại bỏ.
Nếu không có allow_from nào được định cấu hình cho một nhóm thì tất cả người dùng trong nhóm đó đều được phép (giả sử chính nhóm đó đã vượt qua quá trình kiểm tra chính sách cấp cao nhất).
Hỗ trợ truyền thông
Trong nước (đang nhận)
Bộ điều hợp nhận tệp đính kèm phương tiện từ người dùng và lưu chúng vào bộ nhớ đệm cục bộ để xử lý tác nhân:
| Loại | Cách xử lý |
|---|---|
| Hình ảnh | Đã tải xuống và lưu vào bộ nhớ đệm cục bộ. Hỗ trợ cả hình ảnh dựa trên URL và mã hóa base64. |
| Tệp | Đã tải xuống và lưu vào bộ nhớ đệm. Tên tệp được giữ nguyên từ tin nhắn gốc. |
| Giọng nói | Phiên âm văn bản tin nhắn thoại được trích xuất nếu có. |
| Tin nhắn hỗn hợp | Tin nhắn loại hỗn hợp WeCom (văn bản + hình ảnh) được phân tích cú pháp và tất cả các thành phần được trích xuất. |
Tin nhắn được trích dẫn: Phương tiện từ các tin nhắn được trích dẫn (đã trả lời) cũng được trích xuất, do đó, tổng đài viên có ngữ cảnh về nội dung người dùng đang trả lời.
Giải mã phương tiện được mã hóa AES
WeCom mã hóa một số tệp đính kèm phương tiện gửi đến bằng AES-256-CBC. Bộ điều hợp tự động xử lý việc này:
- Khi một mục phương tiện gửi đến bao gồm trường
aeskey, bộ điều hợp sẽ tải xuống các byte được mã hóa và giải mã chúng bằng AES-256-CBC với phần đệm PKCS#7. - Khóa AES là giá trị được giải mã base64 của trường
aeskey(phải chính xác là 32 byte). - IV được lấy từ 16 byte đầu tiên của khóa.
- Điều này yêu cầu gói Python
cryptography(pip install cryptography).
Không cần cấu hình - quá trình giải mã diễn ra một cách minh bạch khi nhận được phương tiện mã hóa.
Gửi đi (gửi)
| Phương pháp | Nó gửi gì | Giới hạn kích thước |
|---|---|---|
send | Tin nhắn văn bản đánh dấu | 4000 ký tự |
send_image / send_image_file | Tin nhắn hình ảnh gốc | 10 MB |
send_document | Tệp đính kèm | 20 MB |
send_voice | Tin nhắn thoại (chỉ định dạng AMR dành cho giọng nói bản địa) | 2 MB |
send_video | Tin nhắn video | 10 MB |
Tải lên theo từng đoạn: Các tệp được tải lên theo từng đoạn 512 KB thông qua giao thức ba bước (bắt đầu → các đoạn → kết thúc). Bộ điều hợp tự động xử lý việc này.
Tự động hạ cấp: Khi phương tiện vượt quá giới hạn kích thước của loại gốc nhưng dưới giới hạn tệp tuyệt đối 20 MB, thay vào đó, phương tiện đó sẽ tự động được gửi dưới dạng tệp đính kèm chung:- Hình ảnh > 10 MB → gửi dưới dạng tệp
- Video > 10 MB → gửi dưới dạng tệp
- Giọng nói > 2 MB → gửi dưới dạng tệp
- Âm thanh không phải AMR → được gửi dưới dạng tệp (WeCom chỉ hỗ trợ AMR cho giọng nói gốc)
Các tệp vượt quá giới hạn 20 MB tuyệt đối sẽ bị từ chối kèm theo một thông báo thông tin được gửi tới cuộc trò chuyện.
Phản hồi theo luồng ở chế độ trả lời
Khi bot nhận được tin nhắn qua lệnh gọi lại WeCom, bộ điều hợp sẽ ghi nhớ ID yêu cầu gửi đến. Nếu phản hồi được gửi trong khi bối cảnh yêu cầu vẫn hoạt động thì bộ điều hợp sẽ sử dụng chế độ trả lời của WeCom ( aibot_respond_msg ) với tính năng phát trực tuyến để tương quan trực tiếp với phản hồi với tin nhắn gửi đến. Điều này mang lại trải nghiệm trò chuyện tự nhiên hơn trong ứng dụng khách WeCom.
Nếu ngữ cảnh yêu cầu gửi đến đã hết hạn hoặc không khả dụng, bộ điều hợp sẽ chuyển sang gửi tin nhắn chủ động qua aibot_send_msg .
Chế độ trả lời cũng hoạt động đối với phương tiện: phương tiện đã tải lên có thể được gửi dưới dạng trả lời cho thư gốc.
Kết nối và kết nối lại
Bộ điều hợp duy trì kết nối WebSocket liên tục với cổng WeCom tại wss://openws.work.weixin.qq.com .
Vòng đời kết nối
- Kết nối: Mở kết nối WebSocket và gửi khung xác thực
aibot_subscribevới bot_id và bí mật. - Nhịp tim: Gửi khung ping cấp ứng dụng cứ sau 30 giây để duy trì kết nối.
- Nghe: Liên tục đọc các khung gửi đến và gửi các lệnh gọi lại tin nhắn.
Hành vi kết nối lại
Khi mất kết nối, bộ điều hợp sử dụng thời gian chờ theo cấp số nhân để kết nối lại:
| Cố gắng | Trì hoãn |
|---|---|
| Thử lại lần đầu | 2 giây |
| Thử lại lần thứ 2 | 5 giây |
| Thử lại lần thứ 3 | 10 giây |
| Thử lại lần thứ 4 | 30 giây |
| Lần thứ 5+ thử lại | 60 giây |
Sau mỗi lần kết nối lại thành công, bộ đếm thời gian lùi sẽ đặt lại về 0. Tất cả các yêu cầu tương lai đang chờ xử lý đều không thành công khi ngắt kết nối nên người gọi không bị treo vô thời hạn.
Chống trùng lặp
Tin nhắn gửi đến sẽ được loại bỏ trùng lặp bằng cách sử dụng ID tin nhắn có thời lượng 5 phút và bộ đệm tối đa 1000 mục nhập. Điều này ngăn cản việc xử lý kép các tin nhắn trong quá trình kết nối lại hoặc trục trặc mạng.
Tất cả các biến môi trường
| Biến | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|
WECOM_BOT_ID | ✅ | — | ID Bot AI của WeCom |
WECOM_SECRET | ✅ | — | Bí mật về Bot AI của WeCom |
WECOM_ALLOWED_USERS | — | (trống) | ID người dùng được phân tách bằng dấu phẩy cho danh sách cho phép cấp cổng |
WECOM_HOME_CHANNEL | — | — | ID trò chuyện cho đầu ra cron/thông báo |
WECOM_WEBSOCKET_URL | — | wss://openws.work.weixin.qq.com | URL cổng WebSocket |
WECOM_DM_POLICY | — | open | Chính sách truy cập DM |
WECOM_GROUP_POLICY | — | open | Chính sách truy cập nhóm |
Khắc phục sự cố
| Vấn đề | Sửa chữa |
|---|---|
WECOM_BOT_ID and WECOM_SECRET are required | Đặt cả hai biến env hoặc định cấu hình trong trình hướng dẫn thiết lập |
WeCom startup failed: aiohttp not installed | Cài đặt aiohttp: pip install aiohttp |
WeCom startup failed: httpx not installed | Cài đặt httpx: pip install httpx |
invalid secret (errcode=40013) | Xác minh bí mật khớp với thông tin đăng nhập bot của bạn |
Timed out waiting for subscribe acknowledgement | Kiểm tra kết nối mạng tới openws.work.weixin.qq.com |
| Bot không phản hồi theo nhóm | Kiểm tra cài đặt group_policy và đảm bảo ID nhóm nằm trong group_allow_from |
| Bot bỏ qua một số người dùng nhất định trong nhóm | Kiểm tra danh sách allow_from theo nhóm trong phần cấu hình groups |
| Giải mã phương tiện không thành công | Cài đặt cryptography : pip install cryptography |
cryptography is required for WeCom media decryption | Phương tiện gửi đến được mã hóa AES. Cài đặt: pip install cryptography |
| Tin nhắn thoại được gửi dưới dạng tệp | WeCom chỉ hỗ trợ định dạng AMR cho giọng nói gốc. Các định dạng khác được tự động hạ cấp xuống tập tin. |
File too large lỗi | WeCom có giới hạn tuyệt đối là 20 MB cho tất cả các tệp tải lên. Nén hoặc chia nhỏ tập tin. |
| Hình ảnh được gửi dưới dạng tập tin | Hình ảnh > 10 MB vượt quá giới hạn hình ảnh gốc và được tự động hạ cấp xuống tệp đính kèm. |
Timeout sending message to WeCom | WebSocket có thể đã bị ngắt kết nối. Kiểm tra nhật ký để tìm thông báo kết nối lại. |
WeCom websocket closed during authentication | Sự cố mạng hoặc thông tin xác thực không chính xác. Xác minh bot_id và bí mật. |