KTB-15 Отправить сообщение пользователю через Telegram API¶
📝 Описание¶
Для отправки сообщений пользователям через Telegram API необходимо использовать метод sendMessage. Этот метод принимает обязательные параметры chat_id и text. Параметр chat_id определяет, в какой чат нужно отправить сообщение, а text содержит текст самого сообщения.
Отправка пустых сообщений недопустима. Разрешается отправлять сообщения размером от 1 до 4096 символов. Поскольку сообщения могут поступать из разных чатов, необходимо отвечать именно в тот чат, откуда пришло сообщение.
Где получить chat_id? Значение chat_id содержится в полученном обновлении (апдейте). Необходимо извлечь его из апдейта и передать в качестве параметра запроса в метод sendMessage().
Обратившись к документации Telegram API, можно найти описание метода sendMessage. В нем указано: "Используйте этот метод для отправки текстовых сообщений. При успешной отправке метод вернет отправленное сообщение". Это означает, что сервер в ответ предоставит объект Message, детали которого также описаны в документации.
🗒 Задание¶
- Создать отдельную функцию для отправки сообщений (
sendMessage), аналогичнуюgetUpdates, которая принимаетchatId. - Разработать новое регулярное выражение (RegEx) для извлечения
chatIdиз полученных обновлений. - Реализовать функциональность: при отправке в бота сообщения "Hello" он должен отвечать тем же сообщением "Hello".
- Провести рефакторинг кода: создать отдельный класс
TelegramBotServiceс методами для взаимодействия с Telegram API (на данный момент у нас есть 2 метода).
❌ Ошибки¶
✏️ Комментарии¶
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)
}
}
}