Сегодня разберемся, как написать своего простейшего телеграм бота, который будет выполнять простейшие команды пользователя в режиме чате/диалога. “Пишем боту команду, получаем ответ.”

/**/

Материалы по теме ботов в php

Смотрим , что есть в интернете по теме (на самом деле, примеров и бибилиотек доступно много).

  1. Хороший простейший пример: Пишем простого чат-бота для Telegram на PHP https://habr.com/ru/company/netologyru/blog/326174/

  2. Пишем бота Telegram на PHP https://code.tutsplus.com/ru/articles/how-to-start-a-telegram-bot-with-php—cms-26329

  3. Библиотеки от Телеграм: https://core.telegram.org/bots/samples

Справочники по работе с API

Предварительно: настройки ssl на сервере

Для работы телеграм ботов, на сайте д.б. настроено ssl/https соединение, для чего нужно установить ssl сертификат. Разбираемся как это сделать в моей отдельной заметке.

(звезда) Или просто ставим ssl в контрольной панели вашего хостинг- провайдера, например, инструкция для Masterhost: https://masterhost.ru/support/faq/ssl/install/


Создаем свой бот (по готовому примеру)

Начнем с примера (1) от Нетологии из cсылок выше (возьмем его за основу, но адаптируем под себя)

Создаем бота в Телеграм

Регистрация проходит в 5 простых этапов:

Открываете чат с @BotFather;

Вводите или выбираете из списка команду /newbot;

Отправляете желаемое название для бота, например:

MishaikonBot

Пишете юзернейм бота, по которому его будут находить через поиск. Обязательно на конце вашего юзернейма должно быть слово «bot» или «_bot». Например, NetologyRSSbot;

mishaikon_bot

По желанию можно сразу настроить полное или краткое описание, список команд и аватарку.

Пишем код

Что наш бот будет уметь

Пусть меню будет таким:

Выберите нужную команду:

/start — приветствие

/help — помощь

/about — обо мне

/soc — мои сайты и соцсети (список)

/news — последние посты из моего блога

То есть бот будет уметь показывать заданный текст и читать RSS ленту блога, выводя последние записи оттуда (заголовки со ссылками).

Создаем проект

(звезда) советую все делать в PhpStorm

# create prj dir
mkdir chatbot && cd chatbot

# create bot file
cat mishaikon_bot.php
<вставляем сюда исходники, указанные ниже>

# setup telegram library
composer require irazasyed/telegram-bot-sdk

Библиотека с зависимостями поставилась:

Исходники кода

Основной файл с логикой бота:

<?php

/**
 * Mishaikon news bot
 * @see https://habr.com/ru/company/netologyru/blog/326174/
 */

ini_set("display_errors", 1);
error_reporting(E_ALL);

// Подключаем библиотеки
include('vendor/autoload.php');

use TelegramBotApi;
use TelegramBotObjectsMessage as MessageObject;

/**
 * Telegram message
 */
class TgMessage {

	private string $text;
	private int $chat_id;
	private string $fromUsername;

	/**
	 * @param array $params
	 */
	public function __construct(array $params) {
		// Текст сообщения
		$this->text = $params["text"];

		// Уникальный идентификатор чата
		$this->chat_id = $params["chat"]["id"];

		// message sender username
		$this->fromUsername = (isset($params["from"]["username"]) ? $params["from"]["username"] : '');
	}

	/**
	 * @return int
	 */
	public function getChatId() {
		return $this->chat_id;
	}

	public function getFromUserName() {
		return $this->fromUsername;
	}

	/**
	 * @return mixed|string
	 */
	public function getText() {
		return $this->text;
	}
}

/**
 * Bot @mishaikon_bot
 */
class MishaikonBot {

	private Api $tgApi;
	private array $config;
	private TgMessage $msg;

	/**
	 * Constructor
	 */
	public function __construct() {
		// config file
		$filename = basename(__FILE__);
		$filename = strtok($filename, ".") . ".ini";
		$this->config = parse_ini_file($filename, true);

		// Устанавливаем токен
		$this->tgApi = new Api($this->config['bot']['api_key']);
	}

	/**
	 * @return void
	 */
	public function setWebhook() {
		$url = $this->config['bot']['webhook_url'];
		echo "Setting webhook to '$url' ...";

		$result = $this->tgApi->setWebhook(['url' => $url]);
		echo "Result : ";
		var_dump($result);
	}

	/**
	 * Write to debug log
	 * @param $this- >msg_text
	 * @return bool
	 */
	public function writeLog($msg_text) {

		$filename = $this->config['common']['log_file'];

		$fo = fopen($filename, "a");
		if ($fo == false) {
			return false;
		}

		$res = fwrite($fo, $msg_text . "n");
		if ($res == false) {
			return false;
		}

		$res = fclose($fo);
		if ($res == false) {
			return false;
		}

		return true;
	}

	/**
	 * @param string $reply
	 * @return MessageObject

	 * @throws TelegramBotExceptionsTelegramSDKException
	 */
	public function sendMsg(string $reply): MessageObject {
		return $this->tgApi->sendMessage(['chat_id' => $this->msg->getChatId(), 'parse_mode' => 'HTML', 'disable_web_page_preview' => true, 'text' => $reply]);
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// ACTIONS

	/**
	 * Show social networks list
	 * @return bool
	 * @throws TelegramBotExceptionsTelegramSDKException
	 */
	private function actSoc(): bool {
		$reply ="<b>Мои блоги со статьями:</b> n" .
				"🌎 Основной блог (фото/видео/заметки): http://www.mishaikon.ru n" .
				"🌎 Живой Журнал (копия блога): https://mishaikon.livejournal.com/ n" .
				"🌎 Яндекс-дзен: https://zen.yandex.ru/user/13791326 n" .
			    "🌎 Блог о программировании и IT: http://www.nujensait.ru nn" .
				"<b>Все мои видео-ролики</b>: n" .
				"🎥 Ютуб: https://youtube.com/c/mishaikon n" .
				"🎥 ТикТок: https://www.tiktok.com/@mishaikon nn" .
				"<b>Мои основные соцсети:</b> n" .
				"📸 Вконтакте: https://vk.com/mishaikon n" .
				"📸 Телеграм канал: https://t.me/mishaikon_vlog n" .
				"📸 Инстаграм: http://instagram.com/mishaikon nn" .
				"<b>Мои доп. соцсети</b> (копии постов): n" .
				"🌎 Фейсбук: http://www.facebook.com/mishaikon n" .
				"🌎 Одноклассники: https://ok.ru/profile/90610013839 n" .
				"🌎 Твиттер: http://twitter.com/mishaikon n" .
				"🌎 Тамблр: https://mishaikon.tumblr.com/ n";

		$this->sendMsg($reply);

		return true;
	}

	/**
	 * Start action
	 * @return bool
	 * @throws TelegramBotExceptionsTelegramSDKException
	 */
	private function actStart(): bool {
		$name = $this->msg->getFromUsername();            // Юзернейм пользователя

		$reply = "Приветствую, {$name}! 🙋 n" .
				 "Меня зовут Михаил, и это мой бот-помощник, 🤖 который поможет узнать обо мне больше.";

		$this->sendMsg($reply);

		return $this->actHelp();
	}

	/**
	 * @return bool
	 * @throws TelegramBotExceptionsTelegramSDKException
	 */
	private function actHelp(): bool {
		$reply = "Выберите нужную команду: n" .
				"/start - приветствие n" .
				"/help - помощь n" .
				"/about - обо мне n" .
				"/soc - мои сайты и соцсети (список) n" .
				"/news - последние посты из моего блога www.mishaikon.run";

		$this->sendMsg($reply);

		return true;
	}

	/**
	 * About me (info)
	 * @return bool
	 * @throws TelegramBotExceptionsTelegramSDKException
	 */
	private function actAbout(): bool {
		$years_birth = floor((time() - strtotime($this->config['me']['birth_date'])) / (3600 * 24 * 365) );
		$years_in_msk = floor((time() - strtotime($this->config['me']['in_msk_date'])) / (3600 * 24 * 365) );
		$reply = "👋 Я Михаил. Рад знакомству ) n".
				 "Мне {$years_birth} лет. n".
			     "👶 Родился в Челябинске. n".
				 "🏢 Живу и работаю в Москве, последние {$years_in_msk} лет. n".
			     "💻 Работаю веб-программистом. n".
			     "🌎 Мой технический блог по IT: www.nujensait.ru n".
				 "✈ Люблю путешествия, спорт, блоггинг (как хобби). n".
			     "📝 Мой блог об активном отдыхе и тревеле: www.mishaikon.ru n".
				 "✍ Также пишу заметки о жизни в соцсетях, их список тут: /soc n".
				 //"Почитать мои заметки вы можете здесь, набрав команду /blog n".
				 //"Вы можете написать мне сообщение выбрав команду /msg n".
				 "🙋 Будем знакомы )";

		$this->sendMsg($reply);

		return true;
	}

	/**
	 * Show last news list
	 * @return bool
	 * @throws TelegramBotExceptionsTelegramSDKException
	 */
	private function actNews(): bool {
		$html = simplexml_load_file('http://mishaikon.ru/rss');
		$cnt = 0;
		$reply = "";
		foreach ($html->channel->item as $item) {
			$reply .= "⦿ <b>" . $item->title . "</b>" .
				" <a href='" . $item->link . "'>xE2x9ExA1</a>nn";
			$cnt++;
			if ($cnt > $this->config['news']['posts_limit']) {
				break;
			}
		}

		$this->sendMsg($reply);

		return true;
	}

	/**
	 * Default messagges handler
	 * @return bool
	 * @throws TelegramBotExceptionsTelegramSDKException
	 */
	private function actDefault(): bool {
		if(!$this->msg->getText()) {
			$reply = "Отправьте сообщение.";
		} else if (substr($this->msg->getText(), 0, 1) === '/') {
			$reply = "Неизвестная команда: "<b>" . $this->msg->getText() . "</b>"";
		} else {
			return $this->actHelp();
		}

		$this->sendMsg($reply);

		return true;
	}

	/**
	 * @return bool
	 */
	private function actMenu() : bool {
		//$keyboard = [["/blog"], ["/help"]]; 						// Клавиатура
		//$reply = "Выберите действие:";
		//$reply_markup = $this->tgApi->replyKeyboardMarkup(['keyboard' => $keyboard, 'resize_keyboard' => true, 'one_time_keyboard' => false]);
		//$this->tgApi->sendMessage(['chat_id' => $chat_id, 'text' => $reply, 'reply_markup' => $reply_markup]);

		return true;
	}

	/**
	 * Handle message from telegram
	 * @return bool
	 * @throws TelegramBotExceptionsTelegramSDKException
	 */
	public function getMessage(): bool {

		$input = file_get_contents('php://input');
		$requestBody = (array)json_decode($input, true);

		if (!isset($requestBody['message'])) {
			echo "Error: Message body is empty";
			return false;
		}

		// Передаем в переменную $result полную информацию о сообщении пользователя
		$result = $this->tgApi->getWebhookUpdates();

		$msg = new TgMessage($result["message"]);
		$this->msg = $msg;

		switch ($this->msg->getText()) {

			case "/menu":
				return $this->actMenu();

			case "/start":
				return $this->actStart();

			case "/about":
				return $this->actAbout();

			case "/help":
				return $this->actHelp();

			case "/soc":
				return $this->actSoc();

			case "/news":
				return $this->actNews();

			default:
				return $this->actDefault();
		}    // eof switch
	}
}

$bot = new MishaikonBot();

$action = (isset($_GET['action']) ? $_GET['action'] : '');

switch ($action) {
	case 'webhook':
		$bot->setWebhook();
		break;
	case 'message':
		$bot->getMessage();
		break;
	case 'test':
		print "Testing ...n";
		print "Write to log ...n";
		$res = $bot->writeLog("Test");
		echo "Result: ";
		var_dump($res);
		break;
	default:
		echo "Unknown action: " . $action;
		break;
}

Все настройки вынесем в отдельный конфиг файл — mishaikon_bot.ini

(правим под себя все)

[common]
log_file = 'mishaikon_bot.log'

[bot]
; токен, полученный у @BotFather
api_key = '726880...................K4wU'
bot_name = 'mishaikon_bot'
webhook_url = 'https://XXXX.ru/bots/mishaikon_bot.php?action=message'

[news]
posts_limit = 8

[me]
birth_date = "1996-05-26"
in_msk_date = "2002-05-17"

Заливаем исходники на сервер

(звезда) В нашем случае, исходники разместим на своем домене, тут:

https://XXXXX.ru/bots/

Заливаем сюда в папку /bots через sftp файл mishaikon_bot.php

Привязываем вебхук

https://api.telegram.org/52255........luU?url=https://XXXXXX.ru/bots/mishaikon_bot.php?action=message

Или через консоль (то же самое):

https://XXXXXX.ru/bots/mishaikon_bot.php?action=webhook

Проверяем что все работает

Открываем диалог с ботом : https://t.me/mishaikon_bot

Пишем команды:


Заключение

Остались вопросы? Пишите в комментариях )

Tags

Нет комментариев

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.