Some checks failed
CD Pipeline / deploy (push) Failing after 5m18s
🔴 Critical - auto_heal_service: 補 import re + sqlalchemy.text + 修正 orchestrator 變數名 + autoheal_playbook→playbooks 表名 + _alert_and_store cooldown 修復 - aider_heal_executor: shell injection 改 shell=False + list 參數 - docker-compose: DISABLE_LOGIN 改 env var + 移除密碼 fallback + POSTGRES_HOST 修正 - app.py: /api/backup /api/run_task 等 6 個管理 API 加 @login_required - config.py + pg_sync + e2e_test: 移除 wooo_pg_2026 hardcoded 密碼 fallback - pg_backup.sh: 移除 TELEGRAM_TOKEN= 中間變數,直接用 $TELEGRAM_BOT_TOKEN - migration 014: trigger_pattern→match_pattern + 補 error_type NOT NULL 欄位 🟡 High - telegram_bot_service: str(e) 改通用訊息 + session try/finally + 移除 pa:/pr: 舊 callback - run_scheduler: ElephantAlpha thread 死亡監控 + 自動重啟 + Telegram 告警 + agent_context 03:30 TTL 定時清理任務 - openclaw_learning_service: build_rag_context 兩路徑加 .limit(200) - hooks: commit-quality + momo-prod-guard 空 catch 改 stderr+exit(1) - scripts/code_review: auto_yes 預設改 false - db_backup_service: PGPASSWORD 透過 env dict 傳遞 📦 Migrations - 013_autoheal: 修正建表順序 playbooks→incidents(外鍵前向引用) - 018_add_missing_indexes: heal_logs/incidents 外鍵索引 + cleanup_expired_agent_context() 🟢 Infrastructure - requirements.txt: 加版本下界 Flask>=2.3 SQLAlchemy>=1.4 等 - cd.yaml: 新增 run_scheduler.py + run_telegram_bot.py 監聽路徑 - .gitignore: insert_playbook_local.py 加入忽略 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
153 lines
4.4 KiB
Python
153 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Telegram Bot 獨立執行腳本
|
||
|
||
用法:
|
||
python run_telegram_bot.py
|
||
|
||
環境變數:
|
||
TELEGRAM_BOT_TOKEN: Telegram Bot Token (必填)
|
||
|
||
功能:
|
||
- 啟動 Telegram Bot 監聽
|
||
- 每日 09:00 推播趨勢摘要
|
||
- 處理用戶指令:/trend, /search, /copy, /keywords, /daily, /settings
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import asyncio
|
||
import logging
|
||
from datetime import datetime, time
|
||
from dotenv import load_dotenv
|
||
|
||
# 載入環境變數
|
||
load_dotenv()
|
||
|
||
# 設定日誌
|
||
logging.basicConfig(
|
||
level=logging.INFO,
|
||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||
handlers=[
|
||
logging.StreamHandler(),
|
||
logging.FileHandler('logs/telegram_bot.log', encoding='utf-8')
|
||
]
|
||
)
|
||
logger = logging.getLogger('TelegramBot')
|
||
|
||
def check_dependencies():
|
||
"""檢查必要的套件"""
|
||
try:
|
||
from telegram import Update
|
||
from telegram.ext import Application
|
||
logger.info("✅ python-telegram-bot 已安裝")
|
||
return True
|
||
except ImportError:
|
||
logger.error("❌ 請安裝 python-telegram-bot: pip install python-telegram-bot")
|
||
return False
|
||
|
||
def check_token():
|
||
"""檢查 Bot Token"""
|
||
token = os.getenv('TELEGRAM_BOT_TOKEN')
|
||
if not token:
|
||
logger.error("❌ 請在 .env 設定 TELEGRAM_BOT_TOKEN")
|
||
logger.info(" 1. 在 Telegram 搜尋 @BotFather")
|
||
logger.info(" 2. 發送 /newbot 建立新 Bot")
|
||
logger.info(" 3. 複製 Token 到 .env 檔案")
|
||
return None
|
||
logger.info("✅ Bot Token 已設定")
|
||
return token
|
||
|
||
async def main():
|
||
"""主程式"""
|
||
print("=" * 60)
|
||
print(" MOMO Pro System - Telegram Bot")
|
||
print("=" * 60)
|
||
print()
|
||
|
||
# 檢查依賴
|
||
if not check_dependencies():
|
||
sys.exit(1)
|
||
|
||
# 檢查 Token
|
||
token = check_token()
|
||
if not token:
|
||
sys.exit(1)
|
||
|
||
# 導入 Bot 服務
|
||
try:
|
||
from services.telegram_bot_service import TelegramBotService
|
||
logger.info("✅ TelegramBotService 已載入")
|
||
except ImportError as e:
|
||
logger.error(f"❌ 無法載入 TelegramBotService: {e}")
|
||
sys.exit(1)
|
||
|
||
# 建立 Bot 服務
|
||
bot_service = TelegramBotService(token)
|
||
|
||
# 取得 Application
|
||
app = bot_service.get_application()
|
||
|
||
if not app:
|
||
logger.error("❌ 無法建立 Bot Application")
|
||
sys.exit(1)
|
||
|
||
# 設定每日推播排程 (每天 09:00)
|
||
from telegram.ext import JobQueue
|
||
|
||
async def daily_summary_job(context):
|
||
"""每日摘要推播任務"""
|
||
logger.info("📤 執行每日趨勢摘要推播...")
|
||
await bot_service.send_daily_summary()
|
||
|
||
# 啟動 Bot
|
||
logger.info("🚀 啟動 Telegram Bot...")
|
||
logger.info(" 指令列表:")
|
||
logger.info(" /trend [分類] - 查看熱門趨勢")
|
||
logger.info(" /search [關鍵字] - AI 網路搜尋")
|
||
logger.info(" /copy [商品名] - 生成行銷文案")
|
||
logger.info(" /keywords - 熱門關鍵字")
|
||
logger.info(" /daily - 每日趨勢摘要")
|
||
logger.info(" /settings - 通知設定")
|
||
print()
|
||
|
||
# 初始化並啟動
|
||
await app.initialize()
|
||
await app.start()
|
||
|
||
# 設定每日推播 (09:00 台北時間)
|
||
# 注意:此排程(send_daily_summary)與 momo-scheduler 的 run_daily_report_task 功能不同:
|
||
# - 此處:從 TrendAnalysis 表推播「趨勢摘要」給訂閱 notify_daily_summary=True 的 Telegram 用戶
|
||
# - momo-scheduler:呼叫 OpenClaw generate_daily_report(),產出業績快報+競品威脅+圖表推播
|
||
# 兩者各自負責不同數據源與受眾,均需保留。
|
||
job_queue = app.job_queue
|
||
if job_queue:
|
||
# 計算下一個 09:00 的時間
|
||
target_time = time(hour=9, minute=0, second=0)
|
||
job_queue.run_daily(daily_summary_job, time=target_time, name='daily_summary')
|
||
logger.info("📅 已設定每日 09:00 推播趨勢摘要")
|
||
|
||
# 開始輪詢
|
||
await app.updater.start_polling(drop_pending_updates=True)
|
||
|
||
logger.info("✅ Bot 已啟動,按 Ctrl+C 停止")
|
||
|
||
# 保持運行
|
||
try:
|
||
while True:
|
||
await asyncio.sleep(1)
|
||
except KeyboardInterrupt:
|
||
logger.info("🛑 收到停止信號...")
|
||
finally:
|
||
await app.updater.stop()
|
||
await app.stop()
|
||
await app.shutdown()
|
||
logger.info("👋 Bot 已停止")
|
||
|
||
if __name__ == '__main__':
|
||
# 確保 logs 目錄存在
|
||
os.makedirs('logs', exist_ok=True)
|
||
|
||
# 執行
|
||
asyncio.run(main())
|