Files
abot/main.py
2025-04-22 15:13:57 +08:00

169 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import logging
import threading
import time
from argparse import ArgumentParser
import uvicorn
from fastapi import FastAPI
from gewechat_client import GewechatClient
import socket
# 启动FastAPI服务器
# 从callback_url中提取主机和端口
import urllib.parse
from configuration import Config
from constants import ChatType
from robot import Robot
from gewechat.api.callback import router as callback_router
# 配置日志
logger = logging.getLogger(__name__)
def is_port_in_use(port, host='0.0.0.0'):
"""检查端口是否被占用"""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
try:
s.bind((host, port))
return False
except socket.error:
return True
def start_fastapi_server(host="0.0.0.0", port=8999):
"""启动FastAPI服务器"""
# 检查端口是否被占用
if is_port_in_use(port, host):
logger.warning(f"端口 {port} 已被占用,尝试使用其他端口")
# 尝试其他端口
for test_port in range(9000, 9100):
if not is_port_in_use(test_port, host):
port = test_port
break
else:
logger.error("无法找到可用端口,服务器启动失败")
return False
try:
app = FastAPI()
app.include_router(callback_router)
# 添加健康检查路由
@app.get("/health")
async def health_check():
return {"status": "ok"}
logger.info(f"正在启动FastAPI服务器地址: http://{host}:{port}")
# 使用线程启动uvicorn服务器
server_thread = threading.Thread(
target=uvicorn.run,
args=(app,),
kwargs={"host": host, "port": port, "log_level": "info"},
daemon=True
)
server_thread.start()
logger.info(f"FastAPI 服务已在 http://{host}:{port} 启动")
logger.info(f"回调URL: http://{host}:{port}/gewechat/callback")
# 返回启动的端口,以便调用者知道实际使用的端口
return port
except Exception as e:
logger.error(f"启动FastAPI服务器失败: {e}", exc_info=True)
return False
def main(chat_type: int):
config = Config()
base_url = config.BASE_URL
token = config.GEWECHAT_TOKEN
app_id = config.APP_ID
callback_url = config.CALLBACK_URL
send_msg_wxid = "filehelper" # 要发送消息的好友昵称
parsed_url = urllib.parse.urlparse(callback_url)
host = parsed_url.hostname or "0.0.0.0"
port = parsed_url.port or 8999
start_fastapi_server(host, port)
# 创建 GewechatClient 实例
client = GewechatClient(base_url, token)
# 登录, 自动创建二维码,扫码后自动登录
app_id, error_msg = client.login(app_id=app_id)
if error_msg:
logger.error("登录失败")
return
#休眠等待server启动防止回调设置失败
time.sleep(10)
resp = client.set_callback(token, callback_url)
print(f"set_callback:{resp}")
# 如果启动时配置文件中的app_id为空那么将app_id写入配置文件
if not config.APP_ID:
# 更新配置文件中的APP_ID
config.update_config('gewechat', 'app_id', app_id)
logger.info(f"已将新的APP_ID: {app_id} 写入配置文件")
# 同时更新当前配置对象中的APP_ID
config.APP_ID = app_id
# 创建机器人实例
robot = Robot(config, app_id, client, chat_type)
robot.LOG.info(f"WeChatRobot gewechat 成功启动···")
# # 注册Robot实例到callback模块
from gewechat.api.callback import register_robot
register_robot(app_id, robot)
# 机器人启动发送测试消息
client.post_text(app_id, send_msg_wxid, "gewechat client 启动成功!")
#
# # 每天 8:30 发送新闻
# robot.onEveryTime("08:30", robot.news_baidu_report_auto)
#
# # epic
# robot.onEveryTime("10:30", robot.send_epic_free_games)
#
# # message report 1:数据自动从redis 转到sqllite
# robot.onEveryTime("02:30", robot.message_count_to_db)
# # 从db中提取并发送给相关群
# robot.onEveryTime("09:30", robot.generate_and_send_ranking)
#
# # sehuatang
# robot.onEveryTime("15:30", robot.generate_sehuatang_pdf)
#
# # 秀人网每天自动下载帖子
# robot.onEveryTime("01:30", robot.xiu_ren_download_task)
#
# # 秀人网每天自动发pdf
# robot.onEveryTime("17:30", robot.xiu_ren_pdf_send)
# 启动Dashboard服务器
dashboard_server = None
# try:
# # 创建Dashboard服务器实例共享robot对象
# from admin.dashboard.server import DashboardServer
# dashboard_server = DashboardServer(robot_instance=robot)
#
# # 在单独的线程中启动Dashboard服务器
# dashboard_thread = threading.Thread(target=dashboard_server.run, daemon=True)
# dashboard_thread.start()
# robot.LOG.info(f"Dashboard服务器已在 http://{dashboard_server.host}:{dashboard_server.port} 启动")
# except Exception as e:
# robot.LOG.error(f"Dashboard服务器启动失败: {e}")
# 让机器人一直跑
robot.keep_running_and_block_process()
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument('-c', type=int, default=0, help=f'选择模型参数序号: {ChatType.help_hint()}')
args = parser.parse_args().c
main(args)