В прошлом месяце мне было очень интересно узнать, как работает игровая платформа Telegram. И поскольку мне было очень скучно играть в одиночку в игру Chrome T-Rex, я решил сделать ее как игру Telegram.

Разрабатывая его, я заметил, что обучающих программ для игровых ботов Telegram было не так много. Учебник объяснит весь процесс его создания от начала до конца. Я решил написать об этом.

Если вы хотите увидеть результат, игра доступна как trexjumpbot в Telegram и размещена здесь.

Требования

У вас должен быть установлен Node.js.

Шаг 1: Создание нашего бота

Чтобы создать игру, мы должны сначала создать встроенного бота. Мы делаем это, разговаривая с BotFather и отправляя команду

/newbot

Затем нас просят ввести имя и имя пользователя для нашего бота, и нам выдают токен API. Нам нужно сохранить его, так как он нам понадобится позже.

Мы также можем дополнить информацию о нашем боте, изменив его описание (которое будет отображаться, когда пользователь войдет в чат с нашим ботом в разделе «Что этот бот может делать?») На

/setdescription

А также установите его изображение, чтобы его можно было отличить от списка чата. Изображение должно быть квадратным, и мы можем установить его с помощью следующей команды:

/setuserpic

Мы также можем установить текст о нем, который будет отображаться на странице профиля бота, а также при предоставлении доступа другим пользователям.

/setabouttext

Наш бот должен быть встроенным, чтобы иметь возможность использовать его в нашей игре. Для этого нам просто нужно выполнить следующее и следовать инструкциям

/setinline

Шаг 2: Создание нашей игры

Теперь, когда наш встроенный бот полностью настроен, пришло время попросить BotFather создать игру:

/newgame

Мы просто следуем инструкциям и, наконец, нам нужно указать короткое имя для нашей игры. Это будет действовать как уникальный идентификатор, который нам понадобится позже вместе с нашим токеном API бота.

Шаг 3: Получение исходного кода игры T-Rex

Поскольку Chromium имеет открытый исходный код, некоторые пользователи извлекли из него игру T-Rex, и мы можем легко найти ее исходный код в Интернете.

Чтобы создать игру, я использовал код, доступный в этом репозитории GitHub, так что продолжайте и клонируйте его:

git clone https://github.com/wayou/t-rex-runner.git

Шаг 4. Настройка зависимостей

Сначала перейдите в клонированную папку и переместите все ее файлы в новую папку под названием «общедоступная».

mkdir public && mv * public/.

И запускаем проект

npm init

Вы можете заполнить запрошенную информацию по своему усмотрению (вы можете оставить значения по умолчанию), оставив точку входа как index.js

Нам понадобятся Express и node-telegram-bot-api, чтобы легко взаимодействовать с API Telegram.

npm install express --save
npm install node-telegram-bot-api --save

Мы собираемся добавить сценарий запуска, так как он необходим для развертывания игры на Heroku. Откройте package.json и добавьте стартовый скрипт в раздел скриптов:

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
}

Шаг 5: Кодирование нашего сервера

Теперь, когда у нас есть все зависимости, пришло время написать код сервера для нашего бота. Идем дальше и создаем файл index.js:

const express = require("express");
const path = require("path");
const TelegramBot = require("node-telegram-bot-api");
const TOKEN = "YOUR_API_TOKEN_GOES_HERE";
const server = express();
const bot = new TelegramBot(TOKEN, { polling: true } );
const port = process.env.PORT || 5000;
const gameName = "SHORT_NAME_YOUR_GAME";
const queries = {};

Код выше довольно прост. Нам просто требуются наши зависимости и устанавливаем токен, полученный от BotFather, а также короткое имя, которое мы определили в качестве идентификатора игры. Также мы настраиваем порт, инициализируем Express и объявляем пустой объект запроса. Это будет действовать как карта для хранения объекта пользователя Telegram под его идентификатором, чтобы получить его позже.

Затем нам нужно сделать содержимое общедоступного каталога доступным в виде статических файлов.

server.use(express.static(path.join(__dirname, 'public')));

Теперь приступим к определению логики нашего бота. Во-первых, давайте запрограммируем команду / help

bot.onText(/help/, (msg) => bot.sendMessage(msg.from.id, "This bot implements a T-Rex jumping game. Say /game if you want to play."));

Мы должны указать команду как регулярное выражение для первого параметра onText, а затем указать ответ бота с помощью sendMessage. Обратите внимание, что мы можем получить доступ к идентификатору пользователя, чтобы ответить, используя msg.from.id

Когда наш бот получит команду / start или / game, мы отправим игру пользователю с помощью bot.sendGame.

bot.onText(/start|game/, (msg) => bot.sendGame(msg.from.id, gameName));

Теперь пользователю будет показано название игры, его рекорд и кнопка для игры, но кнопка воспроизведения по-прежнему не работает. Итак, реализуем его логику.

bot.on("callback_query", function (query) {
  if (query.game_short_name !== gameName) {
    bot.answerCallbackQuery(query.id, "Sorry, '" + query.game_short_name + "' is not available.");
  } else {
    queries[query.id] = query;
    let gameurl = "https://YOUR_URL_HERE/index.html?  id="+query.id;
    bot.answerCallbackQuery({
      callback_query_id: query.id,
      url: gameurl
    });
  }
});

Когда пользователь нажимает кнопку воспроизведения, Telegram отправляет нам обратный вызов. В приведенном выше коде, когда мы сначала получаем этот обратный вызов, мы проверяем, что запрошенная игра действительно является нашей игрой, и если нет, мы показываем пользователю ошибку.

Если все верно, мы сохраняем запрос в объекте запросов, определенном ранее под его идентификатором, чтобы получить его позже и установить высокий балл, если это необходимо. Затем нам нужно ответить на обратный вызов, указав URL-адрес игры. Позже мы собираемся загрузить его в Heroku, поэтому вам нужно будет ввести здесь URL. Обратите внимание, что я передаю идентификатор в качестве параметра запроса в URL-адресе, чтобы иметь возможность установить высокий балл.

Прямо сейчас у нас есть полностью функциональная игра, но нам все еще не хватает рекордов и встроенного поведения. Давайте начнем с реализации встроенного кода и предложим нашу игру:

bot.on("inline_query", function(iq) {
  bot.answerInlineQuery(iq.id, [ { type: "game", id: "0", game_short_name: gameName } ] );
});

Наконец, мы собираемся реализовать логику рекордов:

server.get("/highscore/:score", function(req, res, next) {
  if (!Object.hasOwnProperty.call(queries, req.query.id)) return   next();
  let query = queries[req.query.id];
  let options;
  if (query.message) {
    options = {
      chat_id: query.message.chat.id,
      message_id: query.message.message_id
    };
  } else {
    options = {
      inline_message_id: query.inline_message_id
    };
  }
  bot.setGameScore(query.from.id, parseInt(req.params.score),  options,
  function (err, result) {});
});

В приведенном выше коде мы прослушиваем URL-адреса типа / highscore / 300? Id = 5721. Мы просто извлекаем пользователя из объекта запросов по его идентификатору (если он существует) и используем bot.setGameScore для отправки рекорда в Telegram. Объект параметров отличается, независимо от того, вызывает пользователь встроенного бота или нет, поэтому мы проверяем обе ситуации, как определено в Telegram Bot API.

Последнее, что нам нужно сделать на нашем сервере, - это просто прослушивать ранее определенный порт:

server.listen(port);

Шаг 6: изменение игры T-Rex

Мы должны изменить игру T-Rex, которую мы клонировали из репозитория GitHub, чтобы она отправляла высокий балл на наш сервер.

Откройте файл index.js в общей папке и в верхней части добавьте следующие строки, чтобы получить идентификатор игрока из URL-адреса:

var url = new URL(location.href);
var playerid = url.searchParams.get("id");

Наконец, мы собираемся найти функцию setHighScore и добавить в ее конец следующий код, чтобы отправить высокий балл на наш сервер:

// Submit highscore to Telegram
var xmlhttp = new XMLHttpRequest();
var url = "https://YOUR_URL_HERE/highscore/" + distance  +
"?id=" + playerid;
xmlhttp.open("GET", url, true);
xmlhttp.send();

Шаг 7: развертывание на Heroku

Наша игра завершена, но, не загрузив ее на сервер, мы не сможем протестировать ее в Telegram, и Heroku предоставляет нам очень простой способ ее загрузки.

Начните с создания нового приложения:

Измените наши заполнители URL на фактический URL (замените своим собственным):

Замените URL-адрес функцией setHighScore

var url = "https://trexgame.herokuapp.com/highscore/" + distance +
"?id=" + playerid;

А также при обратном вызове на сервере:

let gameurl = "https://trexgame.herokuapp.com/index.html?id="+query.id;

Наконец, давайте загрузим нашу игру на Heroku. Давайте выполним шаги, подробно описанные на странице Heroku: После установки Heroku CLI войдите в папку проекта и нажмите файлы:

heroku login
git init
heroku git:remote -a YOUR_HEROKU_APP_NAME
git add .
git commit -m "initial commit"
git push heroku master

Вот и все !, теперь у вас наконец-то есть полностью рабочая игра для Telegram. Давай, попробуй!

Полный исходный код этого примера доступен на GitHub.

использованная литература