Last active
April 22, 2025 02:36
-
-
Save Malith-Rukshan/da02bbf6e0219653c53ec9116cdd37f2 to your computer and use it in GitHub Desktop.
Validate Init data of Telegram Mini-App | TypeScript & Python
This file contains hidden or 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
import hmac | |
def checkValidateInitData(hash_str, init_data, token, c_str="WebAppData"): | |
""" | |
Validates the data received from the Telegram web app, using the | |
method documented here: | |
https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app | |
hash_str - the has string passed by the webapp | |
init_data - the query string passed by the webapp | |
token - Telegram bot's token | |
c_str - constant string (default = "WebAppData") | |
""" | |
init_data = sorted([ chunk.split("=") | |
for chunk in unquote(init_data).split("&") | |
if chunk[:len("hash=")]!="hash="], | |
key=lambda x: x[0]) | |
init_data = "\n".join([f"{rec[0]}={rec[1]}" for rec in init_data]) | |
secret_key = hmac.new(c_str.encode(), token.encode(), | |
hashlib.sha256 ).digest() | |
data_check = hmac.new( secret_key, init_data.encode(), | |
hashlib.sha256) | |
return data_check.hexdigest() == hash_str |
This file contains hidden or 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
import crypto from 'crypto'; | |
/** | |
* Validates the data received from the Telegram web app, following the | |
* documentation: https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app | |
* | |
* @param hashStr - The hash string passed by the web app. | |
* @param initData - The query string passed by the web app. | |
* @param token - Telegram bot's token. | |
* @param cStr - Constant string (default = "WebAppData"). | |
* @returns Boolean indicating whether the validation is successful. | |
*/ | |
export async function checkValidateInitData(hashStr: string, initData: string, token: string, cStr = 'WebAppData'): Promise<boolean> { | |
// Parse and sort the init data | |
const sortedData = initData | |
.split('&') | |
.filter(chunk => !chunk.startsWith('hash=')) | |
.map(chunk => chunk.split('=')) | |
.sort((a, b) => a[0].localeCompare(b[0])) | |
.map(([key, value]) => `${key}=${decodeURIComponent(value)}`) | |
.join('\n'); | |
// Create secret key | |
const secretKey = new Uint8Array(crypto.createHmac('sha256', cStr) | |
.update(token) | |
.digest()); | |
// Generate the data check hash | |
const dataCheck = crypto.createHmac('sha256', new Uint8Array(secretKey)) | |
.update(sortedData) | |
.digest('hex'); | |
// Compare the generated hash with the provided hash | |
return dataCheck === hashStr; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
helpful!