新增小红书、XMPP、元宝、Zalo 四个渠道扩展。 小红书渠道扩展主要模块:config, gateway, webhook, outbound, streaming, pairing, security, dedupe, media, status, window XMPP 渠道扩展主要模块:plugin, config, gateway, outbound, streaming, pairing, security, dedupe, accounts, commands, muc, rate_limiter, stanza_utils, status, monitor 元宝渠道扩展主要模块:plugin, client, config_schema, gateway, outbound(chunk/queue/transport), inbound(dispatcher), streaming, pairing, security, accounts, actions, commands, codec(biz/conn), session, shared, utils Zalo 渠道扩展主要模块:api, config, gateway, webhook, outbound, pairing, security, session, polling, monitor, status
58 lines
2.0 KiB
Python
58 lines
2.0 KiB
Python
import asyncio
|
|
import logging
|
|
|
|
from yuxi.channel.extensions.zalo.api import ZaloBotApi
|
|
from yuxi.channel.extensions.zalo.errors import ZaloApiError
|
|
from yuxi.channel.extensions.zalo.types import ZaloAccount
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
SLEEP_BETWEEN_POLLS_S = 0.25
|
|
|
|
|
|
async def start_polling_loop(account: ZaloAccount, abort_event: asyncio.Event, gateway):
|
|
api = ZaloBotApi(account.bot_token, proxy=account.proxy)
|
|
try:
|
|
await _clean_webhook_before_polling(api)
|
|
except ZaloApiError:
|
|
logger.debug("Zalo webhook cleanup failed or not available, continuing")
|
|
|
|
logger.info("Zalo polling loop started for account %s", account.account_id)
|
|
|
|
while not abort_event.is_set():
|
|
try:
|
|
resp = await api.get_updates(timeout=30)
|
|
result = resp.get("result", {})
|
|
|
|
if isinstance(result, dict) and result:
|
|
await gateway.process_update(result, account)
|
|
|
|
except ZaloApiError as e:
|
|
logger.warning("Zalo polling API error: %s", e)
|
|
await asyncio.sleep(5.0)
|
|
except Exception as e:
|
|
if isinstance(e, ZaloApiError):
|
|
pass
|
|
else:
|
|
logger.debug("Zalo polling error (likely 408 timeout): %s", e)
|
|
finally:
|
|
await asyncio.sleep(SLEEP_BETWEEN_POLLS_S)
|
|
|
|
await api.close()
|
|
logger.info("Zalo polling loop stopped for account %s", account.account_id)
|
|
|
|
|
|
async def _clean_webhook_before_polling(api: ZaloBotApi):
|
|
try:
|
|
info = await api.get_webhook_info()
|
|
if info.get("result", {}).get("url"):
|
|
await api.delete_webhook()
|
|
logger.info("Zalo webhook cleaned before polling")
|
|
except ZaloApiError as e:
|
|
if e.error_code == 404:
|
|
logger.debug("Zalo webhook info endpoint not available (404), skipping cleanup")
|
|
else:
|
|
logger.warning("Zalo webhook cleanup warning: %s", e)
|
|
except Exception as e:
|
|
logger.warning("Zalo webhook cleanup error: %s", e)
|