Содержание
29 Ноября, 2016 19 мин чтения
Вступление
Заикнулся в присутствии нового коллеги о своем блоге, первый его вопрос был “что за блог?”, а второй “а телеграм канал у тебя есть?”. Поймал себя на мысли неужели я стал ретроградом. Когда начался хайп вокруг влогов и Youtube каналов я остался верен теплому ламповому формату текстовых статей, так и сейчас, считаю что нет необходимости иметь свой Telegram канал, но задача меня заинтересовала. Вокруг Telegram ботов сейчас много шумихи, как завести своего бота или канал написано в официальной документации. Не хотелось делать что-то надуманное, только ради “попробовать” и я решил что более менее полезной задачей будет уведомление о новых статьях в этом же блоге и только потом понял, что в принципе, мою реализацию можно использовать для любой RSS
ленты c небольшими правками под себя.
Наивная реализация или тупой бот
Первое что нужно сделать это создать бота и получить API токен.
Недолго думая, я взял самую популярную либу-обертку для ботов Telegram – gem telegram-bot-ruby и наваял следующий код:
Что же тут происходит? Все очень просто, вот здесь:
подключаем библиотеки для работы с RSS и Telegram, а вот здесь:
сетим в переменную с именем token
наш API токен, который получили от @BotFather
.
Здесь я использую переменные окружения (Environment variables), чтобы это работало, перед запуском скрипта нужно выполнить в командной строке
export TELEGRAM_BOT_API_KEY=123456789
, где вместо 123456789 нужно вставить собственно токен. Использование переменных окружения один из двенадцати факторов приложения согласно – Adam Wiggins
Затем, с помощью строчки:
сохраняем в объект rss
всю RSS
ленту моего блога (я точно знаю что у меня там только 10 записей, поэтому не боюсь никаких переполнений или задержек).
После этого мы создаем бот клиента, обходим каждый item
внутри rss
и отправляем его ссылку в канал Telegram. Таким образом, при каждом запуске скрипта в канал будет отправляться 10 сообщений с одинаковыми ссылками. Я использую бота, хотя для такого же функционала, например, в Slack я бы использовал Incoming Hooks.
Кстати, чтобы бот мог слать сообщения в канал, его нужно добавить в администраторы этого канала.
На этом этапе я понял что нужно хранить состояние постов, т.е. запоминать информацию какие записи уже отправлены в канал, а какие еще нет.
Используем простую БД или чуть более умный бот
На самом деле новая версия бота растянулась на 55 строк кода, и вот он целиком:
Опять же приведу разбор этого кода по кусочкам далее по тексту.
Я использую теже две библиотеки что и раньше rss
и telegram
, затем подключаю sdbm
это встроенная либа Ruby, которая предоставляет простое хранилище типа ключ-значение (key-value), в качестве ключей или значений могут выступать только строки. Далее я подключаю json
, чтобы легко кодировать объекты в строки и декодировать обратно. И еще одной библиотекой является logger
, который предоставляет простой способ для отладки.
Сперва делаем простые вещи, создаем объект для логирования и сетим переменную окружения.
Устанавливаем переменную окружения в этот раз мы чуть сложнее. Вначале мы проверяем что ENV пустая и если это так то выбрасываем ошибку через логгер и выходим из программы c использованием
exit
кода 1, в обратном случае, если переменная не пустая, записываем её значение в переменную, которую мы будем использовать в дальнейшем.
Парсинг RSS
ленты происходит таким же образом как и ранее.
Далее, этой строчкой мы открываем нашу базу данных, которая является просто файлами в нашей файловой системе, в случае если базы не существует она будет создана с нуля.
И после этого мы начинаем первый цикл: обходим все полученные rss итемы, записываем ссылки, заголовок и дату публикации соответственно в переменные key, title и published. Проверяем есть ли в нашей базе ключ с таким же значением как наш и если есть просто выводим в лог текст, что не будем ничего перезаписывать (это нужно только на этапе отладки, но вообще не обязательно), в обратном случае, если в базе нет записи с таким ключом мы генерируем json строку и записываем её в базу. В качестве ключа я выбрал URL, так как они обеспечивают уникальность, всегда написаны в одном регистре и латиницей.
Следующим шагом я создаю объект типа Hash
и прохожусь по всем записям которые есть в базе. С помощью hash[k] = JSON.parse(v)
я делаю парсинг строки значения и создаю вложенные хеши. Затем проверяю значение поля sended
, если там 0 то генерирую текст и отправляю его в канал, после чего перезаписываю объект cо значением 1, чтобы не отправить эту же запись при следующем запуске.
На самом деле это не совсем рабочая версия кода, я почему-то не закоммитил тот момент когда довел работу с SDBM до ума. Можете попробовать сами понять что здесь не так.
Теперь уже я решил попробовать задеплоить мой код на Heroku и выполнить его там. С использоавнием раннера задач все получилось, да только вот Heroku не сохраняет файлы между запусками задачи (да и вообще). Так что мое решение с SDBM является быстрым и простым, но может быть использовано только как selfhosted.
Прикручиваем РСУБД или умеренно сообразительный бот
Пост становится довольно длинным, но вы же вместе сомной прошли все этапы разработки этого бота и уже в курсе дела, поэтому привожу код обновленной версии:
Здесь проделывается точно такая же работа: иницилизируются необходимые компоннеты, синхронизируется rss
лента и локальная база данных и отправляются ссылки на записи которые числятся в базе как “неотправленные”. Только в качестве базы используется PostgreSQL
и все это обернуто в класс и методы. Метод initialize
выполняется при вызове метода new
на объекте класса DoamTelegramBot
, остальные методы нужно вызывать отдельно. И чтобы выполнить всё правильно, я создал каталог bin
в который положил файл с именем doam_bot
и содержимым:
В котором я указываю что для выполнения скрипта нужно использовать язык Ruby, подключаю созданный мной класс через файл app.rb
, создаю объект telegram
и передаю в него урл для парсинга и id канала, вызываю методы sync
и send
. После чего я заливаю код на Heroku и создаю периодическую задачу, например раз в сутки. И если за сутки появились новые записи то в мой канал придет уведомление, уже без моего содействия в автоматическом режиме.
Заключение
Полностью это маленькое приложение можно посмотреть у меня в gitlab (для этого нужно залогиниться в gitlab.com). Лицензия пока не указана, но она MIT, т.е. можете править и использовать в своих целях. Если будет время я хотел бы прикрутить еще несколько функций, например отправку не только в телеграм но и другие сервисы, а также решить проблему первого запуска, когда база наполняется новыми записями с флагом “не отправлено” но неизвестно точно какие записи уже были отправлены в канал. В любом случае готов рассмотреть ваши Merge Requests.
#Ruby#Telegram#Heroku Ruby, Telegram, Heroku –> –>
Виталий Емельянцев
</span>
Jul 8, 2017·2 min read
</span>
Письма идут долго — до 7 минут. СМСки стоят по 2–5 руб. за штуку. Подключать CRM — иногда перебор. Выход? Бот на руби, отправляющий заявки в телеграм-чат менеджерам.
Как настроить? Читайте в статье.
UPD 25/08/2017: Поправил код в примерах.
Для создания нужно выбрать хотя бы одного участника кроме вас. Можете выбрать любого из знакомых, создать чат и удалить знакомого. Далее:
- Конвертируем чат в супергруппу;
- Добавляем бота @get_id_bot;
- Пишем в чат
/my_id
; - Читаем сообщение от бота, находим в нем ID чата, сохраняем ID;
- Удаляем бота.
Создаем через @botfather. Как — описано здесь .
Один такой бот может обслуживать много чатов с разных проектов. Имя и аватар выберите по вкусу, у меня бот такой:
Давать боту права администратора не нужно. Никаких дополнительных прав — тоже.
Суть такая:
- На сервере живет нативный телеграм-клиент;
- В руби проекте — тонкий руби гем;
- Командуем в руби проекте гему отправить сообщение — он дает команду телеграм-клиенту, а тот — отправляет сообщение в чат через бота.
Инструкция по установке: https://github.com/atipugin/telegram-bot-ruby
Копируем туда же, где у вас лежат все credentials. В ENV-переменные, например. Я использую figaro.
Где брать значения ключей:
TELEGRAM_BOT_TOKEN
– токен бота с шага 2 (получаем через @botfather);TELEGRAM_CHAT_ID
– ID чата с шага 1.
На самом деле вы уже можете отправлять сообщения командами на руби. Но чтобы делать удобной отправку заявок (с форматируемым текстом, DRY) — мы напишем пару классов. Пример учитывает, что у вас — Ruby on Rails, но не обязывает сидеть на нем. Если у вас не RoR — адаптируйте решение под ваш фреймворк.
Базовый класс. Обращается к телеграм-гему и просит отправить сообщение. Какое именно — за это отвечает метод render_message
. Кладем файл в папку app/notifiers
, и рельса подгружает его автоматически.
Пример нотификатора по заявкам с сайта (модель SiteRequest
). Наследуемся от TelegramNotifier
. При создании передаем внутрь запись модели. В render_message
— рендерим сообщение. В итоге в телеграм-чат придет подобное сообщение:
Пишите в комментариях, или у нас в чате. И подписывайтесь на канал в телеграме, чтобы быть в курсе новых статей.
- Tutorial
После выпуска Telegram Bot Platform многие задумывались о написании своего бота. Этот пост описывает минимальные шаги, необходимые для написания собственного бота на Ruby. Для этого потребуется только аккаунт в Telegram и машина с установленным Ruby на ней. Я выбрал Ruby из за удобного гема для работы с Telegram bot api. Первое, что нужно сделать, это создать .rb файл, в котором будет храниться логика бота, к примеру, start_bot.rb, и добавить туда минимальный код, необходимый для работы бота:
require 'telegram/bot' token = 'YOUR_TELEGRAM_BOT_API_TOKEN' Telegram::Bot::Client.run(token) do |bot| bot.listen do |message| case message.text when '/start' bot.api.sendMessage(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}") end end end
Для работы сервера не хватает только установки гема. Установку можно совершить двумя способами: 1. Установка гема непосредственно на машину:
gem install telegram-bot-ruby
2. Используя Gemfile
gem 'telegram-bot-ruby'
с последующим выполнением
bundle
Я для простоты примера использовал первый способ. Теперь необходимо получить токен для бота. Заходим в Telegram, добавляем бота @BotFather, и создаем бота: Далее добавляем токен в файл и получаем готовый сервер для бота:
require 'telegram/bot' token = '118997426:AAFVFtYa15Z7ckyDUIHb578NazgepL4kmU8' Telegram::Bot::Client.run(token) do |bot| bot.listen do |message| case message.text when '/start' bot.api.sendMessage(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}") end end end
Для проверки работы бота в начале запускаем сервер:
ruby start_bot.rb
А после пишем боту в Telegram: Как видно, все работает. PS: Бота после я удалил, поэтому мой токен, как и бот, недоступны. UPD: 3 строки на Ruby
require 'telegram/bot' token = '<>' Telegram::Bot::Client.run(token) { |bot| bot.listen { |message| bot.api.sendMessage(chat_id: message.chat.id, text: 'Hi!') if message.text == '/start' } }
За Python спасибо 3 строки на Python
from twx.botapi import TelegramBot token = '<>' while True: [lambda update: TelegramBot(token).send_message(update.message.chat.id, 'test message body') if update.message.text.startswith('/start') else None for update in TelegramBot(token).get_updates().wait()]
Telegram может быть новым именем для вас, но он набирает популярность в последние несколько лет, в последних новостях Telegram сообщал о 100 000 000 активных пользователей в месяц. Так о чем это все?
Telegram — это облачное приложение для обмена сообщениями, которое хорошо известно благодаря множеству функций, и его безопасная передача сообщений является одной из ключевых функций. Он поддерживает различные платформы, такие как Windows, OSX, GNU / Linux, Android, iOS и Windows Phone. Стоит также упомянуть, что клиентская сторона Telegram имеет открытый исходный код, поэтому мы будем использовать любое другое приложение для обмена сообщениями, например Pidgin, для связи с Telegram.
Некоторые особенности Telegram:
- шифрование
- Супер группы (1000 участников или больше)
- Передача файлов / фотографий
- Открытая сторона клиента
- Синхронизирует ваши сообщения на всех ваших устройствах
- Ограничение общего размера файла 1,5 ГБ
- Боты
О последнем поговорим конкретно. Telegram предлагает два API: API разработчика и API бота
Во-первых, нам нужно зарегистрировать аккаунт. Либо загрузите одного из клиентов, либо перейдите непосредственно к веб- версии Telegram. Оттуда вам будет предложено указать номер телефона, и Telegram отправит вам SMS с подтверждением.
Познакомьтесь с BotFather
Боты — это специальные учетные записи Telegram, предназначенные для автоматической обработки сообщений. Пользователи могут взаимодействовать с ботами, отправляя им команды в приватных или групповых чатах. Мы контролируем наших ботов, используя HTTPS-запросы к API ботов.
Что мы можем сделать с ботами?
- Делайте заметки в группах Telegram
- Получайте обновления погоды
- Играть в игры
- Взаимодействовать с другими сервисами, такими как социальные сети, IRC и т. Д.
Мы можем делать много вещей с ботами. Первый шаг в создании нашего бота — поговорить с BotFather .
Введите в форме поиска BotFather .
Нажмите на BotFather, и контейнер чата будет открыт, чтобы мы могли пообщаться с ним. Нажмите кнопку «Пуск», чтобы отобразить список команд, которые мы можем использовать для взаимодействия с BotFather.
Давайте создадим нашего бота с помощью команды /newbot
Он запросит имя для нашего бота, поэтому мы будем называть нашего бота sitepbot .
Теперь мы должны зарегистрироваться для имени пользователя, обратите внимание: оно должно заканчиваться ботом , если наш бот называется TetrisBot, имя пользователя должно быть ботом tetris . Пусть это будет sitepointbot .
BotFather поздравит нас и даст ссылку на нашего бота telegram.me/sitepoint_bot .
Мы можем добавить описание, а также добавить фотографию профиля для нашего бота. Команда /help
/newbot - create a new bot /token - generate authorization token /revoke - revoke bot access token /setname - change a bot's name /setdescription - change bot description /setabouttext - change bot about info /setuserpic - change bot profile photo /setinline - change inline settings /setinlinefeedback - change inline feedback settings /setcommands - change bot commands list /setjoingroups - can your bot be added to groups? /setprivacy - what messages does your bot see in groups? /deletebot - delete a bot /cancel - cancel the current operation
Используя одну из приведенных выше команд, мы можем внести различные изменения в нашего бота. Но сейчас наиболее важной командой является /token
Идите вперед и введите это сейчас:
/token
Возвращаемое значение будет выглядеть примерно так: 197372558:AAEtvechentOstoPmVyb1_aF2Dbe7k
После того, как мы создадим нашего бота и послушаем его, пришло время для Ruby. Есть несколько драгоценных камней для взаимодействия с API бота. Мы будем использовать telegram-bot-ruby .
Установка
Мы можем установить его прямо с вашего терминала:
gem install telegram-bot-ruby
Или добавьте его в наш Gemfile :
gem 'telegram-bot-ruby'
Если мы используем его с Gemfile, нам нужно ввести bundle install
Это установит гем и необходимые ему зависимости.
Привет Пример SitePoint
Создайте файл с именем sitepointbot.rb , мы создадим содержимое этого файла здесь.
Во-первых, нам нужно импортировать наш драгоценный камень:
require 'telegram/bot'
Далее нам нужно добавить наш токен, который мы сгенерировали ранее:
token = 'YOUR API TOKEN'
Используя объект bot.api
Telegram::Bot::Client.run(token) do |bot| bot.listen do |message| case message.text when '/sitepoint' bot.api.send_message(chat_id: message.chat.id, text: "Welcome to http://sitepoint.com") end end end
send_message
chat_id
chat_id
Конечно, text
Всякий раз, когда бот видит /sitepoint
Примечание. Настоятельно рекомендуется использовать косую черту (/) перед нашими командами, мы не хотим, чтобы наши боты мешали нашим разговорам.
Полный код
require 'telegram/bot' token = 'YOUR API TOKEN' Telegram::Bot::Client.run(token) do |bot| bot.listen do |message| case message.text when '/sitepoint' bot.api.send_message(chat_id: message.chat.id, text: "Welcome to http://sitepoint.com") end end end
Теперь пришло время запустить наш бот:
ruby sitepointbot.rb
Мы должны искать бота. Он появится в области результатов поиска.
Как видите, есть кнопка «Пуск». Если мы нажмем кнопку, команда /start
Это должно всегда содержать приветственное сообщение от нашего бота, это лучшее место для добавления общей информации о боте, например, что он делает и какие команды он понимает.
Это эффект кнопки «Пуск» или команды /start
Если вы хотите запустить бот внутри чата, вы также можете набрать
start@SitepBot
что необходимо, если в чате больше одного бота.
Теперь давайте попробуем /sitepoint
Результатом является приветственное сообщение со ссылкой на сайт SitePoint.
Еще один пример
Давайте использовать метод sendLocation
Этот метод сделает точку на карте. Мы будем использовать тот же объект bot.api
send_location
bot.api.send_location(chat_id: message.chat.id, latitude: -37.807416, longitude: 144.985339)
Полный код
require 'telegram/bot' token = 'YOUR API KEY' Telegram::Bot::Client.run(token) do |bot| bot.listen do |message| case message.text when '/start' bot.api.send_message(chat_id: message.chat.id, text: "I am the SitePoint bot, My commands are /sitepoint /map") when '/sitepoint' bot.api.send_message(chat_id: message.chat.id, text: "Welcome to http://sitepoint.com") when '/map' bot.api.send_location(chat_id: message.chat.id, latitude: -37.807416, longitude: 144.985339) end end end
Примечание : нам нужно выйти из бота и начать сначала, прежде чем увидеть изменения.
Вывод
Telegram предлагает надежную и безопасную службу обмена сообщениями. Как и Slack, Telegram предлагает возможность создавать ботов, которые могут взаимодействовать с пользователями. Мы видели некоторые основные функции, которые могут делать боты, но мы можем сделать их умнее и функциональнее, взглянуть на API Telegram и проявить креативность. Если вы делаете что-то великое, поделитесь этим с нами
Используемые источники:
- https://doam.ru/telegram_bot_for_push_messages_when_new_post_published/
- https://medium.com/@gambala/ruby-telegram-a4223c654fef
- https://habr.com/ru/post/264707/
- https://coderlessons.com/articles/ruby/bystro-sozdat-bot-telegram-v-ruby