import logging import httpx from typing import Optional from app.config import settings logger = logging.getLogger(__name__) TEST_USER_THRESHOLD = 999999000 class MaxAPI: def __init__(self): self.base_url = settings.max_api_base self.token = settings.max_token self.client = httpx.AsyncClient(timeout=30.0) self.mock_replies: list = [] def _headers(self) -> dict: return { "Authorization": self.token, "Content-Type": "application/json", } async def get_me(self) -> dict: r = await self.client.get(f"{self.base_url}/me", headers=self._headers()) r.raise_for_status() return r.json() async def subscribe_webhook(self) -> dict: payload = { "url": settings.webhook_url, "update_types": settings.update_types, "secret": settings.webhook_secret, } r = await self.client.post( f"{self.base_url}/subscriptions", headers=self._headers(), json=payload, ) r.raise_for_status() return r.json() async def unsubscribe_webhook(self) -> dict: r = await self.client.delete( f"{self.base_url}/subscriptions", headers=self._headers(), ) r.raise_for_status() return r.json() async def get_subscriptions(self) -> dict: r = await self.client.get( f"{self.base_url}/subscriptions", headers=self._headers(), ) r.raise_for_status() return r.json() async def send_message( self, user_id: int, text: str, attachments: Optional[list] = None, format: Optional[str] = None, notify: bool = True, ) -> dict: if user_id >= TEST_USER_THRESHOLD: logger.info(f"MOCK send_message to test user {user_id}: {text[:50]}") self.mock_replies.append(text) return {"ok": True, "mock": True, "text": text} payload = {"text": text, "notify": notify} if attachments: payload["attachments"] = attachments if format: payload["format"] = format r = await self.client.post( f"{self.base_url}/messages?user_id={user_id}", headers=self._headers(), json=payload, ) r.raise_for_status() return r.json() async def answer_callback( self, callback_id: str, message: Optional[dict] = None, notification: Optional[str] = None, ) -> dict: payload = {} if message is not None: payload["message"] = message if notification is not None: payload["notification"] = notification r = await self.client.post( f"{self.base_url}/answers?callback_id={callback_id}", headers=self._headers(), json=payload, ) r.raise_for_status() return r.json() def pop_mock_replies(self) -> list: replies = list(self.mock_replies) self.mock_replies.clear() return replies def is_test_user(self, user_id: int) -> bool: return user_id >= TEST_USER_THRESHOLD async def close(self): await self.client.aclose() max_api = MaxAPI()