Last active
July 19, 2024 00:59
-
-
Save dantetemplar/68e09e3674bf6ce72e23b89b2091d159 to your computer and use it in GitHub Desktop.
Check Telegram WebAppData in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Check Telegram WebAppData in Python | |
Based on https://core.telegram.org/widgets/login#checking-authorization | |
""" | |
import hashlib | |
import hmac | |
import json | |
from pydantic import BaseModel | |
BOT_TOKEN = "Your bot token here" | |
class TelegramWidgetData(BaseModel): | |
hash: str | |
query_id: str | |
user: str | |
auth_date: int | |
@property | |
def user_id(self): | |
json_ = json.loads(self.user) | |
return json_["id"] | |
@classmethod | |
def parse_from_string(cls, string: str) -> "TelegramWidgetData": | |
""" | |
Parse telegram widget data from string | |
""" | |
from urllib.parse import parse_qs | |
params = parse_qs(string) | |
return cls(**{k: v[0] for k, v in params.items()}) | |
@property | |
def string_to_hash(self) -> str: | |
return "\n".join([f"{k}={getattr(self, k)}" for k in sorted(self.model_fields.keys()) if k != "hash"]) | |
@property | |
def encoded(self) -> bytes: | |
return self.string_to_hash.encode("utf-8").decode("unicode-escape").encode("ISO-8859-1") | |
class VerificationResult(BaseModel): | |
success: bool | |
user_id: int | None = None | |
def telegram_webapp_check_authorization( | |
telegram_data: TelegramWidgetData, | |
) -> VerificationResult: | |
""" | |
Verify telegram data | |
https://core.telegram.org/widgets/login#checking-authorization | |
""" | |
received_hash = telegram_data.hash | |
encoded_telegram_data = telegram_data.encoded | |
token = BOT_TOKEN | |
secret_key = hmac.new("WebAppData".encode(), token.encode(), hashlib.sha256).digest() | |
evaluated_hash = hmac.new(secret_key, encoded_telegram_data, hashlib.sha256).hexdigest() | |
success = evaluated_hash == received_hash | |
if success: | |
return VerificationResult(success=success, user_id=telegram_data.user_id) | |
else: | |
return VerificationResult(success=success) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment