feat(bot): add async DB and FSM state handling

This commit is contained in:
2026-07-23 22:58:52 +05:00
parent b1c8f6d9f8
commit 87385228ea
28 changed files with 514 additions and 213 deletions
+24 -3
View File
@@ -14,11 +14,11 @@ def _headers() -> dict[str, str | None]:
def asf_get(path: str) -> requests.Response:
logger.info("Отправка GET-запроса в ASF: path=%s", path)
response = requests.get(f"{ASF_URL}{path}", headers=_headers())
logger.info(
"Получен ответ ASF на GET-запрос: path=%s status=%s",
path,
response.status_code,
"Получен ответ ASF на GET-запрос: path=%s status=%s", path, response.status_code
)
return response
@@ -28,12 +28,14 @@ def asf_post(path: str, payload: dict | None = None) -> requests.Response:
path,
sorted((payload or {}).keys()),
)
response = requests.post(f"{ASF_URL}{path}", headers=_headers(), json=payload)
logger.info(
"Получен ответ ASF на POST-запрос: path=%s status=%s",
path,
response.status_code,
)
return response
@@ -41,6 +43,7 @@ def get_asf_status() -> requests.Response:
logger.info("Запрос статуса ASF")
response = requests.get(f"{ASF_URL}/Api/ASF", headers=_headers()) # type: ignore[arg-type]
logger.info("Получен статус ASF: status=%s", response.status_code)
return response
@@ -71,6 +74,7 @@ async def get_bot_inventory(bot_name: str, appid: int, contextid: int) -> dict |
appid,
contextid,
)
async with aiohttp.ClientSession() as session:
async with session.get(
f"{ASF_URL}/Api/Bot/{bot_name}/Inventory/{appid}/{contextid}",
@@ -85,6 +89,7 @@ async def get_bot_inventory(bot_name: str, appid: int, contextid: int) -> dict |
response.status,
)
return None
data = await response.json()
if not data.get("Success"):
logger.warning(
@@ -94,17 +99,20 @@ async def get_bot_inventory(bot_name: str, appid: int, contextid: int) -> dict |
contextid,
)
return None
logger.info(
"Инвентарь бота получен: bot=%s appid=%s contextid=%s",
bot_name,
appid,
contextid,
)
return data.get("Result")
async def get_2fa_token(bot_name: str) -> str:
logger.info("Запрос 2FA-кода: bot=%s", bot_name)
async with aiohttp.ClientSession() as session:
async with session.get(
f"{ASF_URL}/Api/Bot/{bot_name}/TwoFactorAuthentication/Token",
@@ -117,24 +125,29 @@ async def get_2fa_token(bot_name: str) -> str:
response.status,
)
return f"Ошибка HTTP {response.status}"
data = await response.json()
if not data.get("Success"):
logger.warning(
"ASF вернул ошибку при запросе 2FA-кода: bot=%s", bot_name
)
return "Ошибка ASF"
try:
logger.info("2FA-код успешно получен: bot=%s", bot_name)
return data["Result"][bot_name]["Result"]
except Exception:
logger.exception(
"Не удалось извлечь 2FA-код из ответа ASF: bot=%s", bot_name
)
return "Не удалось получить код"
async def get_confirmations(bot_name: str) -> list:
logger.info("Запрос подтверждений 2FA: bot=%s", bot_name)
async with aiohttp.ClientSession() as session:
async with session.get(
f"{ASF_URL}/Api/Bot/{bot_name}/TwoFactorAuthentication/Confirmations",
@@ -147,6 +160,7 @@ async def get_confirmations(bot_name: str) -> list:
response.status,
)
return []
data = await response.json()
if not data.get("Success"):
logger.warning(
@@ -154,6 +168,7 @@ async def get_confirmations(bot_name: str) -> list:
bot_name,
)
return []
try:
result = data["Result"][bot_name]["Result"]
logger.info(
@@ -162,6 +177,7 @@ async def get_confirmations(bot_name: str) -> list:
len(result),
)
return result
except Exception:
logger.exception(
"Не удалось извлечь подтверждения 2FA из ответа ASF: bot=%s",
@@ -172,6 +188,7 @@ async def get_confirmations(bot_name: str) -> list:
async def accept_confirmations(bot_name: str) -> int:
logger.info("Отправка запроса на подтверждение всех 2FA-операций: bot=%s", bot_name)
async with aiohttp.ClientSession() as session:
async with session.post(
f"{ASF_URL}/Api/Bot/{bot_name}/TwoFactorAuthentication/Confirmations/Accept",
@@ -182,6 +199,7 @@ async def accept_confirmations(bot_name: str) -> int:
bot_name,
response.status,
)
return response.status
@@ -192,6 +210,7 @@ def save_bot_config(bot_name: str, config: dict) -> requests.Response:
async def redeem_key(bot_name: str, key: str) -> tuple[bool, str]:
logger.info("Запрос активации ключа: bot=%s", bot_name)
async with aiohttp.ClientSession() as session:
async with session.post(
f"{ASF_URL}/Api/Command",
@@ -205,11 +224,13 @@ async def redeem_key(bot_name: str, key: str) -> tuple[bool, str]:
response.status,
)
return False, f"HTTP_ERROR_{response.status}"
data = await response.json()
if not data.get("Success"):
logger.warning(
"ASF вернул ошибку при активации ключа: bot=%s", bot_name
)
return False, "ASF_ERROR"
logger.info("ASF вернул результат активации ключа: bot=%s", bot_name)
return True, str(data.get("Result", ""))