TelegramMiniappValidation (telegram_miniapp_validation v0.1.0)
View SourceProvides functionality to validate Telegram Mini App initialization data.
This module implements the validation algorithm described in the Telegram Mini Apps documentation: https://docs.telegram-mini-apps.com/platform/init-data#validating
Summary
Functions
Parses the initialization data and extracts the hash value.
Checks if the provided hash is valid for the given data and bot token.
Validates the initialization data from a Telegram Mini App.
Validates the auth_date parameter to ensure it's not too old.
Functions
Parses the initialization data and extracts the hash value.
Parameters
init_data
: The raw initialization data string from the Telegram Mini App
Returns
{:ok, {data_map, hash}}
: If parsing is successful, returns the data map and hash{:error, reason}
: If parsing fails, returns the reason for failure
Checks if the provided hash is valid for the given data and bot token.
Parameters
data_map
: The parsed data maphash
: The hash value to validatebot_token
: The Telegram Bot token used to sign the data
Returns
true
: If the hash is validfalse
: If the hash is invalid
@spec validate(String.t(), String.t(), non_neg_integer()) :: {:ok, map()} | {:error, String.t()}
Validates the initialization data from a Telegram Mini App.
The validation process follows these steps:
- Parse the query string into key-value pairs
- Extract the hash value and remove it from the pairs
- Sort the remaining pairs alphabetically
- Create a data check string by joining the pairs with newlines
- Create an HMAC-SHA256 signature of the bot token using "WebAppData" as the key
- Create an HMAC-SHA256 signature of the data check string using the result from step 5 as the key
- Compare the calculated hash with the provided hash
Parameters
init_data
: The raw initialization data string from the Telegram Mini Appbot_token
: The Telegram Bot token used to sign the datamax_age_seconds
: Optional maximum age in seconds for the auth_date parameter (default: 86400 - 24 hours)
Returns
{:ok, parsed_data}
: If validation is successful, returns the parsed data as a map{:error, reason}
: If validation fails, returns the reason for failure
Examples
This example shows the structure of the returned data, but in a real scenario, you would need to use a valid hash and bot token:
# Using 0 for max_age_seconds to skip auth_date validation in this example
iex> init_data = "query_id=AAHdF6IQAAAAAN0XohDhrOrc&user=%7B%22id%22%3A279058397%7D&auth_date=1662771648&hash=mock_hash"
iex> TelegramMiniappValidation.parse_and_extract_hash(init_data)
{:ok, {%{"auth_date" => "1662771648", "query_id" => "AAHdF6IQAAAAAN0XohDhrOrc", "user" => %{"id" => 279058397}}, "mock_hash"}}
@spec validate_auth_date(map(), non_neg_integer()) :: :ok | {:error, String.t()}
Validates the auth_date parameter to ensure it's not too old.
Parameters
data_map
: The parsed data mapmax_age_seconds
: Maximum age in seconds for the auth_date parameter
Returns
:ok
: If the auth_date is valid{:error, reason}
: If the auth_date is invalid or missing