8.5 KiB
WeCom Customer Service EBA Adapter
Status
WeCom Customer Service now has an EBA adapter directory:
src/langbot/pkg/platform/adapters/wecomcs/
├── adapter.py
├── api_impl.py
├── event_converter.py
├── manifest.yaml
├── message_converter.py
├── platform_api.py
└── types.py
The adapter is registered as wecomcs-eba. It is separate from regular WeCom application messages (wecom-eba) and WeCom AI Bot (wecombot-eba).
Configuration
| Field | Required | Default | Description |
|---|---|---|---|
webhook_url |
No | "" |
Unified webhook URL copied into the WeCom Customer Service callback settings. |
corpid |
Yes | "" |
WeCom corporate ID. |
secret |
Yes | "" |
Customer Service secret used for access tokens. |
token |
Yes | "" |
Customer Service callback token. |
EncodingAESKey |
Yes | "" |
Customer Service callback encryption key. |
api_base_url |
No | https://qyapi.weixin.qq.com/cgi-bin |
WeCom API base URL, overrideable for proxy/private-network deployments. |
Events
| Event | Status | Notes |
|---|---|---|
message.received |
Plugin E2E UI covered for text | Text, image, file, and voice payloads convert to common EBA message components in unit tests. Real WeChat customer-side UI text reached EBAEventProbe on May 27, 2026. |
platform.specific |
Unit covered | Non-message or unknown Customer Service payloads become structured PlatformSpecificEvent records. |
Common APIs
| API | Status | Notes |
|---|---|---|
send_message |
Plugin E2E outbound covered | Private/person target only. target_id must be `external_userid |
reply_message |
Plugin E2E partial | Replies through Customer Service kf/send_msg using the original source_platform_object. The pipeline reply path reached the send API, but the dev account later hit WeCom 95001 send msg count limit. |
get_message |
Plugin E2E covered from cache | Returns cached inbound MessageReceivedEvent by message ID. |
get_user_info |
Plugin E2E covered | Uses cached event users first, then Customer Service customer/batchget. |
get_friend_list |
Plugin E2E covered, partial | Returns customer users seen by this adapter instance. |
call_platform_api |
Unit covered | See platform-specific APIs below. |
edit_message / delete_message |
Not supported | WeCom Customer Service does not expose a general edit/delete endpoint for bot-sent messages in this adapter. |
| Group/member/moderation APIs | Not supported | Customer Service conversations handled here are private customer sessions, not group chats. |
upload_file / get_file_url |
Not supported | Media upload is used internally for outbound image; no portable file URL common API is exposed. |
Platform-Specific APIs
| Action | Status | Notes |
|---|---|---|
check_access_token |
Unit covered | Checks whether the current access token is present. |
refresh_access_token |
Unit covered | Refreshes the Customer Service access token. |
get_customer_info |
Unit covered | Calls Customer Service customer lookup by external_userid. |
Message Components
Receive:
| Component | Status | Notes |
|---|---|---|
Source |
Unit covered | Uses Customer Service msgid and send_time. |
Plain |
Unit covered | Text payload content is preserved. |
Image |
Unit covered | Uses the base64 data URL produced by the existing SDK image download path. |
Voice |
Unit covered | Maps exposed voice media ID to common Voice.voice_id; live UI evidence pending. |
File |
Unit covered | Maps exposed file media ID/name/size to common File; live UI evidence pending. |
Quote, At, AtAll, Face, Forward |
Not supported inbound | The current Customer Service SDK event model does not expose these as structured inbound fields. |
Unknown |
Unit covered | Unsupported message types become Unknown in message conversion or platform.specific at event level. |
Send:
| Component | Status | Notes |
|---|---|---|
Plain |
Plugin E2E outbound covered | Sends through kf/send_msg text. |
Image |
Plugin E2E outbound covered | Uploads media as WeCom image media and sends through kf/send_msg image. |
Quote, At, AtAll, Forward |
Unit covered fallback, live partially blocked | Flattened to text where possible. In the May 27 sweep, later text sends hit WeCom 95001 send msg count limit after the successful text/image sends. |
Voice, File, Face |
Not supported | The adapter raises NotSupportedError; no tested Customer Service send path is implemented. |
Unit Verification
Covered by:
PYTHONPATH=/Users/wangqiang/code/python/langbot-plugin-sdk/src uv run pytest tests/unit_tests/platform/test_wecomcs_eba_adapter.py
Result on May 27, 2026: 10 passed.
The local PYTHONPATH is required in this workspace because the installed SDK package in the LangBot venv does not contain the newer langbot_plugin.api.entities.builtin.platform.errors module; the existing EBA adapter tests need the same SDK override.
Live Probe
Auxiliary direct adapter probe:
PYTHONPATH=/path/to/langbot-plugin-sdk/src uv run python -m py_compile tests/e2e/live_wecomcs_eba_probe.py
WECOMCS_CORPID=... \
WECOMCS_SECRET=... \
WECOMCS_TOKEN=... \
WECOMCS_ENCODING_AES_KEY=... \
PYTHONPATH=/path/to/langbot-plugin-sdk/src \
uv run python tests/e2e/live_wecomcs_eba_probe.py \
--path /wecomcs/callback \
--log data/temp/wecomcs_eba_live_probe.jsonl
This probe is diagnostic only. Final EBA acceptance still requires the standalone SDK runtime plus EBAEventProbe plugin path.
Standalone Runtime Plugin E2E Record
Completed partial plugin E2E on May 27, 2026 against dev.rockchin.top and the WeChat customer-side UI entry 微信 -> 客服消息 -> 浪波智能客服.
Evidence:
- Server JSONL:
/home/wgc/LangBotxg/LangBotEbaTest/data/temp/wecomcs_eba_plugin_probe.jsonl - Trigger text:
EBA wecomcs dedupe probe 2026-05-27 bot_uuid:cc810d2c-91f3-4f92-8f27-e1bf9f7b6cb4adapter_name:wecomcs-eba- Observed common event:
MessageReceived,event.type=message.received - Observed message chain:
Source + Plain - Observed chat:
chat_type=private,chat_id=external_userid|open_kfid - Observed sender: customer
Userwith nickname/avatar from Customer Service lookup - Plugin API probe:
send_message,get_message,get_user_info,get_friend_list, plugin/workspace storage, and manifest/list APIs succeeded - Component sweep: outbound
PlainandImagesucceeded;FaceandFilereturned explicitNotSupportedError; later quote/forward fallback sends were blocked by WeCom95001 send msg count limit
Command shape used:
cd langbot-plugin-sdk
uv run python -m langbot_plugin.cli.__init__ rt --debug-only --ws-control-port 5400 --ws-debug-port 5401 --skip-deps-check
cd LangBot
PYTHONPATH=/absolute/path/to/langbot-plugin-sdk/src uv run main.py --standalone-runtime
cd data/plugins/LangBot__EBAEventProbe
DEBUG_RUNTIME_WS_URL=ws://127.0.0.1:5401/plugin/ws \
EBA_PROBE_LOG=/absolute/path/to/LangBot/data/temp/wecomcs_eba_plugin_probe.jsonl \
EBA_PROBE_API=1 \
EBA_PROBE_COMPONENT_SWEEP=1 \
EBA_PROBE_PLATFORM_API=1 \
uv --project /absolute/path/to/langbot-plugin-sdk run python -m langbot_plugin.cli.__init__ run
Required real UI trigger: send a Customer Service message from the WeCom/WeChat customer-side UI to the configured dev.rockchin.top Customer Service account.
Current Acceptance
Current status is partial EBA acceptance.
Blocked or pending items:
- Inbound UI media (
Image,Voice,File) was not sent from the real WeChat customer UI during this run, so receive-side media remains unit-covered only. - Pipeline auto-reply reached
kf/send_msg, but the test account hit WeCom95001 send msg count limitafter successful plugin outbound text/image sends. This is recorded as an account/platform rate-limit block, not a conversion or API-shape failure. - The current
EBAEventProberun did not call the adapter-specificcall_platform_apiactions (check_access_token,refresh_access_token,get_customer_info); the platform API map remains unit-covered. - Inbound voice/file depends on whether the real Customer Service callback plus
sync_msgendpoint returns those fields in the shape the local SDK models. - Group, member, edit, delete, moderation, and standalone file URL APIs are intentionally not declared because this Customer Service protocol path does not provide tested common equivalents.