Skip to content

Instantly share code, notes, and snippets.

@safra36
Last active March 3, 2026 17:11
Show Gist options
  • Select an option

  • Save safra36/5dc49ee19f6b3546919a247bb26f3a2b to your computer and use it in GitHub Desktop.

Select an option

Save safra36/5dc49ee19f6b3546919a247bb26f3a2b to your computer and use it in GitHub Desktop.
Telegram mini-app authorization
// to use it on your webapp, simply create a backend with these functions, and use this to verify authorization
fetch("/auth", {
method : "POST",
body : window.Telegram.WebApp.initData,
})
import type { TelegramUser } from "./types";
export function isAuthorized(mapped : URLSearchParams) : boolean {
const hashString = [...mapped.entries()]
.filter(([key]) => key !== 'hash')
.sort(([a], [b]) => a.localeCompare(b))
.map(([key, value]) => `${key}=${value}`)
.join('\n');
const secretKey = createHmac("sha256", "WebAppData").update(PRIVATE_BOT_TOKEN).digest();
const hash = createHmac("sha256", secretKey).update(hashString).digest("hex");
// indicate how much this token is valid in your app, in out case it was 1 day (24 * 60 * 60 * 1000)
if(mapped.get('hash') == hash && (Date.now() - new Date(+mapped.get("auth_date")! * 1000).getTime()) < 24 * 60 * 60 * 1000) {
return true
}
else {
return false;
}
}
export function getUserFromParams( mapped : URLSearchParams ) : TelegramUser {
return JSON.parse(mapped.get("user"));
}
export interface TelegramUser {
id: number;
first_name: string;
last_name: string;
username: string;
language_code: string;
allows_write_to_pm: boolean;
photo_url: string;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment