Test / bot /webhook.py
Hfzune's picture
Update bot/webhook.py
aa85742 verified
Raw History Blame Contribute Delete
3.26 kB
import asyncio
import logging
import time
import os
from bot.telegram_api import send_message, edit_message
from bot.onboarding import (
handle_start,
handle_token_command,
handle_reset,
handle_help,
handle_stats,
)
from bot.streaming import stream_reply
from db import models as dbm
log = logging.getLogger("webhook")
_last_msg = {}
RATE_SECONDS = 2.0
ADMIN_TELEGRAM_IDS = {
int(x.strip())
for x in os.environ.get("ADMIN_TELEGRAM_IDS", "").split(",")
if x.strip().isdigit()
}
async def handle_update(update: dict):
msg = update.get("message") or update.get("edited_message")
if not msg:
return
chat = msg.get("chat", {})
chat_id = chat.get("id")
from_user = msg.get("from", {})
user_id = from_user.get("id")
username = from_user.get("username")
first_name = from_user.get("first_name")
if chat_id is None or user_id is None:
return
text = (msg.get("text") or "").strip()
if not text:
await send_message(chat_id, "⚠️ Only text messages are supported.")
return
dbm.upsert_user(user_id, username, first_name)
if text.startswith("/start"):
await handle_start(chat_id, user_id, username)
return
if text.startswith("/token"):
parts = text.split(maxsplit=1)
arg = parts[1].strip() if len(parts) > 1 else ""
await handle_token_command(chat_id, user_id, arg)
return
if text.startswith("/reset"):
await handle_reset(chat_id, user_id)
return
if text.startswith("/help"):
await handle_help(chat_id)
return
if text.startswith("/stats"):
await handle_stats(chat_id, user_id)
return
if text.startswith("/admin"):
if user_id in ADMIN_TELEGRAM_IDS:
await send_message(
chat_id,
"**Admin panel:** open the Space URL and switch to the 🔐 Admin Panel tab.",
)
else:
await send_message(chat_id, "⛔ You are not an admin.")
return
now = time.time()
last = _last_msg.get(user_id, 0)
if now - last < RATE_SECONDS:
await send_message(chat_id, "⏳ Slow down a moment.")
return
_last_msg[user_id] = now
if not dbm.user_has_valid_token(user_id):
await send_message(
chat_id,
"🔒 You need a valid access token.\n"
"Send `/token YOUR_TOKEN_HERE` to activate.",
)
return
try:
daily_limit = int(dbm.get_setting("daily_turn_limit", "100"))
except Exception:
daily_limit = 100
user = dbm.get_user(user_id)
if user and user.get("total_turns", 0) >= daily_limit:
await send_message(
chat_id,
"⚠️ Daily message limit reached. Try again tomorrow.",
)
return
# ---- Persist user turn ----
dbm.add_message(user_id, "user", text)
dbm.archive_append(user_id, "user", text)
try:
await stream_reply(chat_id, user_id, text)
except Exception:
log.exception("stream_reply crashed")
try:
await send_message(chat_id, "⚠️ Something went wrong generating a reply.")
except Exception:
pass