Chuyển tới nội dung chính

Weixin (WeChat)

Kết nối Hermes với WeChat (微信), nền tảng nhắn tin cá nhân của Tencent. Bộ điều hợp sử dụng iLink Bot API của Tencent cho tài khoản WeChat cá nhân — điều này khác với WeCom (Enterprise WeChat). Tin nhắn được gửi thông qua kiểm tra vòng dài, do đó không yêu cầu điểm cuối công khai hoặc webhook.

thông tin

Bộ chuyển đổi này dành cho tài khoản WeChat cá nhân (微信). Nếu bạn cần WeChat dành cho doanh nghiệp/công ty, thay vào đó hãy xem WeCom adapter.

Điều kiện tiên quyết

  • Tài khoản WeChat cá nhân
  • Gói Python: aiohttpcryptography
  • Gói qrcode là tùy chọn (để hiển thị QR đầu cuối trong khi thiết lập)

Cài đặt các phụ thuộc cần thiết:

pip install aiohttp cryptography
# Optional: for terminal QR code display
pip install qrcode

Thiết lập

1. Chạy Trình hướng dẫn cài đặt

Cách dễ nhất để kết nối tài khoản WeChat của bạn là thông qua thiết lập tương tác:

Hermes gateway setup

Chọn Weixin khi được nhắc. Trình hướng dẫn sẽ:

  1. Yêu cầu mã QR từ API iLink Bot
  2. Hiển thị mã QR trong thiết bị đầu cuối của bạn (hoặc cung cấp URL)
  3. Đợi bạn quét mã QR bằng ứng dụng di động WeChat
  4. Nhắc bạn xác nhận đăng nhập trên điện thoại
  5. Tự động lưu thông tin đăng nhập tài khoản vào ~/.Hermes/weixin/accounts/

Sau khi xác nhận, bạn sẽ thấy thông báo như:

微信连接成功,account_id=your-account-id

Trình hướng dẫn lưu trữ account_id, tokenbase_url nên bạn không cần phải định cấu hình chúng theo cách thủ công.

2. Cấu hình biến môi trường

Sau lần đăng nhập QR đầu tiên, hãy đặt ID tài khoản tối thiểu trong ~/.Hermes/.env:

WEIXIN_ACCOUNT_ID=your-account-id

# Optional: override the token (normally auto-saved from QR login)
# WEIXIN_TOKEN=your-bot-token

# Optional: restrict access
WEIXIN_DM_POLICY=open
WEIXIN_ALLOWED_USERS=user_id_1,user_id_2

# Optional: restore legacy multiline splitting behavior
# WEIXIN_SPLIT_MULTILINE_MESSAGES=true

# Optional: home channel for cron/notifications
WEIXIN_HOME_CHANNEL=chat_id
WEIXIN_HOME_CHANNEL_NAME=Home

3. Khởi động Gateway

Hermes gateway

Bộ điều hợp sẽ khôi phục thông tin đăng nhập đã lưu, kết nối với API iLink và bắt đầu kiểm tra lâu dài các tin nhắn.

Tính năng

  • Vận chuyển thăm dò ý kiến dài — không cần điểm cuối công khai, webhook hoặc WebSocket
  • Đăng nhập bằng mã QR — thiết lập quét để kết nối qua Hermes gateway setup
  • DM và nhắn tin nhóm — chính sách truy cập có thể định cấu hình
  • Hỗ trợ đa phương tiện — hình ảnh, video, tệp và tin nhắn thoại
  • CDN được mã hóa AES-128-ECB — mã hóa/giải mã tự động cho tất cả hoạt động truyền tải phương tiện
  • Tính bền vững của mã thông báo bối cảnh — tính liên tục của phản hồi được hỗ trợ bằng đĩa trong các lần khởi động lại
  • Định dạng đánh dấu — tiêu đề, bảng và khối mã được định dạng lại để WeChat có thể đọc được
  • Phân chia tin nhắn thông minh — tin nhắn vẫn ở dạng một bong bóng duy nhất khi ở dưới giới hạn; chỉ các tải trọng quá khổ mới được phân chia ở ranh giới logic
  • Chỉ báo đang gõ — hiển thị trạng thái "đang gõ..." trong ứng dụng khách WeChat trong khi nhân viên xử lý
  • Bảo vệ SSRF — URL phương tiện gửi đi được xác thực trước khi tải xuống
  • Loại bỏ tin nhắn — Cửa sổ trượt 5 phút ngăn chặn việc xử lý kép
  • Tự động thử lại với backoff — khôi phục từ các lỗi API tạm thời

Tùy chọn cấu hình

Đặt những thứ này trong config.yaml trong platforms.weixin.extra:

Chìa khóaMặc địnhMô tả
account_idID tài khoản iLink Bot (bắt buộc)
tokenMã thông báo iLink Bot (bắt buộc, được lưu tự động khi đăng nhập QR)
base_urlhttps://ilinkai.weixin.qq.comURL cơ sở API iLink
cdn_base_urlhttps://novac2c.cdn.weixin.qq.com/c2cURL cơ sở CDN để truyền phương tiện
dm_policyopenTruy cập DM: open, allowlist, disabled, pairing
group_policydisabledTruy 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)
split_multiline_messagesfalseKhi true, chia các câu trả lời nhiều dòng thành nhiều tin nhắn trò chuyện (hành vi cũ). Khi false, hãy giữ các câu trả lời nhiều dòng dưới dạng một tin nhắn trừ khi chúng vượt quá giới hạ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
openBất cứ ai cũng có thể DM bot (mặc định)
allowlistChỉ ID người dùng trong allow_from mới có thể DM
disabledTất cả DM đều bị bỏ qua
pairingChế độ ghép nối (để thiết lập ban đầu)
WEIXIN_DM_POLICY=allowlist
WEIXIN_ALLOWED_USERS=user_id_1,user_id_2

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 | | 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 (mặc định) |

WEIXIN_GROUP_POLICY=allowlist
WEIXIN_GROUP_ALLOWED_USERS=group_id_1,group_id_2
ghi chú

Chính sách nhóm mặc định là disabled cho Weixin (không giống như WeCom có mặc định là open). Điều này là có chủ ý vì tài khoản WeChat cá nhân có thể thuộc nhiều nhóm.

Hỗ trợ truyền thông

Inbound (đang nhận)

Bộ điều hợp nhận các tệp đính kèm phương tiện từ người dùng, tải chúng xuống từ WeChat CDN, giải mã chúng và lưu vào bộ nhớ đệm cục bộ để xử lý tác nhân:

LoạiCách xử lý
Hình ảnhĐã tải xuống, giải mã AES và lưu vào bộ nhớ đệm dưới dạng JPEG.
VideoĐã tải xuống, giải mã AES và lưu vào bộ nhớ đệm dưới dạng MP4.
TệpĐã tải xuống, giải mã AES và lưu vào bộ nhớ đệm. Tên tập tin gốc được giữ nguyên.
Giọng nóiNếu có sẵn bản chép lại văn bản, nó sẽ được trích xuất dưới dạng văn bản. Nếu không, âm thanh (định dạng SILK) sẽ được tải xuống và lưu vào bộ nhớ đệm.

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.

CDN được mã hóa AES-128-ECB

Các tệp phương tiện WeChat được truyền qua CDN được mã hóa. Bộ điều hợp xử lý việc này một cách minh bạch:

  • Inbound: Phương tiện đã mã hóa được tải xuống từ CDN bằng URL encrypted_query_param, sau đó được giải mã bằng AES-128-ECB bằng khóa mỗi tệp được cung cấp trong tải trọng tin nhắn.
  • Gửi đi: Các tệp được mã hóa cục bộ bằng khóa AES-128-ECB ngẫu nhiên, được tải lên CDN và tham chiếu được mã hóa sẽ được bao gồm trong thư gửi đi.
  • Khóa AES là 16 byte (128-bit). Khóa có thể đến dưới dạng base64 thô hoặc mã hóa hex — bộ điều hợp xử lý cả hai định dạng.
  • Điều này yêu cầu gói Python cryptography.

Không cần cấu hình - quá trình mã hóa và giải mã diễn ra tự động.

Gửi đi (gửi)

Phương phápNó gửi gì
sendTin nhắn văn bản có định dạng Markdown
send_image / send_image_fileTin nhắn hình ảnh gốc (thông qua tải lên CDN)
send_documentTệp đính kèm (thông qua tải lên CDN)
send_videoTin nhắn video (thông qua tải lên CDN)

Tất cả phương tiện gửi đi đều đi qua luồng tải lên CDN được mã hóa:

  1. Tạo khóa AES-128 ngẫu nhiên
  2. Mã hóa tệp bằng phần đệm AES-128-ECB + PKCS#7
  3. Yêu cầu URL tải lên từ API iLink (getuploadurl)
  4. Tải bản mã lên CDN
  5. Gửi tin nhắn có tham chiếu phương tiện được mã hóa

Sự tồn tại của mã thông báo bối cảnh

API iLink Bot yêu cầu context_token được phản hồi lại với mỗi tin nhắn gửi đi cho một thiết bị ngang hàng nhất định. Bộ điều hợp duy trì kho lưu trữ mã thông báo ngữ cảnh được hỗ trợ bằng đĩa:

  • Mã thông báo được lưu trên mỗi tài khoản+ngang hàng với ~/.Hermes/weixin/accounts/<account_id>.context-tokens.JSON
  • Khi khởi động, mã thông báo đã lưu trước đó sẽ được khôi phục
  • Mỗi tin nhắn gửi đến sẽ cập nhật mã thông báo được lưu trữ cho người gửi đó
  • Tin nhắn gửi đi tự động bao gồm mã thông báo ngữ cảnh mới nhất

Điều này đảm bảo tính liên tục của phản hồi ngay cả sau khi cổng khởi động lại.

Định dạng đánh dấu

Trò chuyện cá nhân của WeChat về cơ bản không hiển thị đầy đủ Markdown. Bộ chuyển đổi định dạng lại nội dung để dễ đọc hơn:

  • Tiêu đề (# Title) → được chuyển đổi thành 【Title】 (cấp 1) hoặc **Title** (cấp 2+)
  • Bảng → được định dạng lại dưới dạng danh sách khóa-giá trị được gắn nhãn (ví dụ: - Column: Value)
  • Hàng rào mã → được giữ nguyên (WeChat hiển thị đầy đủ các hàng rào này)
  • Quá nhiều dòng trống → thu gọn thành hai dòng mới

Phân đoạn tin nhắn

Tin nhắn được gửi dưới dạng một tin nhắn trò chuyện bất cứ khi nào chúng vừa với giới hạn của nền tảng. Chỉ những trọng tải quá khổ mới được phân chia để phân phối:

  • Độ dài tin nhắn tối đa: 4000 ký tự
  • Tin nhắn dưới giới hạn vẫn nguyên vẹn ngay cả khi chúng chứa nhiều đoạn văn hoặc ngắt dòng
  • Tin nhắn quá khổ được phân chia theo ranh giới logic (đoạn văn, dòng trống, hàng rào mã)
  • Hàng rào mã được giữ nguyên bất cứ khi nào có thể (không bao giờ tách ra giữa khối trừ khi hàng rào vượt quá giới hạn)
  • Các khối riêng lẻ quá khổ sẽ quay trở lại logic cắt ngắn của bộ điều hợp cơ sở
  • Độ trễ giữa các đoạn 0,3 giây sẽ ngăn chặn việc giảm giới hạn tốc độ của WeChat khi nhiều đoạn được gửi

Chỉ báo gõ

Bộ điều hợp hiển thị trạng thái nhập trong ứng dụng khách WeChat:1. Khi có tin nhắn đến, bộ điều hợp sẽ tìm nạp typing_ticket thông qua API getconfig 2. Phiếu đánh máy được lưu vào bộ nhớ đệm trong 10 phút cho mỗi người dùng 3. send_typing gửi Signal bắt đầu gõ; stop_typing gửi Signal dừng gõ 4. Cổng tự động kích hoạt các chỉ báo nhập trong khi tác nhân xử lý tin nhắn

Kết nối thăm dò dài

Bộ điều hợp sử dụng tính năng bỏ phiếu dài HTTP (không phải WebSocket) để nhận tin nhắn:

Cách thức hoạt động

  1. Kết nối: Xác thực thông tin xác thực và bắt đầu vòng thăm dò ý kiến
  2. Thăm dò ý kiến: Gọi getupdates với thời gian chờ là 35 giây; máy chủ giữ yêu cầu cho đến khi có tin nhắn đến hoặc hết thời gian chờ
  3. Điều phối: Tin nhắn gửi đến được gửi đồng thời qua asyncio.create_task
  4. Bộ đệm đồng bộ hóa: Một con trỏ đồng bộ hóa liên tục (get_updates_buf) được lưu vào đĩa để bộ điều hợp tiếp tục hoạt động từ vị trí chính xác sau khi khởi động lại

Thử lại hành vi

Đối với các lỗi API, bộ điều hợp sử dụng chiến lược thử lại đơn giản:

| Tình trạng | Hành vi | |----------||----------| | Lỗi thoáng qua (thứ 1–thứ 2) | Thử lại sau 2 giây | | Lỗi lặp lại (3+) | Lùi lại trong 30 giây rồi đặt lại bộ đếm | | Phiên đã hết hạn (errcode=-14) | Tạm dừng trong 10 phút (có thể cần đăng nhập lại) | | Hết giờ | Thăm dò lại ngay lập tức (hành vi thăm dò ý kiến ​​kéo dài thông thường) |

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 hạn 5 phút. Điều này ngăn chặn việc xử lý kép khi mạng gặp trục trặc hoặc các phản hồi thăm dò chồng chéo.

Khóa mã thông báo

Mỗi lần chỉ có một phiên bản cổng Weixin có thể sử dụng một mã thông báo nhất định. Bộ điều hợp nhận được khóa có phạm vi khi khởi động và mở khóa khi tắt máy. Nếu một cổng khác đang sử dụng cùng một mã thông báo thì quá trình khởi động sẽ không thành công kèm theo thông báo lỗi đầy thông tin.

Tất cả các biến môi trường

BiếnBắt buộcMặc địnhMô tả
WEIXIN_ACCOUNT_IDID tài khoản iLink Bot (từ đăng nhập QR)
WEIXIN_TOKENMã thông báo iLink Bot (được lưu tự động khi đăng nhập QR)
WEIXIN_BASE_URLhttps://ilinkai.weixin.qq.comURL cơ sở API iLink
WEIXIN_CDN_BASE_URLhttps://novac2c.cdn.weixin.qq.com/c2cURL cơ sở CDN để truyền phương tiện
WEIXIN_DM_POLICYopenChính sách truy cập DM: open, allowlist, disabled, pairing
WEIXIN_GROUP_POLICYdisabledChính sách truy cập nhóm: open, allowlist, disabled
WEIXIN_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 DM
WEIXIN_GROUP_ALLOWED_USERS(trống)ID nhóm được phân tách bằng dấu phẩy cho danh sách cho phép của nhóm
WEIXIN_HOME_CHANNELID trò chuyện cho đầu ra cron/thông báo
WEIXIN_HOME_CHANNEL_NAMEHomeTên hiển thị cho kênh chủ
WEIXIN_ALLOW_ALL_USERSCờ cấp cổng để cho phép tất cả người dùng (được sử dụng bởi trình hướng dẫn thiết lập)

Khắc phục sự cố| Vấn đề | Sửa chữa |

|----------|------| | Weixin startup failed: aiohttp and cryptography are required | Cài đặt cả hai: pip install aiohttp cryptography | | Weixin startup failed: WEIXIN_TOKEN is required | Chạy Hermes gateway setup để hoàn tất đăng nhập QR hoặc đặt WEIXIN_TOKEN theo cách thủ công | | Weixin startup failed: WEIXIN_ACCOUNT_ID is required | Đặt WEIXIN_ACCOUNT_ID trong .env của bạn hoặc chạy Hermes gateway setup | | Another local Hermes gateway is already using this Weixin token | Trước tiên hãy dừng phiên bản cổng khác - chỉ cho phép một người thăm dò cho mỗi mã thông báo | | Phiên đã hết hạn (errcode=-14) | Phiên đăng nhập của bạn đã hết hạn. Chạy lại Hermes gateway setup để quét mã QR mới | | Mã QR đã hết hạn trong quá trình thiết lập | QR tự động làm mới tối đa 3 lần. Nếu nó hết hạn, hãy kiểm tra kết nối mạng của bạn | | Bot không phản hồi DM | Kiểm tra WEIXIN_DM_POLICY - nếu được đặt thành allowlist, người gửi phải ở WEIXIN_ALLOWED_USERS | | Bot bỏ qua tin nhắn nhóm | Chính sách nhóm mặc định là disabled. Đặt WEIXIN_GROUP_POLICY=open hoặc allowlist | | Tải xuống/tải lên phương tiện không thành công | Đảm bảo cryptography được cài đặt. Kiểm tra quyền truy cập mạng vào novac2c.cdn.weixin.qq.com | | Blocked unsafe URL (SSRF protection) | URL phương tiện gửi đi trỏ đến địa chỉ riêng tư/nội bộ. Chỉ cho phép các URL công khai | | Tin nhắn thoại hiển thị dưới dạng văn bản | Nếu WeChat cung cấp bản phiên âm thì bộ chuyển đổi sẽ sử dụng văn bản đó. Đây là hành vi được mong đợi | | Tin nhắn xuất hiện trùng lặp | Bộ điều hợp sẽ loại bỏ trùng lặp theo ID tin nhắn. Nếu bạn thấy các bản sao, hãy kiểm tra xem có nhiều phiên bản cổng đang chạy hay không | | iLink POST ... HTTP 4xx/5xx | Lỗi API từ dịch vụ iLink. Kiểm tra tính hợp lệ của mã thông báo và kết nối mạng | | Mã QR đầu cuối không hiển thị | Cài đặt qrcode: pip install qrcode. Ngoài ra, hãy mở URL được in phía trên QR |