Перейти к содержанию

KTB-15 Отправить сообщение пользователю через Telegram API

📝 Описание

Для отправки сообщений пользователям через Telegram API необходимо использовать метод sendMessage. Этот метод принимает обязательные параметры chat_id и text. Параметр chat_id определяет, в какой чат нужно отправить сообщение, а text содержит текст самого сообщения.

Отправка пустых сообщений недопустима. Разрешается отправлять сообщения размером от 1 до 4096 символов. Поскольку сообщения могут поступать из разных чатов, необходимо отвечать именно в тот чат, откуда пришло сообщение.

Где получить chat_id? Значение chat_id содержится в полученном обновлении (апдейте). Необходимо извлечь его из апдейта и передать в качестве параметра запроса в метод sendMessage().

Обратившись к документации Telegram API, можно найти описание метода sendMessage. В нем указано: "Используйте этот метод для отправки текстовых сообщений. При успешной отправке метод вернет отправленное сообщение". Это означает, что сервер в ответ предоставит объект Message, детали которого также описаны в документации.

🗒 Задание

  1. Создать отдельную функцию для отправки сообщений (sendMessage), аналогичную getUpdates, которая принимает chatId.
  2. Разработать новое регулярное выражение (RegEx) для извлечения chatId из полученных обновлений.
  3. Реализовать функциональность: при отправке в бота сообщения "Hello" он должен отвечать тем же сообщением "Hello".
  4. Провести рефакторинг кода: создать отдельный класс TelegramBotService с методами для взаимодействия с Telegram API (на данный момент у нас есть 2 метода).

❌ Ошибки

✏️ Комментарии

`https://api.telegram.org/bot` - можно вынести в константы
botToken можно передать в конструктор TelegramBotService, чтобы не прокидывать в каждый метод
HttpClient можно сделать полем TelegramBotService, чтобы не создавать экземпляр при каждом сетевом вызове.

⌨️ Решение

import java.net.URI
import java.net.URLEncoder
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.nio.charset.StandardCharsets

const val TELEGRAM_BASE_URL = "https://api.telegram.org"

class TelegramBotService(
    private val botToken: String,
) {
    fun getUpdates(updateId: Int): String {
        val urlGetUpdates = "$TELEGRAM_BASE_URL/bot$botToken/getUpdates?offset=$updateId"
        val client: HttpClient = HttpClient.newHttpClient()
        val httpRequest: HttpRequest = HttpRequest.newBuilder().uri(URI.create(urlGetUpdates)).build()
        val response: HttpResponse<String> = client.send(httpRequest, HttpResponse.BodyHandlers.ofString())
        return response.body()
    }

    fun sendMessage(chatId: Int, text: String) {
        val encodedText = URLEncoder.encode(text, StandardCharsets.UTF_8.toString())
        val urlSendMessage = "$TELEGRAM_BASE_URL/bot$botToken/sendMessage?chat_id=$chatId&text=$encodedText"
        val client: HttpClient = HttpClient.newHttpClient()
        val httpRequest: HttpRequest = HttpRequest.newBuilder().uri(URI.create(urlSendMessage)).build()
        client.send(httpRequest, HttpResponse.BodyHandlers.ofString())
    }
}
fun main(args: Array<String>) {

    val botToken = args[0]
    var updateId = 0
    val telegramBotService = TelegramBotService(botToken)

    val regexFindText: Regex = "\"text\":\"(.+?)\"".toRegex()
    val regexFindUpdateId = "\"update_id\":(\\d+)".toRegex()
    val regexFindChatId = "\"chat\":\\{\"id\":(.+?)\"".toRegex()

    while (true) {
        Thread.sleep(2000)

        // KTB-15 (сократили)
        val updates = telegramBotService.getUpdates(updateId)
        println(updates)

        val updateIdInt = regexFindUpdateId.find(updates)?.groups?.get(1)?.value?.toIntOrNull() ?: continue
        updateId = updateIdInt + 1
        val text = regexFindText.find(updates)?.groups?.get(1)?.value ?: continue
        val chatId = regexFindChatId.find(updates)?.groups?.get(1)?.value?.toIntOrNull() ?: continue

        if (text == "Hello") {
            telegramBotService.sendMessage(chatId, text)
        }
    }
}