Spaces:
Paused
Paused
| 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 | |