initdata

package module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 15, 2024 License: MIT Imports: 13 Imported by: 12

README

init-data-golang

The package that provides utilities to work with the initialization data of Telegram Mini Apps.

Installation

go get github.com/telegram-mini-apps/init-data-golang

Validation

If the expiration time is set to 0, the function will skip the expiration time check. However, it is recommended to specify a non-zero value, as this check is considered important in preventing the usage of old stolen initialization data.

package main

import (
	"fmt"
	"time"

	initdata "github.com/telegram-mini-apps/init-data-golang"
)

func main() {
	// Init data in raw format.
	initData := "user=%7B%22id%22%3A279058397%2C%22first_name%22%3A%22Vladislav%20%2B%20-%20%3F%20%5C%2F%22%2C%22last_name%22%3A%22Kibenko%22%2C%22username%22%3A%22vdkfrost%22%2C%22language_code%22%3A%22ru%22%2C%22is_premium%22%3Atrue%2C%22allows_write_to_pm%22%3Atrue%2C%22photo_url%22%3A%22https%3A%5C%2F%5C%2Ft.me%5C%2Fi%5C%2Fuserpic%5C%2F320%5C%2F4FPEE4tmP3ATHa57u6MqTDih13LTOiMoKoLDRG4PnSA.svg%22%7D&chat_instance=8134722200314281151&chat_type=private&auth_date=1733509682&signature=TYJxVcisqbWjtodPepiJ6ghziUL94-KNpG8Pau-X7oNNLNBM72APCpi_RKiUlBvcqo5L-LAxIc3dnTzcZX_PDg&hash=a433d8f9847bd6addcc563bff7cc82c89e97ea0d90c11fe5729cae6796a36d73"

	// Telegram Bot secret key.
	token := "7342037359:AAHI25ES9xCOMPokpYoz-p8XVrZUdygo2J4"

	// Define how long since init data generation date init data is valid.
	expIn := 24 * time.Hour

	// Will return error in case, init data is invalid.
	fmt.Println(initdata.Validate(initData, token, expIn))
}

Third-Party Validation

The package allows validating init data to check if it was signed by Telegram.

To do so, call the ValidateThirdParty function with the following arguments:

  • initData: string: Init data in raw format.
  • botID: int64: The Telegram Bot issuer identifier for the init data.
  • expIn: time.Time: The maximum lifetime of the init data.

Here is an example:

package main

import (
	"fmt"
	"time"

	initdata "github.com/telegram-mini-apps/init-data-golang"
)

func main() {
	// Init data in raw format.
	initData := "user=%7B%22id%22%3A279058397%2C%22first_name%22%3A%22Vladislav%20%2B%20-%20%3F%20%5C%2F%22%2C%22last_name%22%3A%22Kibenko%22%2C%22username%22%3A%22vdkfrost%22%2C%22language_code%22%3A%22ru%22%2C%22is_premium%22%3Atrue%2C%22allows_write_to_pm%22%3Atrue%2C%22photo_url%22%3A%22https%3A%5C%2F%5C%2Ft.me%5C%2Fi%5C%2Fuserpic%5C%2F320%5C%2F4FPEE4tmP3ATHa57u6MqTDih13LTOiMoKoLDRG4PnSA.svg%22%7D&chat_instance=8134722200314281151&chat_type=private&auth_date=1733584787&hash=2174df5b000556d044f3f020384e879c8efcab55ddea2ced4eb752e93e7080d6&signature=zL-ucjNyREiHDE8aihFwpfR9aggP2xiAo3NSpfe-p7IbCisNlDKlo7Kb6G4D0Ao2mBrSgEk4maLSdv6MLIlADQ"

	// Telegram Bot secret key.
	var botID int64 = 7342037359

	// Define how long since init data generation date init data is valid.
	expIn := 24 * time.Hour

	// Will return an error if init data is invalid.
	fmt.Println(initdata.ValidateThirdParty(initData, botID, expIn))
}

You can also use the ValidateThirdPartyWithEnv function with the additional boolean argument responsible for marking the environment as the testing one.

Parsing

It is important to note that the Parse function does not perform the same checks as the Validate function. Therefore, this function solely parses incoming data without conducting validations for the hash or expiration time.

package main

import (
	"fmt"

	initdata "github.com/telegram-mini-apps/init-data-golang"
)

func main() {
	// Init data in raw format.
	initData := "user=%7B%22id%22%3A279058397%2C%22first_name%22%3A%22Vladislav%20%2B%20-%20%3F%20%5C%2F%22%2C%22last_name%22%3A%22Kibenko%22%2C%22username%22%3A%22vdkfrost%22%2C%22language_code%22%3A%22ru%22%2C%22is_premium%22%3Atrue%2C%22allows_write_to_pm%22%3Atrue%2C%22photo_url%22%3A%22https%3A%5C%2F%5C%2Ft.me%5C%2Fi%5C%2Fuserpic%5C%2F320%5C%2F4FPEE4tmP3ATHa57u6MqTDih13LTOiMoKoLDRG4PnSA.svg%22%7D&chat_instance=8134722200314281151&chat_type=private&auth_date=1733509682&signature=TYJxVcisqbWjtodPepiJ6ghziUL94-KNpG8Pau-X7oNNLNBM72APCpi_RKiUlBvcqo5L-LAxIc3dnTzcZX_PDg&hash=a433d8f9847bd6addcc563bff7cc82c89e97ea0d90c11fe5729cae6796a36d73"

	// Will return 2 values.
	// 1. InitData instance if passed data has a correct format.
	// 2. Error in case, something is wrong. 
	fmt.Println(initdata.Parse(initData))
}

Signing

The functions that sign data remove parameters such as hash and auth_date since it is assumed that the hash will be returned by the function and the auth_date will be set by the function itself.

package main

import (
	"fmt"
	"time"

	initdata "github.com/telegram-mini-apps/init-data-golang"
)

func main() {
	// Init data in raw format.
	initData := "user=%7B%22id%22%3A279058397%2C%22first_name%22%3A%22Vladislav%20%2B%20-%20%3F%20%5C%2F%22%2C%22last_name%22%3A%22Kibenko%22%2C%22username%22%3A%22vdkfrost%22%2C%22language_code%22%3A%22ru%22%2C%22is_premium%22%3Atrue%2C%22allows_write_to_pm%22%3Atrue%2C%22photo_url%22%3A%22https%3A%5C%2F%5C%2Ft.me%5C%2Fi%5C%2Fuserpic%5C%2F320%5C%2F4FPEE4tmP3ATHa57u6MqTDih13LTOiMoKoLDRG4PnSA.svg%22%7D&chat_instance=8134722200314281151&chat_type=private&auth_date=1733509682&signature=TYJxVcisqbWjtodPepiJ6ghziUL94-KNpG8Pau-X7oNNLNBM72APCpi_RKiUlBvcqo5L-LAxIc3dnTzcZX_PDg&hash=a433d8f9847bd6addcc563bff7cc82c89e97ea0d90c11fe5729cae6796a36d73"

	// Telegram Bot secret key.
	token := "7342037359:AAHI25ES9xCOMPokpYoz-p8XVrZUdygo2J4"

	// Signing timestamp.
	// Here we took the value from the initData variable
	// above (auth_date query parameter).
	authDate := time.Unix(1733509682, 0)

	// Signing query parameters.
	// Returned values:
	// 1. Parameters sign result ("hash" init data property).
	// 2. Error occurring while parsing query string as query parameters.
	fmt.Println(initdata.SignQueryString(initData, token, authDate))

	// Signing the same query parameters presented as a map.
	fmt.Println(initdata.Sign(map[string]string{
		"user":          "{\"id\":279058397,\"first_name\":\"Vladislav + - ? \\/\",\"last_name\":\"Kibenko\",\"username\":\"vdkfrost\",\"language_code\":\"ru\",\"is_premium\":true,\"allows_write_to_pm\":true,\"photo_url\":\"https:\\/\\/t.me\\/i\\/userpic\\/320\\/4FPEE4tmP3ATHa57u6MqTDih13LTOiMoKoLDRG4PnSA.svg\"}",
		"chat_instance": "8134722200314281151",
		"chat_type":     "private",
		"signature":     "TYJxVcisqbWjtodPepiJ6ghziUL94-KNpG8Pau-X7oNNLNBM72APCpi_RKiUlBvcqo5L-LAxIc3dnTzcZX_PDg",
	}, token, authDate))

	// In the console, you should see the same results.
}

GoDoc

To see GoDoc documentation, visit this link.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrAuthDateMissing  = errors.New("auth_date is missing")
	ErrSignMissing      = errors.New("sign is missing")
	ErrSignInvalid      = errors.New("sign is invalid")
	ErrUnexpectedFormat = errors.New("init data has unexpected format")
	ErrExpired          = errors.New("init data is expired")
)

Functions

func Sign

func Sign(payload map[string]string, key string, authDate time.Time) string

Sign signs passed payload using specified key. Function removes such technical parameters as "hash" and "auth_date".

func SignQueryString

func SignQueryString(qs, key string, authDate time.Time) (string, error)

SignQueryString signs passed query string.

func Validate

func Validate(initData, token string, expIn time.Duration) error

Validate validates passed init data. This method expects initData to be passed in the exact raw format as it could be found in window.Telegram.WebApp.initData.

Returns error if something is wrong with the passed init data. Nil otherwise.

initData - init data passed from application; token - init data Telegram Bot issuer token; expIn - maximum init data lifetime. It is strongly recommended to use this parameter. In case, exp duration is less than or equal to 0, function does not check if parameters are expired.

func ValidateThirdParty added in v1.3.0

func ValidateThirdParty(initData string, botID int64, expIn time.Duration) error

ValidateThirdParty performs validation described in the Validate3rdWithEnv function using production environment.

func ValidateThirdPartyWithEnv added in v1.3.0

func ValidateThirdPartyWithEnv(
	initData string,
	botID int64,
	expIn time.Duration,
	isTest bool,
) error

ValidateThirdPartyWithEnv validates passed init data assuming that it was signed by Telegram. This method expects initData to be passed in the exact raw format as it could be found in window.Telegram.WebApp.initData.

Returns error if something is wrong with the passed init data. Nil otherwise.

initData - init data passed from application; botID - init data Telegram Bot issuer identifier; expIn - maximum init data lifetime. It is strongly recommended to use this parameter. In case, exp duration is less than or equal to 0, function does not check if parameters are expired. isTest - true if the init data was issued in Telegram production environment;

Types

type Chat

type Chat struct {
	// Unique identifier for this chat.
	ID int64 `json:"id"`

	// Type of chat.
	Type ChatType `json:"type"`

	// Title of the chat.
	Title string `json:"title"`

	// Optional. URL of the chat’s photo. The photo can be in .jpeg or .svg
	// formats. Only returned for Web Apps launched from the attachment menu.
	PhotoURL string `json:"photo_url"`

	// Optional. Username of the chat.
	Username string `json:"username"`
}

Chat describes chat information: https://docs.telegram-mini-apps.com/launch-parameters/init-data#chat

type ChatType

type ChatType string

ChatType describes type of chat.

const (
	ChatTypeSender     ChatType = "sender"
	ChatTypePrivate    ChatType = "private"
	ChatTypeGroup      ChatType = "group"
	ChatTypeSupergroup ChatType = "supergroup"
	ChatTypeChannel    ChatType = "channel"
)

func (ChatType) Known added in v1.1.3

func (c ChatType) Known() bool

Known returns true if current chat type is known.

type InitData

type InitData struct {
	// The date the initialization data was created. Is a number representing a
	// Unix timestamp.
	AuthDateRaw int `json:"auth_date"`

	// Optional. The number of seconds after which a message can be sent via
	// the method answerWebAppQuery.
	// https://core.telegram.org/bots/api#answerwebappquery
	CanSendAfterRaw int `json:"can_send_after"`

	// Optional. An object containing information about the chat with the bot in
	// which the Mini Apps was launched. It is returned only for Mini Apps
	// opened through the attachment menu.
	Chat Chat `json:"chat"`

	// Optional. The type of chat from which the Mini Apps was opened.
	// Returned only for applications opened by direct link.
	ChatType ChatType `json:"chat_type"`

	// Optional. A global identifier indicating the chat from which the Mini
	// Apps was opened. Returned only for applications opened by direct link.
	ChatInstance int64 `json:"chat_instance"`

	// Initialization data signature.
	// https://core.telegram.org/bots/webapps#validating-data-received-via-the-web-app
	Hash string `json:"hash"`

	// Optional. The unique session ID of the Mini App. Used in the process of
	// sending a message via the method answerWebAppQuery.
	// https://core.telegram.org/bots/api#answerwebappquery
	QueryID string `json:"query_id"`

	// Optional. An object containing data about the chat partner of the current
	// user in the chat where the bot was launched via the attachment menu.
	// Returned only for private chats and only for Mini Apps launched via the
	// attachment menu.
	Receiver User `json:"receiver"`

	// Optional. The value of the startattach or startapp query parameter
	// specified in the link. It is returned only for Mini Apps opened through
	// the attachment menu.
	StartParam string `json:"start_param"`

	// Optional. An object containing information about the current user.
	User User `json:"user"`
}

InitData contains init data. https://docs.telegram-mini-apps.com/launch-parameters/init-data#parameters-list

func Parse

func Parse(initData string) (InitData, error)

Parse converts passed init data presented as query string to InitData object.

func (*InitData) AuthDate

func (d *InitData) AuthDate() time.Time

AuthDate returns AuthDateRaw as time.Time.

func (*InitData) CanSendAfter

func (d *InitData) CanSendAfter() time.Time

CanSendAfter returns computed time which depends on CanSendAfterRaw and AuthDate. Originally, CanSendAfterRaw means time in seconds, after which `answerWebAppQuery` method can be called and that's why this value could be computed as time.

type User

type User struct {
	// Optional. True, if this user added the bot to the attachment menu.
	AddedToAttachmentMenu bool `json:"added_to_attachment_menu"`

	// Optional. True, if this user allowed the bot to message them.
	AllowsWriteToPm bool `json:"allows_write_to_pm"`

	// First name of the user or bot.
	FirstName string `json:"first_name"`

	// A unique identifier for the user or bot.
	ID int64 `json:"id"`

	// Optional. True, if this user is a bot. Returned in the `receiver` field
	// only.
	IsBot bool `json:"is_bot"`

	// Optional. True, if this user is a Telegram Premium user.
	IsPremium bool `json:"is_premium"`

	// Optional. Last name of the user or bot.
	LastName string `json:"last_name"`

	// Optional. Username of the user or bot.
	Username string `json:"username"`

	// Optional. IETF language tag of the user's language. Returns in user
	// field only.
	// https://en.wikipedia.org/wiki/IETF_language_tag
	LanguageCode string `json:"language_code"`

	// Optional. URL of the user’s profile photo. The photo can be in .jpeg or
	// .svg formats. Only returned for Web Apps launched from the
	// attachment menu.
	PhotoURL string `json:"photo_url"`
}

User describes user information: https://docs.telegram-mini-apps.com/launch-parameters/init-data#user

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL