[Kotlin] Эхо-бот для Telegram на Kotlin

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
22-Апр-2021 22:31

ВведениеВ рамках этой статьи мы создадим своего бота, способного переотправлять отправленные пользователем сообщения с учётом форматирования и медиа. Тема ботов была изъезжена до дыр уже многими блогами, постами, блогпостами и прочими кодерами. Однако в большинстве своём это боты на условных Python/JS/PHP, в которых обычно можно сделать как получится и всё вроде как даже заработает. Я же в своё время (почти) ушел из этих языков в мир строгой типизации и объектной ориентированности Java, а позже и в Kotlin. На момент, когда мне было интересно написать своего первого бота, на рынке github из интересных присутствовала только библиотека pengrad/java-telegram-bot-api, однако лично для меня она имела один фатальный недостаток: она на тот момент полностью дублировала Telegram Bot API, то есть фактически являлась прокладкой, которая кроме взаимодействия через Java классы больше ничего не давала.Так я пришел к идее написать свою библиотеку для Telegram Bot API. Первая покрывающая основной API версия заняла у меня месяц, но выходили обновления, пользователи предлагали идеи по улучшению, да и мне часто не нравилось делать какие-то вещи руками на постоянной основе. В итоге, библиотека развивается по сей день, там есть удобный API, свой DSL, но что главное - она не утратила свою исходную идею о том, чтобы строго типизировать работу с Telegram Bot API.Как вообще работают боты в TelegramУ ботов в телеграме есть масса ограничений. На красивые циферки очень часто можно посмотреть тут, но если вкратце (ссылка на BotFather, чтобы дальше не повторяться) (скорее всего, будет пополняться для расширения кругозора):
  • По-умолчанию бот не видит сообщения других пользователей в группах до прямого обращения к боту командой (это можно поменять через group privacy настройку в BotFather)
  • По-умолчанию боты не инлайновые. Инлайновые боты - это как бот для гифок, то есть когда вы вводите ник бота, добавляете пробел и он вам предлагает варианты. После нажатия на вариант отправляется сообщение в чат с контентом, предложенным ботом (тоже включается через настройку в BotFather)
    • Кроме того, после включения инлайн-режима для бота, нужно будет отдельно включить поддержку инлайн-режима для локаций, когда бот может выдать результаты на основе геолокации пользователя
  • В API сейчас нет способа получить историю чата. Никакого. Вообще. Можно разве что кешировать сообщения
В среднем же пайплайн разработки бота выглядит следующим образом:
  • Идея
  • Создание тестового бота через BotFather с помощью /newbot
  • Кодинг, исправление ошибок
  • Хостинг
Итак, бот
  • Топаем к BotFather и создаём бота через /newbot
  • Для простоты открываем этот шаблон на гитхабе и создаём из него свой проект
Далее можно проследовать в Readme шаблона и настроить проект, а можно просто начать кодить в вашем файле App.kt. Итак, что же у нас есть из коробки:
suspend fun main(args: Array<String>) {
    val bot = telegramBot(args.first()) // 1
    val scope = CoroutineScope(Dispatchers.Default) // 2
    bot.buildBehaviour(scope) { // 3
        val me = getMe()
        onCommand("start", requireOnlyCommandInMessage = true) {
            reply(it, "Hello, I am ${me.firstName}")
        }
    }.join() // 4
}
  • Создаём бота. Можно заменить args.first() на явную передачу вашего токена, полученного при создании бота через BotFather
  • Создание CoroutineScope. Почитать о корутинах в котлине можно тут, но если вкратце - они позволяют производить работу с ботом асинхронно
  • Начало самого интересного. В коллбэке для buildBehaviour мы будем составлять логику нашего бота в этом туториале
  • Заставляем нашу программу не заканчиваться после составления логики бота и его запуска
Теперь давайте заменим код в логике бота на следующий:
onContentMessage { // 1
    execute( // 2
        it.content.createResend(it.chat.id) // 3
    )
}
Готово ? Давайте теперь разберёмся, что же тут происходит:
  • Данный метод позволяет нам отдельно получать сообщения с некоторым контентом: медиа, локации, текст и т.д.
  • execute - основной метод всей библиотеки. Этот метод отправляет запрос в систему телеграма. Скорее всего, напрямую вы будете использовать его очень редко, но знать о нём полезно
  • Магия с createResend заключается в том, что практически любой контент в телеграме может быть переотправлен. По этой причине в библиотеке были сделаны методы переотправки контента - они автоматически формируют запрос на отправку сообщения с тем же контентом
Теперь можно сделать что-то по-интересней. Давайте научимся реагировать на команды:
onCommand("start") { // 1
  reply(it, "Привет, я пока что умею не так много, но скоро всему научусь!") // 2
}
onCommand("help") {
  reply(it, "Отправьте мне любое сообщение, и я отвечу вам тем же?")
}
  • Этот коллбэк будет вызываться каждый раз при отправке /start , но важно знать, что он будет вызываться при наличии в сообщении только этой команды
  • Отвечаем текстовым сообщением. it тут обозначает само сообщение
Ну и напоследок давайте попробуем переписать часть с onContentMessage так, чтобы попутно сохранять части текстовых сообщений:
fun save(sources: List<TextSource>) {
  // работа с сохранением частей текста
  println(sources.makeString()) // 3
}
onContentMessage {
  it.content.asTextContent() ?.let { content -> // 1
    save(content.textSources) // 2
  }
  execute(it.content.createResend(it.chat.id))
}
  • asTextContent() проверяет, является ли контент сообщения текстом и вызывает let, если да
  • content.textSources создаст список TextSource объектов, с этим списком потенциально можно:
    • Сохранять (у TextSource есть сериализатор для kotlinx.serialization)
    • Копировать, перемещать, модифицировать
    • Использовать для форматирования - сурсы могут быть превращены в стандартные текстовые части телеграма
  • makeString создаст из списка TextSource текст, который будет виден пользователю без учета форматирования
ЗаключениеИтак, мы создали бота, который:
  • Умеет отвечать на простые команды /start и /help
  • Умеет переотправлять полученные сообщения отправителю
  • Отбирает текстовые сообщения и производит операции с их контентом
Далее остаётся только развивать бота насколько хватит фантазии. Например, можно выделить модули в функции/плагины, как я это сделал в своём PlaguBotе.Для более подробной информации о проекте можно посмотреть его основную страницу, вики, проект с примерами и заглянуть в наш телеграм канал.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_kotlin, #_kotlin, #_telegrambot, #_kotlin
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 02-Июн 19:10
Часовой пояс: UTC + 5