Пишем простого чат-бота для Telegram на PHP

2019-08-31

Представляю Вашему вниманию практические примеры по теме, как создать Telegram бот на Python3 с использованием библиотеки pyTelegramBotAPI. Тут я не вижу смысла рассказывать о том, как использовать Bot Father, так как, скорее всего это знают все, либо инфы в инете полно. Минимум что будет из банальных примеров — это обработка таких команд, как «/start» и «/help» либо любой бот начинается именно с этого + это будет полезно, для тех кто только начинает свой путь в создании ботов Telegram.

План действий в рамках этой статьи такой. Но она будет дополнятся, так как данную статью я буду использовать для себя в качестве справки… По этому можете добавить страницу в закладки.

  1. Подготовка — Создаём config.py и используем Proxy.
  2. Обработка команд «/start» и «/help».
  3. Обработка простых сообщений. Отправка и получение.
  4. Как скачать и отправить стикер пользователю из бота.
  5. Как отправить и получить документ, аудио, видео и.т.д
  6. Разбираемся с Emoji, как получить код смайла для отправки в сообщении.
  7. Получаем информацию о пользователе, который запустил бота.

Подготовка — Создаём config.py и используем Proxy.

Файл config.py понадобится нам для хранения Токена бота и proxy (Если используете). Сложного тут нет ничего, обычный файл с двумя переменными, которые мы будет использовать в основном файле проекта.

Так просто выглядит файл config.py который нужно импортировать в основном файле проекта, созданием которого мы сейчас займемся. Я его так и назову «telegram_bot.py»

Практически Telegram бот на Python уже готов к работе и его можно запустить, если нет ошибок то бот работает. Но есть одна проблема. Бот работает через прокси, а библиотека request, которая нам нужна для загрузки файлов от пользователя, в данном случаи не использует прокси, по этому скачивать файлы не получиться… Это дело можно исправить, но лучше использовать VPN а от proxy отказаться.

В дальнейшем будем считать, что у нас настроен VPN ну или бот пишется непосредственно на сервере))) Теперь когда с подключением разобрались, пришло время научить бота совершать какие либо действия.

Обработка команд «/start» и «/help».

Библиотека «pyTelegramBotAPI» использует декораторы, это очень удобно и практично. Посмотрим как это работает на примере обработки команд «/start» и «/help».

Если пользователь Вашего бота отправить одну из команд start или help то сработает функция «welcome()» (Название функции может быть произвольным) главное что бы она принимала обязательный параметр «message» в котором содержится много полезной информации.

А вот пример как работают декораторы. Мы можем обработать команды в разных функциях.

Все получается аккуратно и логично, запутаться что и где уже стало сложнее, а значит разработка бота сводится не к рутине а к удовольствию =)

Обработка простых сообщений. Отправка и получение.

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

Типов сообщений в pyTelegramBotAPI достаточно. Некоторые из них для примера «text, audio, document» и.т.д. Рассмотрим пример

Так же можно записать следующим образом @bot.message_handler(content_types=[«text», «document», «audio»]) Надеюсь с этим все понятно, и работа декораторов Вам понятна.

Как получить простое сообщение от пользователя.

Ранее я уже сказал что в «message» много интересного. Там же и находится сообщение которое напечатал пользователь боту. Прочитать его можно так.

В консоль будет выведено сообщение от пользователя.

Как отправить простое сообщение от пользователя.

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

Вызываем метод «send_message» и передаём ему собственно ID и текст сообщение. В данном примере происходит следующие: Если пользователь напишет «hello» то бот ему ответит «И тебе hello»

Как скачать и отправить стикер пользователю из Telegram бота

Думаю это будет интересный пример, сейчас мы научимся отправлять Стикеры из telegram бот на python3. Для того что бы отправить стикер из бота, нам нужно узнать ID нужного нам стикера. Сделать это просто, отправьте любой стикер боту «@StickerID_Bot» и он в ответ вернёт Вам ID файла.

Как отправить Стикер

Если пользователь боту пришлёт слово «sticker» то в ответ мы отправим ему свой стикер. За место send_message вызывается метод send_sticker также передаётся id и за место текста отправляется ID стикера. Все просто — стикер отправлен))

Как получить Стикер (Скачать на локальную машину)

Давайте скачаем на локальную машину файл стикера, который прислал пользователь боту.

Собственно опять «message»! Пользователь отправляет нам стикер. Находим ID Стикера и отдаём его методу «get_file» что бы получить путь до файла на сервере телеграмма. А дальше скачаем файл в папку «stickers» которую нужно создать в том каталоге, где находится весь проект бота.

Как отправить и получить документ, аудио, видео, фото и.т.д

Продолжаем пилить telegram бот на python3 и на простом примере разберёмся, как отправлять файлы пользователям telegram бота.

Как отправить файл пользователю бота

Отправляем пользователю фотографию

За это отвечает метод «send_photo» Аналогично поступим и с другими типами файлов. Например нам нужно отправить документ «file.txt»

Отправляем пользователю документ

Тут мы уже используем метод «send_document» аналогично поступаем с другими типами файлов аудио, видео и прочие.

Как получить файл от пользователя

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

Получим от пользователя музыку

Точно таким-же способом можно получить любой тип файла от пользователей и создать Telegram бот на Python для конвертации файлов или у кого на что фантазии хватает))

2019-08-31

  • Tutorial

Шукюров Заур, разработчик @KinomanBot и @GaidarForum_bot, написал руководство по созданию простого чат-бота на PHP. 24 июня 2015 года разработчики Telegram открыли платформу для создания ботов (программ, которые выполняют определенные действия по заданному алгоритму). За полтора года работы платформы набралось много интересных чат-ботов, решающих множество проблем и позволяющих с пользой провести время в мессенджере.1c54f0445bdf4c9e8b9152d44ba018ea.jpg

Шаг 1: регистрация бота у @BotFather

Прежде чем начать писать код, нового бота нужно зарегистрировать у «папы всех ботов» — @BotFather, чтобы получить токен (ключ) для работы с Telegram API. Регистрация проходит в 5 простых этапов: 1) Открываете чат с @BotFather; 2) Вводите или выбираете из списка команду /newbot; 3) Отправляете желаемое название для бота; 4) Пишете юзернейм бота, по которому его будут находить через поиск. Обязательно на конце вашего юзернейма должно быть слово «bot» или «_bot». Например, NetologyRSSbot; 5) По желанию можно сразу настроить полное или краткое описание, список команд и аватарку.5b740f4b03044274a3949b129d0b9635.png По итогу регистрации получаем наш токен — 375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s. Будьте осторожны: никогда и никому не показывайте токен, иначе ваш бот может быть скомпрометирован. Если по несчастливой случайности кто-то нехороший все-таки узнал ваш токен, то заменить его можно всё в том же @BotFather, нажав на кнопку «Revoke current token» в разделе «API Token».

Шаг 2: выбираем способ обработки запросов

Исходя из официальной документации, Telegram API основан на простых HTTP-запросах. Существует всего два различных способа обрабатывать запросы, которые пользователи будут посылать боту: 1) проверять «вручную», используя «Long Polling»; 2) доверить всё Telegram, поставив «Webhook». В этом случае любой запрос от пользователя Telegram сам будет посылать нам на сервер. Мы остановимся на втором варианте, но у него есть ограничение: у вас на сайте обязательно должен быть установлен SSL-сертификат, чтобы все запросы проходили через безопасный протокол HTTPS. Самоподписанные и бесплатные сертификаты «Let’s Encrypt», которые поддерживает большинство хостингов, также подходят. Пример настройки самоподписанного сертификата из официальной документации Telegram.

Шаг 3: пишем код

Писать код бота будем на PHP, но чтобы не изобретать заново колесо, воспользуемся уже готовой и очень удобной библиотекой. Перво-наперво привязываем через метод SetWebhook бота к нашему файлу-обработчику. Сделать это можно при помощи библиотеки, но есть вариант быстрее и проще – это построить вот такую ссылку:https:// api. telegram. org/bot375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s/setWebhook?url=https:// yoursitehere .ru/directory/bot.php, где375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s — это наш токен,https:// yousitehere. ru/directory/bot.php — ссылка на файл-обработчик на нашем сайте. Открыв в браузере эту ссылку, должен прийти JSON-ответ со значением «Webhook was set», что будет означать, что вебхук установлен, и теперь все запросы от пользователей будут присылаться по адресу файла-обработчика. Переходим к самому главному — обработке этих самых запросов и написанию функционала бота. Ниже представлен полный листинг файла-обработчика:

     include('vendor/autoload.php'); //Подключаем библиотеку     use TelegramBotApi;       $telegram = new Api('375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s'); //Устанавливаем токен, полученный у BotFather     $result = $telegram -> getWebhookUpdates(); //Передаем в переменную $result полную информацию о сообщении пользователя          $text = $result["message"]["text"]; //Текст сообщения     $chat_id = $result["message"]["chat"]["id"]; //Уникальный идентификатор пользователя     $name = $result["message"]["from"]["username"]; //Юзернейм пользователя     $keyboard = [["Последние статьи"],["Картинка"],["Гифка"]]; //Клавиатура      if($text){          if ($text == "/start") {             $reply = "Добро пожаловать в бота!";             $reply_markup = $telegram->replyKeyboardMarkup([ 'keyboard' => $keyboard, 'resize_keyboard' => true, 'one_time_keyboard' => false ]);             $telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => $reply, 'reply_markup' => $reply_markup ]);         }elseif ($text == "/help") {             $reply = "Информация с помощью.";             $telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => $reply ]);         }elseif ($text == "Картинка") {             $url = "https://68.media.tumblr.com/6d830b4f2c455f9cb6cd4ebe5011d2b8/tumblr_oj49kevkUz1v4bb1no1_500.jpg";             $telegram->sendPhoto([ 'chat_id' => $chat_id, 'photo' => $url, 'caption' => "Описание." ]);         }elseif ($text == "Гифка") {             $url = "https://68.media.tumblr.com/bd08f2aa85a6eb8b7a9f4b07c0807d71/tumblr_ofrc94sG1e1sjmm5ao1_400.gif";             $telegram->sendDocument([ 'chat_id' => $chat_id, 'document' => $url, 'caption' => "Описание." ]);         }elseif ($text == "Последние статьи") {             $html=simplexml_load_file('http://netology.ru/blog/rss.xml');             foreach ($html->channel->item as $item) {      $reply .= "xE2x9ExA1 ".$item->title." (link."'>читать)n";         }             $telegram->sendMessage([ 'chat_id' => $chat_id, 'parse_mode' => 'HTML', 'disable_web_page_preview' => true, 'text' => $reply ]);         }else{         $reply = "По запросу "".$text."" ничего не найдено.";         $telegram->sendMessage([ 'chat_id' => $chat_id, 'parse_mode'=> 'HTML', 'text' => $reply ]);         }     }else{     $telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => "Отправьте текстовое сообщение." ]);     } 

Разберем всё по порядку. 1. Сначала мы подключаем скачанную библиотеку, указав путь (лучше полный) до файла автозагрузчика.

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

2. Создаем экземпляр класса в переменной $telegram и передаем в него наш токен. В переменной $result получаем информацию о сообщении, которое пришлет нам Telegram.

$telegram = new Api('375466075:AAEARK0r2nXjB67JiB35JCXXhKEyT42Px8s'); //Устанавливаем токен, полученный у BotFather $result = $telegram -> getWebhookUpdates(); //Передаем в переменную $result полную информацию о сообщении пользователя

3. Затем определяем главные переменные: текстовое сообщение, уникальный идентификатор пользователя и его юзернейм. Если предстоит работа с БД, то не забывайте про фильтрацию (или лучше используйте PDO).

$text = $result["message"]["text"]; //Текст сообщения $chat_id = $result["message"]["chat"]["id"]; //Уникальный идентификатор пользователя $name = $result["message"]["from"]["username"]; //Юзернейм пользователя

4. Создаем нашу клавиатуру, состоящую из трех кнопок.

$keyboard = [["Последние статьи"],["Картинка"],["Гифка"]]; //Клавиатура

5. Теперь, когда мы обозначили все переменные, можно перейти к обработке полученного сообщения. Для этого можно использовать конструкцию switch-case либо if-else. Так как принципиальной разницы между ними нет, остановимся на втором варианте, как наиболее привычном. В самом начале проверяем, заполнена ли переменная $text и является ли сообщение пользователя текстовым.

if($text){          …          //код          ... }else{          $telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => "Отправьте текстовое сообщение." ]); }

Если нет, то отправляем пользователю с помощью метода sendMessage сообщение с просьбой ввести текстовое сообщение.6. Рассмотрим вариант, когда пользователь прислал сообщение с командами /start или /help

if ($text == "/start") {             $reply = "Добро пожаловать в бота!";             $reply_markup = $telegram->replyKeyboardMarkup([ 'keyboard' => $keyboard, 'resize_keyboard' => true, 'one_time_keyboard' => false ]);             $telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => $reply, 'reply_markup' => $reply_markup ]);  }elseif ($text == "/help") {             $reply = "Информация с помощью.";             $reply_markup = $telegram->replyKeyboardMarkup([ 'keyboard' => $keyboard, 'resize_keyboard' => true, 'one_time_keyboard' => false ]);             $telegram->sendMessage([ 'chat_id' => $chat_id, 'text' => $reply, 'reply_markup' => $reply_markup ]);   }

В этом случае помимо текста из переменной $reply будет подгружаться клавиатура, состоящая из трёх кнопок: «Последние статьи», «Картинка» и «Гифка». Реализуется это с помощью метода replyKeyboardMarkup, параметрами которого являются:

  • ‘keyboard’ => $keyboard, передаем нашу клавиатуру
  • ‘resize_keyboard’ => true, клавиатура будет сжата в размерах.
  • ‘one_time_keyboard’ => false, клавиатура не исчезнет после нажатия на какую-то кнопку.

7. После появления клавиатуры пользователь явно захочет попробовать потыкать на расположенные на ней кнопки, и вот что у нас «под капотом» в этом случае:

}elseif ($text == "Картинка") {             $url = "https://68.media.tumblr.com/6d830b4f2c455f9cb6cd4ebe5011d2b8/tumblr_oj49kevkUz1v4bb1no1_500.jpg";             $telegram->sendPhoto([ 'chat_id' => $chat_id, 'photo' => $url, 'caption' => "Описание." ]);         }elseif ($text == "Гифка") {             $url = "https://68.media.tumblr.com/bd08f2aa85a6eb8b7a9f4b07c0807d71/tumblr_ofrc94sG1e1sjmm5ao1_400.gif";             $telegram->sendDocument([ 'chat_id' => $chat_id, 'document' => $url, 'caption' => "Описание." ]);         }elseif ($text == "Последние статьи") {             $html=simplexml_load_file('http://netology.ru/blog/rss.xml');             foreach ($html->channel->item as $item) {      $reply .= "xE2x9ExA1 ".$item->title." (link."'>читать)n";             }             $telegram->sendMessage([ 'chat_id' => $chat_id, 'parse_mode' => 'HTML', 'disable_web_page_preview' => true, 'text' => $reply ]);         }

8. Для отправки картинки используется метод sendPhoto, для отправки гифки – sendDocument. В обоих случаях Telegram позволяет передавать прямую ссылку на файл, что безусловно очень удобно, но не так быстро, как если бы мы передавали file_id уже отправленной на сервера Telegram картинки или гифки.9. Для получения последних статей используется простой парсинг RSS ленты Нетологии при помощи встроенной в PHP функции simplexml_load_file. В параметрах метода sendMessage можно заметить два новых значения: 1) 'parse_mode' => 'HTML', чтобы в сообщение можно было вставить HTML-теги

, ,>, или 

2)

'disable_web_page_preview' => true

чтобы к сообщению со ссылкой не подгружалось превью.10. В качестве смайла (стрелка вправо) используются символы xE2x9ExA1. Список всех смайлов в таком виде можно найти на специальном сайте.11. После того, как вы протестируете бота и будете уверены в его работоспособности, можно отправлять его на всеобщее обозрение. Благодаря удобному API, боты Telegram могут стать хорошей платформой для автоматизации рутинных действий, настройки уведомлений, удобному и быстрому получению информации и созданию игр. Бесплатными площадками для продвижения могут послужить каталоги ботов Telegram Bot Store, TeleChappy или 50bots. А анализировать активность пользователей можно с помощью бесплатного инструмента для аналитики ботов от Яндекса — Botan.

От редакции

PHP — один из самых популярных языков программирования. Его легко изучать, с ним легко работать, у него мощное сообщество. 5 мая «Нетология» запускает курс «PHP/SQL: back-end разработка и базы данных», где ведущие программисты расскажут об управляющих конструкциях, циклах, функциях, о строках и массивах. Вы узнаете все про реляционные базы данных и язык запросов SQL, научитесь устанавливать и настраивать веб-сервер nginx и php, управлять базами данных различной сложности. Ждем вас!</pre>

Для применения кейса необходимы базовые знания работы в терминале любой операционной системы Linux, понимание того как настраиваются периодические задания с помощью планировщика. Так же, для запуска скриптов понадобится либо сервер (самый простой, виртуальный), либо аккаунт на хостинге, в котором позволено будет по cron’у запустить скрипт.

Автор прекрасно понимает, что таких каналов в Telegram уже огромное количество, и что они не особо-то и нужны, однако автору было нечего делать, не спалось и хотелось чем-то себя развлечь.

Итак, для организации самонаполняемого канала, нам нужно три вещи:

  1. Скрипт, которым мы получим список тематических ссылок с сайта stocksnap.io.
  2. Telegram бот, полученный от @BotFather и добавленный в наш канал.
  3. Скрипт, который будет постить в канал картинку через бота.

Получаем список ссылок.

Материал для публикации мы будем получать с сайта stocksnap.io, все изображения на этом сайте распространяются под лицензией CC0, а значит проблем с авторскими правами у нас не случится. Список ссылок на изображения в нужной категории мы получим с помощью скрипта, который через API сайта заберёт нужную информацию. Результатом работы скрипта будет файл, в котором будет список прямых ссылок на изображения.

Сам скрипт можно посмотреть здесь.

Запускается он вот так, с параметрами:

# ./downloader food 1

./downloader — имя скрипта.food — категория, из которой мы будем собирать изображения. Найти все доступные категории можно здесь https://stocksnap.io/popular1 — страница, с которой скрипт начнёт собирать информацию. На сайте организован постраничный вывод изображений. Как только пользователь докручивает колесо мыши до нижней части страницы, ему подгружается новая порция картинок. Каждая порция картинок, во внутренностях сайта описана на отдельной странице. Что бы не заморачивать себя и получить все изображения из категории здесь можно всегда использовать единичку.

В процессе работы, скрипт с помощью wget будет по API скачивать служебную информацию, затем из всех страниц со служебной информацией, будет сформирован файл, содержащий список ссылок с именем food.url.list. Этот файл будет использоваться нашим ботом для постинга изображений в канал. Так же, этот файл, при необходимости, можно использовать для скачивания всех изображений себе (для работы бота это не обязательно).

Краткое резюме — мы запускаем скрипт и когда он отработает, получаем файл со списком ссылок на изображения нужной нам категории.

Регистрируем бота в Telegram.

Добавляем себе контакт @BotFather, начинаем работу с ним. Заводим себе нового бота командой /newbot, вводим его имя, его логин и получаем токен (далее в статье НАШТОКЕН), который нужен для работы с ботом из скрипта для постинга. При необходимости, добавляем боту аватар, дополнительно настраиваем его, но это уже по желанию.

Когда бот будет готов, добавляем его в наш канал администратором. После того как бот будет добавлен в канал, узнаем ID канала, который нам так же потребуется для работы скрипта. ID узнаём следующим образом:

  1. После того как бот добавлен администратором, отправляем в канал любое сообщение.
  2. В браузере переходим по ссылке https://api.telegram.org/botНАШТОКЕН/getUpdates и видим текст, в котором находим кусок вида:
"chat":{"id":-1013332055484,

В данном случае, нужным нам ID канала будет -1013332055484 (именно так, со знаком минус).

Краткое резюме второго этапа — мы создали бота, получили его токен (НАШТОКЕН), добавили бота к себе в канал, узнали ID канала.

Постим изображения в канал с помощью бота.

Для постинга изображений мы будем использовать telegram bot api. Через бота, мы будем оформлять пост-картинку и отправлять его в канал с отключенным уведомлением. Такие запросы можно делать из браузера, но для скрипта мы используем wget (да, да, можно и curl, но я люблю wget) Вручную это выглядит примерно так (токен тут не существующий если что):

# wget "https://api.telegram.org/bot414612848:AAGs2pMUNCDIQIrHrABU8xYXGxXVzPcRSrI/sendPhoto?chat_id=-1013332055484&photo=https://d2lm6fxwu08ot6.cloudfront.net/img-thumbs/960w/6AE3CDF29F.jpg&caption=@superchannel&disable_notification=1"

Разберём что бы было понятно:

sendPhoto — отправляем изображение.chat_id=-1001132088554 — в наш канал.photo= — изображение берём по ссылке.caption= — добавляем текст к изображению.disable_notification= — отключаем уведомление для этого сообщения.

Если всё сделано верно, то наш бот, которого мы добавили в канал администратором, запостил изображение, с названием нашего канала в подписи к картинке. Теперь нам остаётся этот процесс автоматизировать.

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

У меня на сервере, создана следующая структура для работы этого скрипта:

В самом скрипте, используются следующие переменные:

botToken — полученный нами НАШТОКЕН.channelId — ID нашего канала.channelName — имя нашего канала.postImage — получение случайной ссылки из файла /opt/telegram/superchannel/food.url.list

Эти параметры вам нужно будет настроить в соответствии с вашим окружением и расположением файлов на сервере.

При запуске, скрипт выбирает случайный адрес изображения из файла food.url.list и отправляет в канал пост с ним. Из общего списка этот адрес удаляется, дабы избежать дублей в дальнейшем.

Скрипт не забываем сделать исполняемым:

# chmod +x /opt/telegram/superchannel/postbot

Резюмирую третью часть — у нас есть сервер, на котором в нужной нам директории лежит скрипт постинга и файл со ссылками. В скрипте верно прописаны токен, ID канала, название канала и путь до файла. При ручном вызове скрипта, бот в канале постит одну картинку:

# /opt/telegram/superchannel/postbot

Автоматизируем постинг в нужное нам время.

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

# crontab -e

В открывшемся редакторе (какой будет редактор зависит от настроек админа сервера) мы вводим, например такое задание:

00 08,13,18 * * * /opt/telegram/superchannel/postbot

Сохраняем изменения и выходим из редактора.

Текущее правило будет запускать наш скрипт каждый день в 08, 13 и 18 часов по серверному времени. В это время на канале будет публиковаться один пост-картинка.

Подходя к завершению и резюмируя всё.

Мы идём на сайт фотостока и выбираем там нужную категорию. С помощью скрипта-загрузчика мы получаем список адресов картинок нужной нам категории сайта stocksnap.io. Затем, скрипт-бот выбирает случайную ссылку на изображение и постит её в наш канал, в заданное планировщиком время. Всё происходит без нашего участия. Нам остаётся только заниматься раскруткой канала (если такие каналы сегодня имеет смысл раскручивать конечно).

Примеры созданных и работающих таким образом каналов:

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

Вот такой вот кейс. Пользуйтесь, если он покажется вам полезным.

@SysadminNotes | https://sysadmin.pm

Используемые источники:

  • https://winkomp.ru/telegram-bot-python-pytelegrambotapi
  • https://habr.com/ru/company/netologyru/blog/326174/
  • https://sysadmin.pm/telegram-bot-autopost/

Оцените статью
Рейтинг автора
5
Материал подготовил
Илья Коршунов
Наш эксперт
Написано статей
134
Добавить комментарий