Last active 1755833310

Validates init data from webapp to check if a method was received from Telegram

Revision e9ccdea29105c32b660deff81033caaca396134f

telegram_webapp_validator.py Raw
1from hmac import new as hmac_new
2from hashlib import sha256
3from urllib.parse import unquote
4
5
6def validate(init_data: str, token: str, c_str="WebAppData") -> None | dict[str, str]:
7 """Validates init data from webapp to check if a method was received from Telegram
8 Args:
9 init_data (str): init_data string received from webapp
10 token (str): token of bot that initiated webapp
11 c_str (str, optional): Constant string for hash function, you shouldn't change that. Defaults to "WebAppData".
12 Returns:
13 None | dict[str, str]: object with data deserialized (user is not deserialized, you can do it by own, it's simple json) on successful validation, otherwise None
14 """
15
16 hash_string = ""
17
18 init_data_dict = dict()
19
20 for chunk in init_data.split("&"):
21 [key, value] = chunk.split("=", 1)
22 if key == "hash":
23 hash_string = value
24 continue
25 init_data_dict[key] = unquote(value)
26
27 if hash_string == "":
28 return None
29
30 init_data = "\n".join(
31 [
32 f"{key}={init_data_dict[key]}"
33 for key in sorted(init_data_dict.keys())
34 ]
35 )
36
37 secret_key = hmac_new(c_str.encode(), token.encode(), sha256).digest()
38 data_check = hmac_new(secret_key, init_data.encode(), sha256)
39
40 if data_check.hexdigest() != hash_string:
41 return None
42
43 return init_data_dict