From 45fd4af4820081243ea0ca8657c7e1b6a3b15d9a Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Fri, 12 Sep 2025 10:46:26 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20Telegram=20?= =?UTF-8?q?=E6=9C=BA=E5=99=A8=E4=BA=BA=E6=8E=A8=E9=80=81=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 TELEGRAM_BOT_TOKEN 和 TELEGRAM_CHAT_ID 环境变量配置 - 在 ai_handler.py 中集成 Telegram Bot API 调用 - 支持 HTML 格式化消息,包含商品信息和购买链接 - 更新 .env.example 添加配置说明和获取指导 - 完善错误处理和状态反馈机制 resolves #239 Co-authored-by: rainsfly --- .env.example | 6 +++++ src/ai_handler.py | 56 +++++++++++++++++++++++++++++++++++++++++++++-- src/config.py | 2 ++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 41208e7..bdc6263 100644 --- a/.env.example +++ b/.env.example @@ -25,6 +25,12 @@ BARK_URL="" # 你的 Bark 推送地址, 例如: https://api.day.app/your_key # 企业微信机器人通知配置 如果无则不用配置 WX_BOT_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx" +# Telegram 机器人通知配置 如果无则不用配置 +# 获取 Bot Token: 与 @BotFather 对话创建新的机器人 +# 获取 Chat ID: 与 @userinfobot 对话获取你的用户ID,或者将机器人添加到群组并获取群组ID +TELEGRAM_BOT_TOKEN="your_telegram_bot_token" +TELEGRAM_CHAT_ID="your_telegram_chat_id" + # (可选) 通用 Webhook 通知配置 WEBHOOK_URL="" # 你的 Webhook URL, 例如: https://foo.bar.com/quz?a=b WEBHOOK_METHOD="POST" # 请求方法: "GET" 或 "POST" diff --git a/src/ai_handler.py b/src/ai_handler.py index 8481f89..8ef9224 100644 --- a/src/ai_handler.py +++ b/src/ai_handler.py @@ -28,6 +28,8 @@ from src.config import ( BARK_URL, PCURL_TO_MOBILE, WX_BOT_URL, + TELEGRAM_BOT_TOKEN, + TELEGRAM_CHAT_ID, WEBHOOK_URL, WEBHOOK_METHOD, WEBHOOK_HEADERS, @@ -199,8 +201,8 @@ def validate_ai_response_format(parsed_response): @retry_on_failure(retries=3, delay=5) async def send_ntfy_notification(product_data, reason): """当发现推荐商品时,异步发送一个高优先级的 ntfy.sh 通知。""" - if not NTFY_TOPIC_URL and not WX_BOT_URL and not (GOTIFY_URL and GOTIFY_TOKEN) and not BARK_URL and not WEBHOOK_URL: - safe_print("警告:未在 .env 文件中配置任何通知服务 (NTFY_TOPIC_URL, WX_BOT_URL, GOTIFY_URL/TOKEN, BARK_URL, WEBHOOK_URL),跳过通知。") + if not NTFY_TOPIC_URL and not WX_BOT_URL and not (GOTIFY_URL and GOTIFY_TOKEN) and not BARK_URL and not (TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID) and not WEBHOOK_URL: + safe_print("警告:未在 .env 文件中配置任何通知服务 (NTFY_TOPIC_URL, WX_BOT_URL, GOTIFY_URL/TOKEN, BARK_URL, TELEGRAM_BOT_TOKEN/CHAT_ID, WEBHOOK_URL),跳过通知。") return title = product_data.get('商品标题', 'N/A') @@ -362,6 +364,56 @@ async def send_ntfy_notification(product_data, reason): except Exception as e: safe_print(f" -> 发送企业微信通知时发生未知错误: {e}") + # --- 发送 Telegram 机器人通知 --- + if TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID: + try: + safe_print(f" -> 正在发送 Telegram 通知...") + + # 构建 Telegram API URL + telegram_api_url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" + + # 格式化消息内容 + telegram_message = f"🚨 新推荐!\n\n" + telegram_message += f"{title[:50]}...\n\n" + telegram_message += f"💰 价格: {price}\n" + telegram_message += f"📝 原因: {reason}\n" + + # 添加链接 + if PCURL_TO_MOBILE: + mobile_link = convert_goofish_link(link) + telegram_message += f"📱 手机端链接\n" + telegram_message += f"💻 电脑端链接" + + # 构建请求负载 + telegram_payload = { + "chat_id": TELEGRAM_CHAT_ID, + "text": telegram_message, + "parse_mode": "HTML", + "disable_web_page_preview": False + } + + headers = {"Content-Type": "application/json"} + loop = asyncio.get_running_loop() + response = await loop.run_in_executor( + None, + lambda: requests.post( + telegram_api_url, + json=telegram_payload, + headers=headers, + timeout=10 + ) + ) + response.raise_for_status() + result = response.json() + if result.get("ok"): + safe_print(" -> Telegram 通知发送成功。") + else: + safe_print(f" -> Telegram 通知发送失败: {result.get('description', '未知错误')}") + except requests.exceptions.RequestException as e: + safe_print(f" -> 发送 Telegram 通知失败: {e}") + except Exception as e: + safe_print(f" -> 发送 Telegram 通知时发生未知错误: {e}") + # --- 发送通用 Webhook 通知 --- if WEBHOOK_URL: try: diff --git a/src/config.py b/src/config.py index 6a6fd4f..faf17ae 100644 --- a/src/config.py +++ b/src/config.py @@ -30,6 +30,8 @@ GOTIFY_URL = os.getenv("GOTIFY_URL") GOTIFY_TOKEN = os.getenv("GOTIFY_TOKEN") BARK_URL = os.getenv("BARK_URL") WX_BOT_URL = os.getenv("WX_BOT_URL") +TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") +TELEGRAM_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID") WEBHOOK_URL = os.getenv("WEBHOOK_URL") WEBHOOK_METHOD = os.getenv("WEBHOOK_METHOD", "POST").upper() WEBHOOK_HEADERS = os.getenv("WEBHOOK_HEADERS")