Регистрация бота в Telegram
Регистрация нового бота происходит через бота по имени BotFather. Просто найдите его через поиск контактов Telegram. В чате вы всегда можете понять, что общаетесь с ботом, так как рядом с его именем есть подпись «bot». BotFather позволяет управлять вашими ботами в диалоговом режиме.
Для создания нового бота отправьте команду /newbot. Вам будет предложено ввести имя бота. Если выбранное вами имя не занято, то далее вам будет предложено ввести логин для этого бота. Причём он должен заканчиваться на «bot». Если логин не занят, то вам будет сгенерирован access token для работы с Telegram API по http.
За основу нашего чат-бота возьмём Spring Boot.
Код будем писать на Kotlin. Воспользуемся start.spring.io для создания заготовки нашего приложения. В настройках выберем Gradle Project и Kotlin, в качестве зависимости нам здесь будет достаточно только Web. Скачаем заготовку проекта и откроем файл build.gradle.kts. Проверьте, что в секции dependencies присутствует org.springframework.boot:spring-boot-starter-web.
- Также добавим туда библиотеку для работы с Telegram org.telegram:telegrambots-spring-boot-starter:4.1.
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.telegram:telegrambots-spring-boot-starter:4.1")
// другие зависимости
}
Найдём главный класс нашего приложения, в котором находится метод main() и @SpringBootApplication. В него нужно добавить инициализацию контекста Telegram API:
@SpringBootApplication
class BotApplication
fun main(args: Array<String>) {
ApiContextInitializer.init() // инициализация контекста для Telegram API
runApplication<BotApplication>(*args)
}
Если этого не сделать, то ошибок при запуске не будет, но и бот также работать не будет.
В Telegram боты можно подключать двумя способами: long polling и web-hook. В случае с long polling наше приложение кидает запрос и ждёт ответа от сервера telegram. В случае с webhook сервер telegram сам будет дёргать заранее зарегистрированные эндпоинты нашего приложения. В подключенной нами библиотеке поддерживаются оба варианта, но webhook чуть сложнее в настройке.
Поэтому рассмотрим long polling.
Унаследуем наш сервис от класса TelegramLongPollingBot. Этот абстрактный класс потребует от нас реализации методов getBotUsername(), getBotToken() и onUpdateReceived().
Первые два метода должны возвращать те самые данные, которые мы получили при регистрации. Однако нельзя их хардкодить в виде констант. Они должны подгружаться из параметров приложения.
@Service
class DevmarkBot : TelegramLongPollingBot() {
@Value("\${telegram.botName}")
private val botName: String = ""
@Value("\${telegram.token}")
private val token: String = ""
override fun getBotUsername(): String = botName
override fun getBotToken(): String = token
telegram:
botName: devmark_ru_bot
token: ${TOKEN}
Здесь мы указываем имя бота (telegram.botName) в явном виде, а вот токен (telegram.token) подгружаем из переменной окружения, т.к. этот токен должен сохраняться в секрете. Переменную окружения можно указывать при запуске приложения из командной строки через опцию -D или непосредственно в Idea.
Обработка запросов от пользователя
Вернёмся к нашему сервису и реализуем метод onUpdateReceived()
override fun onUpdateReceived(update: Update) {
if (update.hasMessage()) {
val message = update.message
val chatId = message.chatId
val responseText = if (message.hasText()) {
val messageText = message.text
when {
messageText == "/start" -> "Добро пожаловать!"
else -> "Вы написали: *$messageText*"
}
} else {
"Я понимаю только текст"
}
sendNotification(chatId, responseText)
}
}
В начале мы проверяем объект типа Update на наличие сообщения с помощью метода hasMessage(). Далее, извлекаем chatId (уникальный идентификатор пользователя в telegram). Затем проверяем, что входящее сообщение содержит текст (а не стикер, к примеру). Если сообщение от пользователя равно строке «/start», то мы приветствуем пользователя. Дело в том, что именно такое сообщение отправляется, когда вы впервые подключаетесь к боту и жмёте кнопку «Start»
Отправка сообщения происходит во вспомогательном методе sendNotification().
private fun sendNotification(chatId: Long, responseText: String) {
val responseMessage = SendMessage(chatId, responseText)
responseMessage.setParseMode("Markdown")
execute(responseMessage)
}
Создаём объект ответа, заполняя chatId и текст ответа. Затем с помощью метода setParseMode() включаем режим разметки Markdown. Этот режим позволяет делать простое форматирование текста. Например, текст, обрамлённый с двух сторон символами звёздочки будет отображаться жирным. Затем для отправки сообщения вызываем метод execute() из родительского класса.
Подписывайся и будет продолжение....