Martin Gaens
07/03/2022, 12:02 PMkotlinx.serialization
for serializing objects and here's my issue: The Telegram API supports a lot of methods.
Here's an example of one such method:
The getFile
method. It has one parameter: file_id
which is of type String
.
These methods can receive their parameters through JSON objects. So, if I want to send a request to this method, I first create a class
called GetFileJSONRequest
with @SerialName()
annotations (because in Kotlin, the parameter is called fileId
and in JSON it has to be file_id
). And then, I send the request like this:
val response: HttpResponse = <http://client.post|client.post>("<https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/getFile|https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/getFile>") {
contentType(ContentType.Application.Json)
setBody(GetFileJSONRequest(fileId = fileId))
}
This whole process with creating classes seems very tedious and I wonder if there's a much better solution to my problem.Andreas Scheja
07/03/2022, 3:52 PMsetBody(mapOf("file_id" to fileId))
insteadMartin Gaens
07/03/2022, 5:28 PMSerializing collections of different element types is not yet supported. Selected serializers: [kotlin.String, <http://kotlin.Int|kotlin.Int>]
.
This is the code leading to the error:
<http://client.post|client.post>("sendMessage") {
contentType(ContentType.Application.Json)
setBody(
mapOf(
"chat_id" to chatId.toString(),
"text" to text,
"parse_mode" to parseMode,
"entities" to entities?.map { it.toDto() },
"disable_web_page_preview" to disableWebPagePreview,
"disable_notification" to disableNotification,
"protect_content" to protectContent,
"reply_to_message_id" to replyToMessageId,
"allow_sending_without_reply" to allowSendingWithoutReply,
"reply_markup" to replyMarkup
)
)
}
sendMessage
method to be:
internal suspend fun sendMessage(
chatId: Int,
text: String,
parseMode: String? = null,
entities: List<MessageEntity>? = null,
disableWebPagePreview: Boolean? = null,
disableNotification: Boolean? = null,
protectContent: Boolean? = null,
replyToMessageId: Int? = null,
allowSendingWithoutReply: Boolean? = null,
replyMarkup: ReplyMarkup? = null
) {
@Serializable
class Request(
@SerialName("chat_id") val chatId: Int,
@SerialName("text") val text: String,
@SerialName("parse_mode") val parseMode: String? = null,
@SerialName("entities") val entities: List<MessageEntityDto>? = null,
@SerialName("disable_web_page_preview") val disableWebPagePreview: Boolean? = null,
@SerialName("disable_notification") val disableNotification: Boolean? = null,
@SerialName("protect_content") val protectContent: Boolean? = null,
@SerialName("reply_to_message_id") val replyToMessageId: Int? = null,
@SerialName("allow_sending_without_reply") val allowSendingWithoutReply: Boolean? = null,
@SerialName("reply_markup") val replyMarkup: ReplyMarkup? = null
)
<http://client.post|client.post>("sendMessage") {
contentType(ContentType.Application.Json)
setBody(Request(
chatId = chatId,
text = text,
parseMode = parseMode,
entities = entities?.map { it.toDto() },
disableWebPagePreview = disableWebPagePreview,
disableNotification = disableNotification,
protectContent = protectContent,
replyToMessageId = replyToMessageId,
allowSendingWithoutReply = allowSendingWithoutReply,
replyMarkup = replyMarkup
))
}
}
}
Aleksei Tirman [JB]
07/05/2022, 9:09 AM<http://client.post|client.post>("<https://httpbin.org/post>") {
contentType(ContentType.Application.Json)
setBody(JsonObject(mapOf(
"fileId" to JsonPrimitive(123),
"text" to JsonPrimitive("text"),
"flag" to JsonPrimitive(true)
)))
}
Martin Gaens
07/05/2022, 2:41 PM@Serializable
classes. How do I pass objects of these classes into the map?Aleksei Tirman [JB]
07/05/2022, 3:31 PMMartin Gaens
07/05/2022, 3:52 PMAndreas Scheja
07/05/2022, 4:09 PMkotlinx.serialization
, shouldn't have any problems with mixed maps afaik.Martin Gaens
07/05/2022, 4:10 PMkotlinx.serialization
. Does this mean it is not yet production ready?Andreas Scheja
07/05/2022, 4:14 PMMartin Gaens
07/05/2022, 4:24 PMAndreas Scheja
07/05/2022, 5:24 PMJson.encodeToJsonElement()
which will turn any serializable thing into a JsonElement
which you then can pass to the JsonObject.
@kotlinx.serialization.Serializable
class MyObj(val myProperty: Double)
runBlocking {
val response = <http://client.post|client.post>("<http://localhost:8080/some/url>") {
contentType(ContentType.Application.Json)
setBody(
JsonObject(
mapOf(
"file_id" to JsonPrimitive(123),
"name" to JsonPrimitive("test"),
"obj" to DefaultJson.encodeToJsonElement(MyObj(2.0))
)
)
)
}
println(response.status)
}
Martin Gaens
07/05/2022, 5:29 PM