telega/deep_link
Deep-linking helpers: build t.me links that open the bot with a
/start payload and read that payload back in the command handler.
Telegram restricts start payloads to A-Za-z0-9_-, at most 64
characters. To carry arbitrary data (user ids, referral codes with
separators, unicode), pair encode_payload/decode_payload — they wrap
the data in URL-safe base64, which fits the allowed alphabet.
// Somewhere a link is generated:
let assert Ok(link) = deep_link.encoded_start_link_for_bot(ctx.bot_info, "ref:42")
// -> "https://t.me/my_bot?start=cmVmOjQy"
// In the /start handler:
fn start_handler(ctx, command: update.Command) {
case deep_link.decoded_payload_from_command(command) {
Ok(Some(data)) -> reply.with_text(ctx, "Referred by: " <> data)
_ -> reply.with_text(ctx, "Hello!")
}
}
Types
pub type DeepLinkError {
PayloadTooLong(actual: Int)
InvalidPayloadCharacters(payload: String)
MissingBotUsername
}
Constructors
-
PayloadTooLong(actual: Int)Payload (or data passed to
encode_payload) exceeds the Telegram limit;actualis the offending length. -
InvalidPayloadCharacters(payload: String)Payload is empty or contains characters outside
A-Za-z0-9_-, or cannot be decoded back from base64. -
MissingBotUsernameThe bot has no username, so no
t.melink can be built.
Values
pub fn decode_payload(
payload payload: String,
) -> Result(String, DeepLinkError)
Decodes a payload produced by encode_payload back to the original data.
pub fn decoded_payload_from_command(
command command: update.Command,
) -> Result(option.Option(String), DeepLinkError)
Extracts and base64-decodes the payload of a command produced by an
encode_payload-built link. Ok(None) means there was no payload.
pub fn encode_payload(
data data: String,
) -> Result(String, DeepLinkError)
Encodes arbitrary data into a payload that fits the Telegram alphabet (URL-safe base64 without padding). Data must be at most 48 bytes, otherwise the encoded payload would not fit into 64 characters.
pub fn encoded_start_group_link(
username username: String,
data data: String,
) -> Result(String, DeepLinkError)
Like start_group_link, but encodes arbitrary data with
encode_payload first.
pub fn encoded_start_group_link_for_bot(
bot_info bot_info: types.User,
data data: String,
) -> Result(String, DeepLinkError)
Encodes arbitrary data and builds a group start link for the bot.
pub fn encoded_start_link(
username username: String,
data data: String,
) -> Result(String, DeepLinkError)
Like start_link, but encodes arbitrary data with encode_payload
first — one call instead of encode + link.
pub fn encoded_start_link_for_bot(
bot_info bot_info: types.User,
data data: String,
) -> Result(String, DeepLinkError)
Encodes arbitrary data and builds a start link for the bot — the closest
analog of aiogram’s create_start_link(bot, data, encode=True):
let assert Ok(link) = deep_link.encoded_start_link_for_bot(ctx.bot_info, "ref:42")
pub const max_data_length: Int
Raw data longer than 48 bytes does not fit into 64 characters once base64-encoded.
pub const max_payload_length: Int
Telegram allows at most 64 characters in a start payload.
pub fn payload_from_command(
command command: update.Command,
) -> option.Option(String)
Extracts the raw /start payload from a command, normalizing the empty
payload of a bare /start to None.
pub fn start_app_link(
username username: String,
app_name app_name: String,
payload payload: option.Option(String),
) -> Result(String, DeepLinkError)
Builds https://t.me/<username>/<app_name>?startapp=<payload> — opens a
Mini App directly. Without a payload the startapp parameter is omitted.
pub fn start_app_link_for_bot(
bot_info bot_info: types.User,
app_name app_name: String,
payload payload: option.Option(String),
) -> Result(String, DeepLinkError)
Like start_app_link, but takes the bot’s User (e.g. ctx.bot_info).
pub fn start_group_link(
username username: String,
payload payload: String,
) -> Result(String, DeepLinkError)
Builds https://t.me/<username>?startgroup=<payload> — prompts the user
to pick a group to add the bot to; the payload arrives in /start.
pub fn start_group_link_for_bot(
bot_info bot_info: types.User,
payload payload: String,
) -> Result(String, DeepLinkError)
Like start_group_link, but takes the bot’s User (e.g. ctx.bot_info).
pub fn start_link(
username username: String,
payload payload: String,
) -> Result(String, DeepLinkError)
Builds https://t.me/<username>?start=<payload> — opens a private chat
with the bot and suggests pressing Start; the payload arrives in the
/start command. A leading @ in the username is ignored.
pub fn start_link_for_bot(
bot_info bot_info: types.User,
payload payload: String,
) -> Result(String, DeepLinkError)
Like start_link, but takes the bot’s User (e.g. ctx.bot_info) and
fails with MissingBotUsername when the bot has no username.
pub fn validate_payload(
payload payload: String,
) -> Result(String, DeepLinkError)
Checks that a payload matches the Telegram deep-linking rules:
1 to 64 characters from A-Za-z0-9_-. Returns the payload unchanged.