Bots can offer users HTML5 games to play solo or to compete against each other in groups and one-on-one chats.

Sending a game

inputUserSelf#f7c1b13f = InputUser;

inputGameID#32c3e77 id:long access_hash:long = InputGame;
inputGameShortName#c331e80a bot_id:InputUser short_name:string = InputGame;

inputMediaGame#d33f43f3 id:InputGame = InputMedia;

game#bdf9653b flags:# id:long access_hash:long short_name:string title:string description:string photo:Photo document:flags.0?Document = Game;
messageMediaGame#fdb19008 game:Game = MessageMedia;


messages.sendMedia#3491eba9 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates;

Bots can directly send a game using messages.sendMedia, providing:

  • The bot's shortname obtained from @BotFather to inputGameShortName.short_name
  • The current bot's info to inputGameShortName.bot_id

The sent message will contain a messageMediaGame with a game, that can then be used by users to forward the game using sendMedia with inputGameID.

Starting a game

Games are started clicking on the button, which triggers an callback query that returns the game URL, for more info see here &raquo.
The game should then be opened in a WebView or in native UI (specified by the native_ui flag), exposing the appropriate HTML5 APIs in order to receive various JS game events directly from the code of the game, as described here ยป.

Setting highscores


messages.setGameScore#8ef8ecc0 flags:# edit_message:flags.0?true force:flags.1?true peer:InputPeer id:int user_id:InputUser score:int = Updates;
messages.setInlineGameScore#15ad9f64 flags:# edit_message:flags.0?true force:flags.1?true id:InputBotInlineMessageID user_id:InputUser score:int = Bool;

Games are supposed to report back to the MTProto API every time the user looses a game with a new highscore.
Since games run in the browser, they cannot directly report data to the API using the bot token, which must be kept secret.
Instead, they should send highscores to an intermediate server, that will then report scores using messages.setGameScore or messages.setInlineGameScore, depending on the source of the game.

  • The edit_message flag should be set if the game message should be automatically edited to include the current scoreboard
  • The force flag should be set if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters.

Getting highscores

messageActionGameScore#92a72876 game_id:long score:int = MessageAction;

messageService#286fa604 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction = Message;

highScore#58fffcd0 pos:int user_id:int score:int = HighScore;

messages.highScores#9a3bfd99 scores:Vector<HighScore> users:Vector<User> = messages.HighScores;


messages.getGameHighScores#e822649d peer:InputPeer id:int user_id:InputUser = messages.HighScores;
messages.getInlineGameHighScores#f635e1b id:InputBotInlineMessageID user_id:InputUser = messages.HighScores;

Every time a highscore is reached, and the edit_message flag is set when reporting the score, a messageService with a messageActionGameScore is generated, indicating that the highscore of a certain game has changed, thanks to a certain user_id.
Our own current position of the scoreboard is also reported as pos.

When receiving such an update, graphical clients should refetch the scoreboard using messages.getGameHighScores or messages.getInlineGameHighScores.