Итак продолжим писать наш плагин для WooCommerce и Телеграм. В первой части мы написали каркас плагина, зарегистрировали его в списке плагинов и добавили в интеграции WooCommerce.
Создаем бота в Telegram.
Теперь давайте создадим нашего бота. Для этого необходимо в Telegram найти отца всех ботов @BotFather и дать ему команду /newbot.

Добавляем поля в наш плагин.
Примерно в таком ключе пройдет Ваше общение с @BotFather в результате которого Вы получите token. Теперь этот токен необходимо сохранить в нашем плагине. Этим токеном мы будем подписывать наши сообщения боту. Давайте добавим наше первое поле в настройку плагина. После добавления наш класс Telegram в файле includes/telegram.php будет выглядеть так :
public function __construct()
{
$this->id = "woo-telegram";
$this->method_title = "Телеграм бот для WooCommerce";
$this->method_description = "Плагин связывает WooCommerce c Telegram ботом.";
$this->init_form_fields();
$this->init_form_fields();
$this->token = $this->settings['token'];
add_action( "woocommerce_update_options_integration_" . $this->id, array( $this, "process_admin_options" ) );
}
public function init_form_fields(){
$this->form_fields = [
"token" => array(
"title" => "Токен Telegram",
"description" => "Введите token полученный от BotFather",
"type" => "text",
"desc_tip" => true,
"default" => get_option( "token" )
),
];
}
Мы добавили новый метод init_form_fileds в котором описали настройку необходимых нам полей , название, описание, тип, также добавили опцию по умолчанию . После того как мы сохраним наши настройки то заново зайдем на эту страницу и в это поле автоматически подставится сохраненное значение. Дальше мы определяем переменную token нашего класса Telegram и заполняем ее значением настройки ‘token’. После этого добавляем action «process_admin_options» который и сохранит все наши настройки в БД WooCommerce.
Теперь в Настройках WooCommerce у нас появилось новое поле Token которое мы можем заполнить и сохранить.

Пишем код плагина для связи с Telegram.
Давайте подумаем, что мы хотим получить от нашего бота ? Самое простое это получать уведомление когда кто-то из клиентов совершает заказ. Это и будет наше минимальное ТЗ.
Но сначала давайте подружим WooCommerce и Телеграм. Все общение с Телеграм может происходить двумя способами. 1) Мы сами запрашиваем обновления. 2) Телеграм присылает нам уведомления на указанный нами адрес. Мы выберем способ номер 2). Для этого у нашего сайта должен быть установлен SSL сертификат. Чтобы наш бот мог отправлять нам сообщения, нам надо получить ИД чата между телеграм ботом и нашим персональным telegram. Для этого мы будем отсылать нашему боту в телеграме команду вроде /key=ИД_юзера_на_сайте&auth=ХЭШ_для_защиты. Наш сайт будет принимать от бота ИД чата и прописывать его нужному юзеру.
Добавим в конструктор __construct() нашего класса вызов action, добавим сам метод WooTelegramResponse, пару вспомогательных методов и так же напишем метод отправки сообщений в Telegram.
add_action('woocommerce_api_woo-telegram',[$this,'WooTelegramResponse']); public function WooTelegramResponse() { global $woocommerce; $data = file_get_contents("php://input"); $logger = wc_get_logger(); try { $result = $this->decodePost($data); $userId = $this->parseText($result['text']); if (update_user_meta($userId, 'telegram', $result['chatId'])) { $text = 'Добро пожаловать в WooCommerce.' . PHP_EOL; $text .= 'На странице плагина Вы должны увидеть номер Вашего чата ' . $result['chatId'] . PHP_EOL; $text .= 'Спасибо !'; $this->sendMessageToTelegram($text, $result['chatId'], $this->token); } else { if ($chatId = get_user_meta($userId, 'telegram', true)) { $text = 'Вы уже зарегистрированы в WooCommerce.' . PHP_EOL; $text .= 'Спасибо за то, что Вы с нами'; $this->sendMessageToTelegram($text, $chatId, $this->token); } } } catch (Exception $e) { $logger->info(wc_print_r($e->getMessage(), true)); } } private function parseText(string $text) { $input = []; parse_str($text, $input); $userId = empty($input['key']) ? false : $input['key']; $hash = empty($input['auth']) ? false : $input['auth']; if ($userId && $hash && $hash == md5('telegram2019' . $userId)){ return $userId; } throw new Exception('Не найден пользователь или не совпал секрет !'); } private function decodePost(string $post): array { $data = json_decode($post, true); $text = empty($data['message']['text']) ? false : $data['message']['text']; $text = substr($text, 1); $chatId = empty($data['message']['chat']['id']) ? false : $data['message']['chat']['id']; if ($text && $chatId) { return [ 'text' => $text, 'chatId' => $chatId, ]; } throw new Exception('Не хватает аргументов text или chatId'); } public function sendMessageToTelegram( string $text, string $chatId, string $token ): void { $url = 'https://api.telegram.org/bot' . $token . '/sendMessage'; $args = [ 'timeout' => 5, 'blocking' => true, 'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'], 'body' => ['text' => $text, 'chat_id' => $chatId], ]; $response = wp_remote_post($url, $args); $logger = wc_get_logger(); if (is_wp_error($response)) { $error_message = $response->get_error_message(); $logger->info(wc_print_r($error_message, true)); } }
Добавив action woocommerce_api_woo-telegram мы тем самым задекларировали, что у нас по адресу https://наш_сайт.ru/?wc-api=woo-telegram будет находится наш обработчик WooTelegramResponse. Смысл этого обработчика в том, что он принимает данные с Telegram декодирует их, обрабатывает и записывает нужному юзеру ИД чата с Телеграм.
Добавляем необходимую информацию на страницу плагина.
Итак у нас готов обработчик, теперь надо сообщить Telegram куда он должен отсылать всю ту информацию которую он получит в чате. Но перед этим сделаем проверку на правильность введенного Токена. Переопределим встроенный метод validate_text_field и используем его для проверки нашего токена.
public function validate_text_field($key, $value) { if ($key == 'token') { if (!$this->checkToken($value)) { $this->add_error('Токен не существует'); } } return parent::validate_text_field($key, $value); }
Здесь мы смотрим на полученный ключ сравниваем его с тем что мы задали в методе init_form_fields и запускаем проверку с помощью метода checkToken, если метод вернет false то добавим ошибку в список ошибок и дальше отдадим управление родительскому методу. Опишем метод checkToken :
private function checkToken(string $token) { $url = 'https://api.telegram.org/bot' . $token . '/getMe'; $response = wp_remote_get($url); $body = wp_remote_retrieve_body($response); if (!empty($body)) { try { $data = json_decode($body, true); if (!empty($data['result']['username'])) { return true; } } catch (Exception $e) { } } return false; }
В Telegram есть простой метод getMe который возвращает данные бота или 404 ошибку если бота с таким токеном не существует. Если мы получаем от Телеграм username в данных, то считаем что проверка прошла и возвращаем true, во всех остальных случаях возвращаем false.
Теперь у нас есть валидация Token напишем метод setTelegramWebhook который указывает Telegram куда отсылать webhook.
private function setTelegramWebhook() { $logger = wc_get_logger(); $url = 'https://api.telegram.org/bot' . $this->token . '/setWebhook'; $logger->info(wc_print_r($url, true)); $args = [ 'timeout' => 5, 'redirection' => 1, 'httpversion' => '1.0', 'blocking' => true, 'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'], 'body' => ['url' => home_url('/?wc-api=woo-telegram')], ]; $response = wp_remote_post($url, $args); if (is_wp_error($response)) { $error_message = $response->get_error_message(); $logger->info(wc_print_r($error_message, true)); } }
Здесь мы подключаем встроенный в WooCommerce логер, чтобы фиксировать ошибки в логах. Телеграм метод setWebhook принимает несколько аргументов, но нам нужен только обязательный url в который мы прописываем наш адрес.
Проведем еще немного рефакторинга и добавим проверок в результате которых наш код примет примерно такой вид.
<?php if (!defined('ABSPATH')) { exit; } class Telegram extends WC_Integration { const API_TELEGRAM = 'https://api.telegram.org/bot'; public $registerWebhook; public $token; public $chatId; public $userId; public function __construct() { $current_user = wp_get_current_user(); $this->userId = $current_user->ID; $this->id = "woo-telegram"; $this->method_title = "Телеграм бот для WooCommerce"; $this->method_description = "Плагин связывает WooCommerce c Telegram ботом."; $this->init_form_fields(); $this->init_settings(); $this->token = $this->settings['token']; $this->chatId = get_user_meta($this->userId, 'telegram', true); $this->registerWebhook = $this->checkExistsWebhook($this->token); add_action('woocommerce_api_woo-telegram', [$this, 'WooTelegramResponse']); add_action("woocommerce_update_options_integration_" . $this->id, [$this, "process_admin_options"]); } public function init_form_fields() { $this->form_fields = [ "token" => [ "title" => "Токен Telegram", "description" => "Введите token полученный от BotFather", "type" => "text", "class" => "tm-token", "desc_tip" => true, "default" => get_option("token"), ], ]; } public function process_admin_options() { $result = parent::process_admin_options(); $this->token = $this->settings['token']; $this->setTelegramWebhook(); $this->registerWebhook = $this->checkExistsWebhook($this->token); return $result; } function admin_options() { $hash = md5('telegram2019' . $this->userId); echo '<table class="form-table">'; echo $this->generate_settings_html($this->form_fields, false); echo '</table>'; if (!$this->registerWebhook) { echo '<a href="#" class="button-secondary" id="webhook">WebHook не зарегистрирован</a>'; } if (empty($this->chatId)) { echo "<p> Найдите нашего бота @woo_telegram_bot нажмите Начать и напишите ему команду /key=$this->userId&auth=$hash долждитесь ответа бота и перегрузите эту страницу </p>"; } else { echo "<p>Номер telegram чата : $this->chatId </p>"; } $this->display_errors(); } public function validate_text_field($key, $value) { if ($key == 'token') { if (!$this->checkToken($value)) { $this->add_error('Токен не существует'); } } return parent::validate_text_field($key, $value); } private function setTelegramWebhook() { $logger = wc_get_logger(); $url = self::API_TELEGRAM . $this->token . '/setWebhook'; $logger->info(wc_print_r($url, true)); $args = [ 'timeout' => 5, 'redirection' => 1, 'httpversion' => '1.0', 'blocking' => true, 'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'], 'body' => ['url' => home_url('/?wc-api=woo-telegram')], ]; $response = wp_remote_post($url, $args); if (is_wp_error($response)) { $error_message = $response->get_error_message(); $logger->info(wc_print_r($error_message, true)); } } private function checkExistsWebhook(string $token) { $logger = wc_get_logger(); $url = self::API_TELEGRAM . $token . '/getWebhookInfo'; $logger->info(wc_print_r($url, true)); $response = wp_remote_get($url); $body = wp_remote_retrieve_body($response); if (!empty($body)) { try { $data = json_decode($body, true); if (!empty($data['result']['url'])) { return true; } } catch (Exception $e) { } } return false; } private function checkToken(string $token) { $url = self::API_TELEGRAM . $token . '/getMe'; $response = wp_remote_get($url); $body = wp_remote_retrieve_body($response); if (!empty($body)) { try { $data = json_decode($body, true); if (!empty($data['result']['username'])) { return true; } } catch (Exception $e) { } } return false; } public function WooTelegramResponse() { global $woocommerce; $data = file_get_contents("php://input"); $logger = wc_get_logger(); try { $result = $this->decodePost($data); $userId = $this->parseText($result['text']); if (update_user_meta($userId, 'telegram', $result['chatId'])) { $eol = PHP_EOL; $text = 'Добро пожаловать в WooCommerce.' . $eol; $text .= 'На странице плагина Вы должны увидеть номер Вашего чата ' . $result['chatId'] . $eol; $text .= 'Спасибо !'; $this->sendMessageToTelegram($text, $result['chatId'], $this->token); } else { if ($chatId = get_user_meta($userId, 'telegram', true)) { $text = 'Вы уже зарегистрированы в WooCommerce.' . PHP_EOL; $text .= 'Спасибо за то, что Вы с нами'; $this->sendMessageToTelegram($text, $chatId, $this->token); } } } catch (Exception $e) { $logger->info(wc_print_r($e->getMessage(), true)); } } /** * @param string $text * * @return bool|mixed * @throws \Exception */ private function parseText(string $text) { $input = []; parse_str($text, $input); $userId = empty($input['key']) ? false : $input['key']; $hash = empty($input['auth']) ? false : $input['auth']; if ($userId && $hash && $hash == md5('telegram2019' . $userId)) { return $userId; } throw new Exception('Не найден пользователь или не совпал секрет !'); } /** * @param string $post * * @return array * @throws \Exception */ private function decodePost(string $post): array { $data = json_decode($post, true); $text = empty($data['message']['text']) ? false : $data['message']['text']; $text = substr($text, 1); $chatId = empty($data['message']['chat']['id']) ? false : $data['message']['chat']['id']; if ($text && $chatId) { return [ 'text' => $text, 'chatId' => $chatId, ]; } throw new Exception('Не хватает аргументов text или chatId'); } public function sendMessageToTelegram( string $text, string $chatId, string $token ): void { $url = self::API_TELEGRAM . $token . '/sendMessage'; $args = [ 'timeout' => 5, 'redirection' => 1, 'httpversion' => '1.0', 'blocking' => true, 'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'], 'body' => ['text' => $text, 'chat_id' => $chatId], ]; $response = wp_remote_post($url, $args); $logger = wc_get_logger(); if (is_wp_error($response)) { $error_message = $response->get_error_message(); $logger->info(wc_print_r($error_message, true)); } } }
В итоге сейчас любой Админ или Менеджер магазина , может зайти на страницу плагина получить свой код регистрации в нашем телеграм боте. В следующей части интеграции WooCommerce и Телеграм мы напишем с Вами реализацию отправки заказа в нашему телеграм боту для отправки всем зарегистрированным пользователям.
Здравстуйте ! Подскажите , откуда брать id $this->chatId = get_user_meta($this->userId, ‘telegram’, true); для этой строки ?
ни откуда не надо брать.
в методе public function WooTelegramResponse()
мы записываем update_user_meta($userId, ‘telegram’, $result[‘chatId’]) нужную нам информацию в БД
Это все огонь. А где скачать можно уже готовый к работе плагин. 😇
К сожалению готового нету )))
Добавил готовый код плагина во все части описания.
[…] писать Telegram bot для Woocommerce. В первой и второй части мы сделали каркас плагина, зарегистрировали […]