mirror of
https://github.com/Usagi-org/ai-goofish-monitor.git
synced 2025-11-25 11:29:41 +08:00
Merge pull request #243 from dingyufei615/claude/issue-239-20250912-1044
feat: 添加 Telegram 机器人推送通知功能
This commit is contained in:
@@ -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"
|
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 通知配置
|
||||||
WEBHOOK_URL="" # 你的 Webhook URL, 例如: https://foo.bar.com/quz?a=b
|
WEBHOOK_URL="" # 你的 Webhook URL, 例如: https://foo.bar.com/quz?a=b
|
||||||
WEBHOOK_METHOD="POST" # 请求方法: "GET" 或 "POST"
|
WEBHOOK_METHOD="POST" # 请求方法: "GET" 或 "POST"
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ from src.config import (
|
|||||||
BARK_URL,
|
BARK_URL,
|
||||||
PCURL_TO_MOBILE,
|
PCURL_TO_MOBILE,
|
||||||
WX_BOT_URL,
|
WX_BOT_URL,
|
||||||
|
TELEGRAM_BOT_TOKEN,
|
||||||
|
TELEGRAM_CHAT_ID,
|
||||||
WEBHOOK_URL,
|
WEBHOOK_URL,
|
||||||
WEBHOOK_METHOD,
|
WEBHOOK_METHOD,
|
||||||
WEBHOOK_HEADERS,
|
WEBHOOK_HEADERS,
|
||||||
@@ -199,8 +201,8 @@ def validate_ai_response_format(parsed_response):
|
|||||||
@retry_on_failure(retries=3, delay=5)
|
@retry_on_failure(retries=3, delay=5)
|
||||||
async def send_ntfy_notification(product_data, reason):
|
async def send_ntfy_notification(product_data, reason):
|
||||||
"""当发现推荐商品时,异步发送一个高优先级的 ntfy.sh 通知。"""
|
"""当发现推荐商品时,异步发送一个高优先级的 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:
|
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, WEBHOOK_URL),跳过通知。")
|
safe_print("警告:未在 .env 文件中配置任何通知服务 (NTFY_TOPIC_URL, WX_BOT_URL, GOTIFY_URL/TOKEN, BARK_URL, TELEGRAM_BOT_TOKEN/CHAT_ID, WEBHOOK_URL),跳过通知。")
|
||||||
return
|
return
|
||||||
|
|
||||||
title = product_data.get('商品标题', 'N/A')
|
title = product_data.get('商品标题', 'N/A')
|
||||||
@@ -362,6 +364,56 @@ async def send_ntfy_notification(product_data, reason):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
safe_print(f" -> 发送企业微信通知时发生未知错误: {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"🚨 <b>新推荐!</b>\n\n"
|
||||||
|
telegram_message += f"<b>{title[:50]}...</b>\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"📱 <a href='{mobile_link}'>手机端链接</a>\n"
|
||||||
|
telegram_message += f"💻 <a href='{link}'>电脑端链接</a>"
|
||||||
|
|
||||||
|
# 构建请求负载
|
||||||
|
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 通知 ---
|
# --- 发送通用 Webhook 通知 ---
|
||||||
if WEBHOOK_URL:
|
if WEBHOOK_URL:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ GOTIFY_URL = os.getenv("GOTIFY_URL")
|
|||||||
GOTIFY_TOKEN = os.getenv("GOTIFY_TOKEN")
|
GOTIFY_TOKEN = os.getenv("GOTIFY_TOKEN")
|
||||||
BARK_URL = os.getenv("BARK_URL")
|
BARK_URL = os.getenv("BARK_URL")
|
||||||
WX_BOT_URL = os.getenv("WX_BOT_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_URL = os.getenv("WEBHOOK_URL")
|
||||||
WEBHOOK_METHOD = os.getenv("WEBHOOK_METHOD", "POST").upper()
|
WEBHOOK_METHOD = os.getenv("WEBHOOK_METHOD", "POST").upper()
|
||||||
WEBHOOK_HEADERS = os.getenv("WEBHOOK_HEADERS")
|
WEBHOOK_HEADERS = os.getenv("WEBHOOK_HEADERS")
|
||||||
|
|||||||
Reference in New Issue
Block a user