Статьи

Как запустить бот Telegram с PHP

Если вы читаете это, вы знаете, что чат-боты являются одной из самых больших технологических тенденций 2016 года.

Революция ботов — это не только искусственный интеллект. Бот может быть инструментом в вашем мессенджере с простым интерфейсом чата, который может использоваться для расширения функциональности сайтов или служб или даже может быть автономным приложением. Боты дешевле в разработке и проще в установке, а еще одна замечательная особенность заключается в том, что мессенджеры можно использовать на любом типе устройств — ноутбуках, смартфонах и планшетах. Вот почему сейчас все без ума от ботов.

И самый большой мессенджер с открытым API бота — Telegram .

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

Кстати, я уже подготовил демо, так что вы можете протестировать его, просто добавив @stopwatchbot в свой список контактов Telegram.

Первым шагом к созданию бота является регистрация учетной записи вашего бота в Telegram. И для этого есть бот, который называется BotFather . Просто добавьте его в свой список контактов, и вы сможете создавать и настраивать ботов Telegram, просто набрав команду /newbot и следуя инструкциям BotFather.

BotFather работает Telegram

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

Позже вы можете использовать BotFather для добавления описаний или фотографий в профили ваших ботов, регенерировать токены, устанавливать списки команд для использования, удалять учетные записи и так далее. Чтобы получить полный список команд, просто наберите /help в чате, чтобы получить список команд BotFather.

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

И есть простой инструмент для подключения вашего бота к аналитике, который называется Botan . Он основан на яндекс AppMetric и полностью бесплатен. Используя Botan, вы можете сегментировать свою аудиторию, получать информацию о профилях пользователей, получать наиболее часто используемые команды и получать красивые графики прямо в своем мессенджере, например:

График Bot Analytics

Для начала вам нужно зарегистрировать своего бота в Botan и получить токен. И снова, вы можете сделать это с ботом, BotanioBot:

Регистрация бота в Telegram

Просто нажмите кнопку «Добавить бота» на диалоговой клавиатуре, введите ник своего бота, и вы получите токен бота. Теперь Botanio готов отслеживать ваши бот-события, и вы можете получать статистику по пользователям, сеансам, времени хранения и событиям прямо в своем мессенджере.

В Telegram есть два способа получать сообщения от ваших пользователей: длинные опросы и веб-хуки.

Диаграмма API Telegram

По сути, при длительном опросе вам необходимо запрашивать новые сообщения у API, а при веб-крюках вы устанавливаете обратный вызов, который будет вызывать API Telegram, если новое сообщение поступит от пользователя. Я предпочитаю использовать webhooks, потому что это похоже на общение в реальном времени, поэтому в этой статье мы также будем использовать этот метод. Теперь нам нужно выбрать URL обратного вызова для нашего webhook, который должен быть достигнут по протоколу HTTPS, и нам нужно установить его действительно безопасным, поэтому спрячьте свой скрипт в секретном пути, как сказано в руководстве:

Если вы хотите убедиться, что запрос Webhook исходит от Telegram, мы рекомендуем использовать секретный путь в URL, например, https://www.example.com/<token> . Поскольку никто не знает маркер вашего бота, вы можете быть уверены, что это мы.

Если ваш сертификат SSL является доверенным, все, что вам нужно сделать, это открыть этот URL в вашем браузере:

1
https://api.telegram.org:443/bot[token]/setwebhook?url=[webhook]

В противном случае вы должны создать самозаверяющий сертификат. Вот пример команды для Linux для него:

1
openssl req -newkey rsa:2048 -sha256 -nodes -keyout /path/to/certificate.key -x509 -days 365 -out /path/to/certificate.crt -subj «/C=IT/ST=state/L=location/O=description/CN=yourdomain.com»

И не забудьте открыть порт SSL:

1
sudo ufw allow 443/tcp

Чтобы проверить сертификат и установить для своего домена webhook доверие, необходимо загрузить сертификат открытого ключа:

1
2
3
4
curl \
 -F «url=https://yourdomain.com/path/to/script.php» \
 -F «certificate=/path/to/certificate.key» \
 «https://api.telegram.org/bot[token]/setwebhook»

Наконец, вы получите ответ в формате JSON:

1
{«ok»:true,»result»:true,»description»:»Webhook was set»}

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

Теперь нам нужно создать базу данных для наших таймеров. Что нам нужно хранить в нем? Когда пользователь подает команду на запуск секундомера, мы берем идентификатор чата и сохраняем строку с идентификатором чата и текущим временем Unix, которое представляет собой количество секунд между настоящим моментом и началом Unix Epoch, то есть 1 января 1970 года. в UTC. Следовательно, мы сохраним строку с идентификатором чата и целочисленной временной меткой текущего времени Unix.

Чтобы показать текущее время секундомера, мы получим сохраненную временную метку и сравним ее с текущей временной меткой. Разница будет текущим временем в секундах. Если пользователь остановит таймер, мы просто удалим строку с текущим идентификатором чата.

Итак, давайте создадим базу данных и таблицу для хранения информации о секундомере:

1
2
3
4
5
CREATE TABLE IF NOT EXISTS `stopwatch` (
  `chat_id` int(10) unsigned NOT NULL,
  `timestamp` int(10) unsigned NOT NULL,
  PRIMARY KEY (`chat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Наконец мы готовы начать кодирование. Давайте создадим класс для работы с базой данных в файле с именем stopwatch.php и начнем с конструктора, который установит две частные переменные, где мы будем хранить идентификатор чата и текущее соединение MySQL:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
class Stopwatch
{
    /** @var mysqli */
    private $mysqli;
    /** @var int */
    private $stopwatch_id;
    /**
     * Stopwatch constructor
     * @param mysqli $mysqli
     * @param $stopwatch_id
     */
    public function __construct(\mysqli $mysqli, $stopwatch_id)
    {
        $this->mysqli = $mysqli;
        $this->stopwatch_id = intval($stopwatch_id);
    }
}

Когда пользователь запускает таймер, мы получим текущее время Unix и сохраним его в строке с идентификатором чата, так что вот метод start() :

01
02
03
04
05
06
07
08
09
10
public function start()
{
    $timestamp = time();
    $query = «
        INSERT INTO `stopwatch` (`chat_id`, `timestamp`)
        VALUES (‘$this->stopwatch_id’, ‘$timestamp’)
        ON DUPLICATE KEY UPDATE timestamp = ‘$timestamp’
    «;
    return $this->mysqli->query($query);
}

Если таймер останавливается, нам нужно удалить строку из базы данных:

01
02
03
04
05
06
07
08
09
10
11
12
/**
 * Delete row with stopwatch id
 * @return bool|mysqli_result
 */
public function stop()
{
$query = «
    DELETE FROM `stopwatch`
    WHERE `chat_id` = $this->stopwatch_id
    «;
    return $this->mysqli->query($query);
}

А теперь для основной части класса. Когда пользователь запрашивает статус таймера, нам нужно найти строку с секундомером из текущего разговора и вычислить разницу в секундах между сохраненным временем Unix и текущим временем. К счастью, время Unix является целым числом, поэтому мы можем просто вычесть одно значение из другого. Чтобы отформатировать полученное значение как время, мы будем использовать функцию gmdate .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
/**
 * Find row with stopwatch id and return difference in seconds from saved Unix time and current time
 * @return string
 */
public function status()
{
    $query = «
        SELECT `timestamp` FROM `stopwatch`
        WHERE `chat_id` = $this->stopwatch_id
    «;
    $timestamp = $this->mysqli->query($query)->fetch_row();
    if (!empty($timestamp)) {
        return gmdate(«H:i:s», time() — reset($timestamp));
    }
}

Как вы можете видеть, если в базе данных нет значений, метод status() ничего не вернет, и мы обработаем нулевое значение, как остановленный таймер.

Существует множество библиотек PHP для работы с Telegram API, но, по крайней мере, на момент написания этой статьи, есть только одна, которая поддерживает как оболочку Telegram Bot API, так и отслеживание Botan. И это называется PHP Telegram Bot API.

Используйте Composer для установки этой библиотеки:

1
composer require telegram-bot/api

Если вы не заинтересованы в использовании аналитики, попробуйте Telegram Bot API PHP SDK с интеграцией Lavarel или PHP Telegram Bot .

А теперь начинается основная часть — мы создадим скрипт для обработки обратных вызовов из API Telegram Bot. Запустите файл с именем index.php и включите автозагрузку Composer и новый класс секундомера. Откройте соединение MySQL, создайте новый клиент Telegram API и запустите его:

01
02
03
04
05
06
07
08
09
10
11
12
13
require_once ‘vendor/autoload.php’;
require_once ‘stopwatch.php’;
 
// connect to database
$mysqli = new mysqli(‘database_host’, ‘database_user’, ‘database_password’, ‘database_name’);
if (!empty($mysqli->connect_errno)) {
    throw new \Exception($mysqli->connect_error, $mysqli->connect_errno);
}
 
// create a bot
$bot = new \TelegramBot\Api\Client(‘bot_token’, ‘botanio_token’);
// run, bot, run!
$bot->run();

Теперь нам нужно настроить бота, чтобы он отвечал на команду /start . Эта команда используется для запуска всех ботов Telegram, и пользователям будет показано наше приветственное сообщение при запуске первого чата.

1
2
3
4
$bot->command(‘start’, function ($message) use ($bot) {
    $answer = ‘Howdy!
    $bot->sendMessage($message->getChat()->getId(), $answer);
});

Здесь в методе command() мы определили закрытие для получения команды. Это закрытие получает идентификатор текущего чата и отправляет приветственное сообщение. Кроме того, все зарегистрированные команды автоматически отслеживаются в качестве имени команды.

Чтобы запустить секундомер, мы определим команду /go :

1
2
3
4
5
$bot->command(‘go’, function ($message) use ($bot, $mysqli) {
    $stopwatch = new Stopwatch($mysqli, $message->getChat()->getId());
    $stopwatch->start();
    $bot->sendMessage($message->getChat()->getId(), ‘Stopwatch started. Go!’);
});

Это создаст экземпляр класса Stopwatch и запустит таймер, вызывающий метод start() который мы уже определили.

Чтобы определить команду /status , нам нужно сделать то же самое. Просто вызовите метод status() и верните результат. Если метод вернул значение null, сообщите пользователю, что таймер не запущен.

1
2
3
4
5
6
7
8
$bot->command(‘status’, function ($message) use ($bot, $mysqli) {
    $stopwatch = new Stopwatch($mysqli, $message->getChat()->getId());
    $answer = $stopwatch->status();
    if (empty($answer)) {
        $answer = ‘Timer is not started.’;
    }
    $bot->sendMessage($message->getChat()->getId(), $answer);
});

И если пользователь останавливает таймер, нам нужно сначала получить статус, показать полученное время и остановить таймер с помощью метода stop() .

1
2
3
4
5
6
7
8
9
$bot->command(‘stop’, function ($message) use ($bot, $mysqli) {
    $stopwatch = new Stopwatch($mysqli, $message->getChat()->getId());
    $answer = $stopwatch->status();
    if (!empty($answer)) {
        $answer = ‘Your time is ‘ .
    }
    $stopwatch->stop();
    $bot->sendMessage($message->getChat()->getId(), $answer . ‘Stopwatch stopped. Enjoy your time!’);
});

Это оно! Теперь вы можете загрузить все файлы в каталог webhook и протестировать своего бота.

Чтобы предложить пользователю, какие команды он может выполнять, мы можем добавить к сообщению клавиатуру. Наш секундомер может быть запущен или остановлен, и для каждого состояния будет два. Чтобы показать клавиатуру пользователю, нам просто нужно расширить метод sendMessage() :

1
2
3
4
$keyboard = new \TelegramBot\Api\Types\ReplyKeyboardMarkup([[‘/go’, ‘/status’]], null, true);
 
$bot->sendMessage($message->getChat()->getId(), $answer, false, null, null, $keyboards);
});

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

Итак, теперь у нас есть работающий бот, и мы хотим показать его миру. Лучший способ — зарегистрировать бота в каталоге ботов. На данный момент у Telegram нет такого официального каталога, но есть несколько неофициальных, самый большой из которых — Storebot.me , где уже зарегистрированы тысячи ботов.

И есть … бот для регистрации вашего бота в бот-магазине! Добавьте @storebot в свой список контактов, введите команду /add и следуйте инструкциям. Вам будет предложено ввести имя пользователя, имя и описание бота, выбрать одну из стандартных категорий и подтвердить принадлежность бота, отправив его токен.

Через некоторое время ваш бот пройдет процесс отправки и появится в чартах Storebot. Теперь вы и ваши пользователи можете голосовать, находить и оценивать своего бота в магазине ботинок, чтобы помочь ему подняться на вершину графика.

Мы прошли большой путь от создания детского бота до регистрации его в магазине, чтобы быть доступными для реальных пользователей. Как вы можете видеть, существует множество инструментов, которые могут упростить вашу жизнь с созданием и распространением вашего бота, и вам не нужно много кода для запуска простого бота. Теперь вы готовы сделать свой собственный!

Если у вас есть какие-либо вопросы, не стесняйтесь задавать вопросы в комментариях к статье.