feat(gateway): add WeCom (Enterprise WeChat) platform support (#3847)
Adds WeCom as a gateway platform adapter using the AI Bot WebSocket gateway for real-time bidirectional communication. No public endpoint or new pip dependencies needed (uses existing aiohttp + httpx). Features: - WebSocket persistent connection with auto-reconnect (exponential backoff) - DM and group messaging with configurable access policies - Media upload/download with AES decryption for encrypted attachments - Markdown rendering, quote context preservation - Proactive + passive reply message modes - Chunked media upload pipeline (512KB chunks) Cherry-picked from PR #1898 by EvilRan with: - Moved to current main (PR was 300 commits behind) - Skipped base.py regressions (reply_to additions are good but belong in a separate PR since they affect all platforms) - Fixed test assertions to match current base class send() signature (reply_to=None kwarg now explicit) - All 16 integration points added surgically to current main - No new pip dependencies (aiohttp + httpx already installed) Fixes #1898 Co-authored-by: EvilRan <EvilRan@users.noreply.github.com>
This commit is contained in:
@@ -372,7 +372,7 @@ Important safety rule: cron-run sessions should not recursively schedule more cr
|
||||
},
|
||||
"deliver": {
|
||||
"type": "string",
|
||||
"description": "Delivery target: origin, local, telegram, discord, slack, whatsapp, signal, matrix, mattermost, homeassistant, dingtalk, feishu, email, sms, or platform:chat_id or platform:chat_id:thread_id for Telegram topics. Examples: 'origin', 'local', 'telegram', 'telegram:-1001234567890:17585', 'discord:#engineering'"
|
||||
"description": "Delivery target: origin, local, telegram, discord, slack, whatsapp, signal, matrix, mattermost, homeassistant, dingtalk, feishu, wecom, email, sms, or platform:chat_id or platform:chat_id:thread_id for Telegram topics. Examples: 'origin', 'local', 'telegram', 'telegram:-1001234567890:17585', 'discord:#engineering'"
|
||||
},
|
||||
"model": {
|
||||
"type": "string",
|
||||
|
||||
@@ -130,6 +130,7 @@ def _handle_send(args):
|
||||
"homeassistant": Platform.HOMEASSISTANT,
|
||||
"dingtalk": Platform.DINGTALK,
|
||||
"feishu": Platform.FEISHU,
|
||||
"wecom": Platform.WECOM,
|
||||
"email": Platform.EMAIL,
|
||||
"sms": Platform.SMS,
|
||||
}
|
||||
@@ -368,6 +369,8 @@ async def _send_to_platform(platform, pconfig, chat_id, message, thread_id=None,
|
||||
result = await _send_dingtalk(pconfig.extra, chat_id, chunk)
|
||||
elif platform == Platform.FEISHU:
|
||||
result = await _send_feishu(pconfig, chat_id, chunk, thread_id=thread_id)
|
||||
elif platform == Platform.WECOM:
|
||||
result = await _send_wecom(pconfig.extra, chat_id, chunk)
|
||||
else:
|
||||
result = {"error": f"Direct sending not yet implemented for {platform.value}"}
|
||||
|
||||
@@ -794,6 +797,33 @@ async def _send_dingtalk(extra, chat_id, message):
|
||||
return {"error": f"DingTalk send failed: {e}"}
|
||||
|
||||
|
||||
async def _send_wecom(extra, chat_id, message):
|
||||
"""Send via WeCom using the adapter's WebSocket send pipeline."""
|
||||
try:
|
||||
from gateway.platforms.wecom import WeComAdapter, check_wecom_requirements
|
||||
if not check_wecom_requirements():
|
||||
return {"error": "WeCom requirements not met. Need aiohttp + WECOM_BOT_ID/SECRET."}
|
||||
except ImportError:
|
||||
return {"error": "WeCom adapter not available."}
|
||||
|
||||
try:
|
||||
from gateway.config import PlatformConfig
|
||||
pconfig = PlatformConfig(extra=extra)
|
||||
adapter = WeComAdapter(pconfig)
|
||||
connected = await adapter.connect()
|
||||
if not connected:
|
||||
return {"error": f"WeCom: failed to connect — {adapter.fatal_error_message or 'unknown error'}"}
|
||||
try:
|
||||
result = await adapter.send(chat_id, message)
|
||||
if not result.success:
|
||||
return {"error": f"WeCom send failed: {result.error}"}
|
||||
return {"success": True, "platform": "wecom", "chat_id": chat_id, "message_id": result.message_id}
|
||||
finally:
|
||||
await adapter.disconnect()
|
||||
except Exception as e:
|
||||
return {"error": f"WeCom send failed: {e}"}
|
||||
|
||||
|
||||
async def _send_feishu(pconfig, chat_id, message, media_files=None, thread_id=None):
|
||||
"""Send via Feishu/Lark using the adapter's send pipeline."""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user