我正在使用kotlin
和ktor为 telegram-bot-api 编写包装器。我有一个问题 - 找不到上传文件的工作方式。
(来自 tg bot api docs)
发送文件(照片、贴纸、音频、媒体等)的三种方式:
- 如果文件已经存储在 Telegram 服务器的某个位置,则无需重新上传:每个文件对象都有一个 file_id 字段,只需将此 file_id 作为参数传递,而不是上传。以这种方式发送的文件没有限制。
- 为 Telegram 提供要发送的文件的 HTTP URL。Telegram 将下载并发送文件。照片的最大大小为 5 MB,其他类型的内容最大为 20 MB。
- 使用 multipart/form-data 以通常通过浏览器上传文件的方式发布文件。照片最大 10 MB,其他文件最大 50 MB。
使用第一种和第二种方式我没有任何问题。
现在我有一个丑陋的函数,它向 tg 发出请求并解析答案:
internal suspend inline fun <reified T> makeRequest(token: String, method: TelegramMethod, vararg params: Pair<String, Any?>, files: Map<String, String> = emptyMap()): T {
try {
val data: List<PartData> = formData {
files.forEach { key, fileName ->
append(key, Files.newInputStream(Paths.get(fileName)).asInput())
}
}
val response = client.submitFormWithBinaryData<HttpResponse>(data) {
this.method = HttpMethod.Post
url {
protocol = URLProtocol("https", 42)
host = API_HOST
encodedPath = API_PATH_PATTERN.format(token, method.methodName)
params.forEach { (name, value) ->
if (value != null) { this.parameters[name] = value as String }
}
}
}
val result = response.receive<String>()
return parseTelegramAnswer<T>(response, result)
} catch (e: BadResponseStatusException) {
val answer = mapper.readValue<TResult<T>>(e.response.content.readUTF8Line()!!)
throw checkTelegramError(e.response.status, answer)
}
}
没有文件它可以工作,有文件 - 它不会。(我认为我做错了一切)
使用示例:
suspend fun getUpdates(offset: Long? = null, limit: Int? = null, timeout: Int? = null, allowedUpdates: List<String>? = null): List<Update> =
api.makeRequest(
token,
TelegramMethod.getUpdates,
"offset" to offset?.toString(),
"limit" to limit?.toString(),
"timeout" to timeout?.toString(),
"allowed_updates" to allowedUpdates
)
我已经在不同的文件上对其进行了测试,我发现:
如果我在之间发送文件
17,9 KiB
并且56,6 KiB
我从 tg 得到以下错误:Bad Request: wrong URL host
如果我在两者之间发送文件
75,6 KiB
并且913,2 KiB
我收到错误413 Request Entity Too Large
* 我正在使用sendDocument
方法
使用 发送文件的真正方法是什么ktor
?