new-qwen/bot/telegram_api.py

98 lines
3.3 KiB
Python

from __future__ import annotations
import json
from typing import Any
from urllib import parse, request as urllib_request
class TelegramAPI:
def __init__(self, token: str, proxy_url: str | None = None) -> None:
self.base_url = f"https://api.telegram.org/bot{token}"
handlers = []
if proxy_url:
handlers.append(urllib_request.ProxyHandler({"https": proxy_url, "http": proxy_url}))
self.opener = urllib_request.build_opener(*handlers) if handlers else urllib_request.build_opener()
def _post(self, method: str, payload: dict[str, Any]) -> dict[str, Any]:
data = json.dumps(payload).encode("utf-8")
req = urllib_request.Request(
f"{self.base_url}/{method}",
data=data,
headers={"Content-Type": "application/json"},
method="POST",
)
with self.opener.open(req, timeout=90) as response:
return json.loads(response.read().decode("utf-8"))
def _get(self, method: str, params: dict[str, Any]) -> dict[str, Any]:
query = parse.urlencode(params)
with self.opener.open(f"{self.base_url}/{method}?{query}", timeout=90) as response:
return json.loads(response.read().decode("utf-8"))
def get_updates(self, offset: int | None, timeout: int) -> list[dict[str, Any]]:
params: dict[str, Any] = {"timeout": timeout}
if offset is not None:
params["offset"] = offset
response = self._get("getUpdates", params)
return response.get("result", [])
def send_message(
self,
chat_id: int,
text: str,
*,
parse_mode: str | None = None,
reply_markup: dict[str, Any] | None = None,
) -> int:
payload: dict[str, Any] = {"chat_id": chat_id, "text": text}
if parse_mode:
payload["parse_mode"] = parse_mode
if reply_markup:
payload["reply_markup"] = reply_markup
response = self._post("sendMessage", payload)
result = response.get("result") or {}
return int(result.get("message_id", 0))
def edit_message_text(
self,
chat_id: int,
message_id: int,
text: str,
*,
parse_mode: str | None = None,
reply_markup: dict[str, Any] | None = None,
) -> None:
try:
payload: dict[str, Any] = {
"chat_id": chat_id,
"message_id": message_id,
"text": text,
}
if parse_mode:
payload["parse_mode"] = parse_mode
if reply_markup is not None:
payload["reply_markup"] = reply_markup
self._post(
"editMessageText",
payload,
)
except Exception as exc:
if "message is not modified" in str(exc).lower():
return
raise
def send_chat_action(self, chat_id: int, action: str = "typing") -> None:
self._post(
"sendChatAction",
{
"chat_id": chat_id,
"action": action,
},
)
def answer_callback_query(self, callback_query_id: str, text: str | None = None) -> None:
payload: dict[str, Any] = {"callback_query_id": callback_query_id}
if text:
payload["text"] = text
self._post("answerCallbackQuery", payload)