← Back
#!/usr/bin/env python3
"""
AlphaPulseXP Telegram Bot v7.0
Modular architecture — see individual modules for details.

Modules:
  config.py    — Configuration & constants
  utils.py     — Utility functions (now_van, stable_id, build_hashtags)
  database.py  — SQLite persistence
  fetcher.py   — Content fetching (RSS, CoinGecko, Reddit)
  ai.py        — AI commentary via OpenRouter
  poster.py    — Telegram message formatting & sending
  commands.py  — /command and inline button handlers
  scheduler.py — Main scheduling loop
"""

import sys
import json
import asyncio
import logging
from aiohttp import web

from telegram.ext import Application, CommandHandler, CallbackQueryHandler

from config import CONFIG
from commands import CommandHandlers
from scheduler import AlphaPulseBot

# ─── Logging ──────────────────────────────────────────────────────────────────
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[logging.FileHandler('bot.log'), logging.StreamHandler()]
)
logger = logging.getLogger(__name__)


# ─── Entry Point ──────────────────────────────────────────────────────────────
def main():
    if not CONFIG['bot_token']:
        print("Error: TELEGRAM_BOT_TOKEN not set in environment")
        sys.exit(1)
    if not CONFIG['openrouter_key']:
        print("Error: OPENROUTER_API_KEY not set in environment")
        sys.exit(1)

    bot_instance = AlphaPulseBot()
    cmd_handlers = CommandHandlers(bot_instance.fetcher)

    # Build Application for command handling (polling runs alongside scheduler)
    app = Application.builder().token(CONFIG['bot_token']).build()

    # Slash commands
    app.add_handler(CommandHandler("price",    cmd_handlers.cmd_price))
    app.add_handler(CommandHandler("fear",     cmd_handlers.cmd_fear))
    app.add_handler(CommandHandler("stats",    cmd_handlers.cmd_stats))
    app.add_handler(CommandHandler("trending", cmd_handlers.cmd_trending))
    app.add_handler(CommandHandler("help",     cmd_handlers.cmd_help))

    # Inline button callbacks
    app.add_handler(CallbackQueryHandler(cmd_handlers.btn_price,    pattern="^cb_price$"))
    app.add_handler(CallbackQueryHandler(cmd_handlers.btn_fear,     pattern="^cb_fear$"))
    app.add_handler(CallbackQueryHandler(cmd_handlers.btn_trending, pattern="^cb_trending$"))

    # ── Health HTTP server ──────────────────────────────────────────────
    health_port = int(CONFIG.get('health_port', 8090))

    async def health_handler(request):
        stats = bot_instance.db.get_health_stats()
        stats['status'] = 'ok'
        stats['version'] = '8.2'
        stats['uptime_cycles'] = bot_instance.cycle_count
        return web.json_response(stats)

    async def analytics_handler(request):
        days = int(request.query.get('days', 7))
        data = bot_instance.db.get_analytics(days)
        return web.json_response(data)

    async def run_all():
        # Start health HTTP server
        health_app = web.Application()
        health_app.router.add_get('/health', health_handler)
        health_app.router.add_get('/analytics', analytics_handler)
        runner = web.AppRunner(health_app)
        await runner.setup()
        site = web.TCPSite(runner, '0.0.0.0', health_port)
        await site.start()
        logger.info(f"Health endpoint running on :{health_port}/health")

        await app.initialize()
        await app.start()
        await app.updater.start_polling(drop_pending_updates=True)
        logger.info("Command polling started (/price /fear /stats /trending /help)")
        await bot_instance.run()   # blocks forever
        # cleanup (reached only on KeyboardInterrupt propagated up)
        await runner.cleanup()
        await app.updater.stop()
        await app.stop()
        await app.shutdown()

    try:
        asyncio.run(run_all())
    except KeyboardInterrupt:
        logger.info("Bot stopped by user")
        sys.exit(0)
    except Exception as e:
        logger.error(f"Fatal error: {e}")
        sys.exit(1)


if __name__ == '__main__':
    main()

📜 Git History

a09f02fchore: initial commit — version control setup5 weeks ago
Show last diff
Loading...