bot-signal-telegram / server.py
agus1111's picture
Update server.py
90f24b8 verified
# servr.py — FastAPI entrypoint (HF Spaces friendly)
# - Start bot (botsinyal/botsignal)
# - Start summary guard ala /lb dari summary_daily.py (cek tiap 15 menit; kirim H-1 sekali setelah >=06:00 WIB)
# - Sediakan endpoint /summary/force untuk trigger manual
import os
import asyncio
from datetime import date, timedelta, datetime
from zoneinfo import ZoneInfo
from fastapi import FastAPI, HTTPException, Query
# ========= Import bot core (dukung dua nama modul) =========
client = None
start_bot_background = None
_last_import_err = None
for mod in ("botsinyal", "botsignal"):
try:
m = __import__(mod, fromlist=["*"])
client = getattr(m, "client", None)
start_bot_background = getattr(m, "start_bot_background", None)
if client is not None and start_bot_background is not None:
print(f"[SERVER] imported bot core from {mod}")
break
except Exception as e:
_last_import_err = e
if client is None or start_bot_background is None:
raise RuntimeError(f"Cannot import bot client/startup ({_last_import_err})")
# ========= Import summary guard dari summary_daily =========
try:
from summary_daily import start_summary_guard, compute_summary_for_date, render_telegram_html
except Exception as e:
raise RuntimeError(f"Cannot import summary helpers: {e}")
app = FastAPI(title="Telegram Curator Health (HF Spaces)")
# ====== ENV ======
JAKARTA_TZ = ZoneInfo("Asia/Jakarta")
SUMMARY_CHAT_ID = os.environ.get("SUMMARY_CHAT_ID") # contoh: -100123..., atau @nama_channel
TARGET_CHANNEL_FALLBACK = os.environ.get("TARGET_CHANNEL", "@MidasTouchsignalll")
# ====== Startup ======
@app.on_event("startup")
async def startup():
# 1) start bot utama (listener, autotrack, dsb)
await start_bot_background()
# 2) aktifkan guard loop ala /lb (cek tiap 15 menit, idempotent)
asyncio.create_task(start_summary_guard(client, interval_sec=900, fallback_chat=TARGET_CHANNEL_FALLBACK))
print("[SERVER] ready (summary guard armed)")
# ====== Routes ======
@app.get("/")
async def root():
return {"status": "ok"}
@app.get("/health")
async def health():
return {"healthy": True}
@app.post("/summary/force")
async def force_summary(day: str | None = Query(default=None, description="YYYY-MM-DD (lokal WIB), default H-1")):
"""
Trigger kirim summary manual.
- Tanpa 'day' -> rekap H-1 (lokal WIB)
- Format 'day' = 'YYYY-MM-DD'
"""
if not SUMMARY_CHAT_ID and not TARGET_CHANNEL_FALLBACK:
raise HTTPException(status_code=400, detail="No SUMMARY_CHAT_ID or TARGET_CHANNEL set.")
try:
if day:
target_day = date.fromisoformat(day)
else:
target_day = (datetime.now(JAKARTA_TZ) - timedelta(days=1)).date()
data = compute_summary_for_date(target_day)
text = render_telegram_html(data, label_date=target_day.strftime("%Y-%m-%d"))
await client.send_message(
entity=SUMMARY_CHAT_ID or TARGET_CHANNEL_FALLBACK,
message=text,
parse_mode="html"
)
return {"ok": True, "sent_for": target_day.isoformat()}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))