Add telegram bot
This commit is contained in:
123
bot/services/api_client.py
Normal file
123
bot/services/api_client.py
Normal file
@@ -0,0 +1,123 @@
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
import aiohttp
|
||||
|
||||
from config import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class APIClient:
|
||||
"""HTTP client for backend API communication."""
|
||||
|
||||
def __init__(self):
|
||||
self.base_url = settings.API_URL
|
||||
self._session: aiohttp.ClientSession | None = None
|
||||
logger.info(f"[APIClient] Initialized with base_url: {self.base_url}")
|
||||
|
||||
async def _get_session(self) -> aiohttp.ClientSession:
|
||||
if self._session is None or self._session.closed:
|
||||
logger.info("[APIClient] Creating new aiohttp session")
|
||||
self._session = aiohttp.ClientSession()
|
||||
return self._session
|
||||
|
||||
async def _request(
|
||||
self,
|
||||
method: str,
|
||||
endpoint: str,
|
||||
**kwargs
|
||||
) -> dict[str, Any] | None:
|
||||
"""Make HTTP request to backend API."""
|
||||
session = await self._get_session()
|
||||
url = f"{self.base_url}/api/v1{endpoint}"
|
||||
|
||||
logger.info(f"[APIClient] {method} {url}")
|
||||
if 'json' in kwargs:
|
||||
logger.info(f"[APIClient] Request body: {kwargs['json']}")
|
||||
if 'params' in kwargs:
|
||||
logger.info(f"[APIClient] Request params: {kwargs['params']}")
|
||||
|
||||
try:
|
||||
async with session.request(method, url, **kwargs) as response:
|
||||
logger.info(f"[APIClient] Response status: {response.status}")
|
||||
response_text = await response.text()
|
||||
logger.info(f"[APIClient] Response body: {response_text[:500]}")
|
||||
|
||||
if response.status == 200:
|
||||
import json
|
||||
return json.loads(response_text)
|
||||
elif response.status == 404:
|
||||
logger.warning(f"[APIClient] 404 Not Found")
|
||||
return None
|
||||
else:
|
||||
logger.error(f"[APIClient] API error {response.status}: {response_text}")
|
||||
return {"error": response_text}
|
||||
except aiohttp.ClientError as e:
|
||||
logger.error(f"[APIClient] Request failed: {e}")
|
||||
return {"error": str(e)}
|
||||
except Exception as e:
|
||||
logger.error(f"[APIClient] Unexpected error: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def confirm_telegram_link(
|
||||
self,
|
||||
token: str,
|
||||
telegram_id: int,
|
||||
telegram_username: str | None
|
||||
) -> dict[str, Any]:
|
||||
"""Confirm Telegram account linking."""
|
||||
result = await self._request(
|
||||
"POST",
|
||||
"/telegram/confirm-link",
|
||||
json={
|
||||
"token": token,
|
||||
"telegram_id": telegram_id,
|
||||
"telegram_username": telegram_username
|
||||
}
|
||||
)
|
||||
return result or {"error": "Не удалось связаться с сервером"}
|
||||
|
||||
async def get_user_by_telegram_id(self, telegram_id: int) -> dict[str, Any] | None:
|
||||
"""Get user by Telegram ID."""
|
||||
return await self._request("GET", f"/telegram/user/{telegram_id}")
|
||||
|
||||
async def unlink_telegram(self, telegram_id: int) -> dict[str, Any]:
|
||||
"""Unlink Telegram account."""
|
||||
result = await self._request(
|
||||
"POST",
|
||||
f"/telegram/unlink/{telegram_id}"
|
||||
)
|
||||
return result or {"error": "Не удалось связаться с сервером"}
|
||||
|
||||
async def get_user_marathons(self, telegram_id: int) -> list[dict[str, Any]]:
|
||||
"""Get user's marathons."""
|
||||
result = await self._request("GET", f"/telegram/marathons/{telegram_id}")
|
||||
if isinstance(result, list):
|
||||
return result
|
||||
return result.get("marathons", []) if result else []
|
||||
|
||||
async def get_marathon_details(
|
||||
self,
|
||||
marathon_id: int,
|
||||
telegram_id: int
|
||||
) -> dict[str, Any] | None:
|
||||
"""Get marathon details for user."""
|
||||
return await self._request(
|
||||
"GET",
|
||||
f"/telegram/marathon/{marathon_id}",
|
||||
params={"telegram_id": telegram_id}
|
||||
)
|
||||
|
||||
async def get_user_stats(self, telegram_id: int) -> dict[str, Any] | None:
|
||||
"""Get user's overall statistics."""
|
||||
return await self._request("GET", f"/telegram/stats/{telegram_id}")
|
||||
|
||||
async def close(self):
|
||||
"""Close the HTTP session."""
|
||||
if self._session and not self._session.closed:
|
||||
await self._session.close()
|
||||
|
||||
|
||||
# Global API client instance
|
||||
api_client = APIClient()
|
||||
Reference in New Issue
Block a user