tgBot / app /proxy_session.py
picasco's picture
Upload 61 files
7d488be verified
Raw
History Blame
2.58 kB
from __future__ import annotations
import json
import base64
import logging
from typing import Any, Union, get_args, get_origin
import httpx
from pydantic import TypeAdapter
from aiogram.client.session.base import BaseSession
from aiogram.client.default import Default
from aiogram.methods import TelegramMethod
from aiogram.methods.base import TelegramType
from .config import settings
logger = logging.getLogger(__name__)
def _strip_defaults(obj):
if isinstance(obj, Default):
return None
if isinstance(obj, dict):
return {k: _strip_defaults(v) for k, v in obj.items() if not isinstance(v, Default)}
if isinstance(obj, (list, tuple)):
return [_strip_defaults(i) for i in obj]
return obj
class SupabaseProxySession(BaseSession):
def __init__(self):
super().__init__()
self._client = httpx.AsyncClient(timeout=60)
async def close(self):
await self._client.aclose()
async def make_request(
self,
bot,
method: TelegramMethod[TelegramType],
**kwargs: Any,
) -> TelegramType:
url = f"{settings.SUPABASE_URL}/functions/v1/telegram-proxy"
headers = {
"Authorization": f"Bearer {settings.SUPABASE_SERVICE_KEY}",
"x-bot-token": settings.TELEGRAM_BOT_TOKEN,
"Content-Type": "application/json",
}
method_name = method.__api_method__
raw = method.model_dump(exclude_none=True)
data = _strip_defaults(raw)
body = {"method": method_name, "data": data}
logger.info(f"Proxy → {method_name}")
try:
resp = await self._client.post(url, json=body, headers=headers)
except Exception:
logger.exception(f"Proxy HTTP error for {method_name}")
raise
result = resp.json()
logger.info(f"Proxy ← {method_name} ok={result.get('ok')}")
if not result.get("ok"):
logger.error(f"Telegram API error for {method_name}: {result}")
raise Exception(f"Telegram API error: {result}")
ret_type = method.__returning__
if ret_type is bool:
return result.get("result", True)
try:
return ret_type.model_validate(result["result"])
except Exception:
ta = TypeAdapter(ret_type)
return ta.validate_python(result["result"])
async def stream_content(self, url: str, timeout: int = 30, **kwargs):
async with httpx.AsyncClient() as client:
resp = await client.get(url)
return resp.content