87 lines
2.4 KiB
Python
87 lines
2.4 KiB
Python
"""
|
||
Wechat-Bot 主入口
|
||
启动企业微信 WebSocket 长连接,接收消息后转发给远程 Agent。
|
||
"""
|
||
import asyncio
|
||
import logging
|
||
import sys
|
||
|
||
from config import Config
|
||
from bot.wecom_bot import create_bot_client
|
||
from bot.agent_client import close_http_client
|
||
|
||
# 配置日志
|
||
logging.basicConfig(
|
||
level=getattr(logging, Config.LOG_LEVEL, logging.INFO),
|
||
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
||
datefmt="%Y-%m-%d %H:%M:%S",
|
||
)
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
async def run_bot():
|
||
"""启动企业微信机器人 WebSocket 客户端"""
|
||
# 创建机器人客户端并注册事件处理器
|
||
ws_client = create_bot_client()
|
||
logger.info("正在连接企业微信...")
|
||
|
||
# 用 Event 等待认证完成
|
||
authenticated = asyncio.Event()
|
||
|
||
@ws_client.on("authenticated")
|
||
def _on_authenticated():
|
||
logger.info("企业微信认证成功,机器人已上线")
|
||
authenticated.set()
|
||
|
||
@ws_client.on("error")
|
||
def _on_error(err):
|
||
logger.error("SDK 错误: %s", err)
|
||
|
||
try:
|
||
await ws_client.connect()
|
||
# 等待认证结果(最多 30 秒)
|
||
try:
|
||
await asyncio.wait_for(authenticated.wait(), timeout=30)
|
||
except asyncio.TimeoutError:
|
||
logger.error("认证超时(30秒),请检查 BOT_ID 和 BOT_SECRET 是否正确")
|
||
return
|
||
|
||
# 认证成功,保持事件循环运行以持续接收消息
|
||
logger.info("正在监听消息...")
|
||
await asyncio.Future() # 永远挂起,直到事件循环被取消
|
||
|
||
except asyncio.CancelledError:
|
||
logger.info("任务被取消")
|
||
except Exception as e:
|
||
logger.error("企业微信连接异常: %s", e)
|
||
finally:
|
||
await close_http_client()
|
||
logger.info("机器人已停止")
|
||
|
||
|
||
def main():
|
||
"""主函数"""
|
||
# 校验配置
|
||
missing = Config.validate()
|
||
if missing:
|
||
logger.error("缺少必要配置项: %s", ", ".join(missing))
|
||
logger.error("请复制 .env.example 为 .env 并填写配置")
|
||
sys.exit(1)
|
||
|
||
logger.info("=" * 50)
|
||
logger.info(" Wechat-Bot 启动中")
|
||
logger.info(" Agent 地址: %s", Config.AGENT_BASE_URL)
|
||
logger.info(" 日志级别: %s", Config.LOG_LEVEL)
|
||
logger.info("=" * 50)
|
||
|
||
try:
|
||
asyncio.run(run_bot())
|
||
except KeyboardInterrupt:
|
||
logger.info("收到中断信号,正在停止...")
|
||
|
||
logger.info("Wechat-Bot 已退出")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|