Отправить файл в Telegram с Юлией - PullRequest
0 голосов
/ 12 марта 2020

Я пишу бот Telegram в Джулии, и я не могу понять, как правильно отправлять файлы.

Я видел похожие вопросы для других языков, но это не помогло.

В настоящее время у меня есть такая функция:

function sendDoc(chat, fileName::String)
    file = open(fileName)
    url = string(base_url, "sendDocument")
    mp = HTTP.Multipart(basename(fileName), file)
    query = Dict("chat_id" => chat)
    HTTP.post(url; query=query, files=Dict("document" => mp))

    close(file)
end

Я пробую его на простом test.txt файле с содержанием abc, поэтому размер файла или его имя не могут быть причиной за любые ошибки.

Что я получаю от этого (а также в случае, если я использую file вместо mp), это ошибка HTTP 400 (я удалил некоторые части в целях конфиденциальности):

ERROR: LoadError: HTTP.ExceptionRequest.StatusError(400, "POST", "/bot/sendDocument?chat_id=", HTTP.Messages.Response(v"1.1.0", 400, Pair{SubString{String},SubString{String}}["Server" => "nginx/1.16.1", "Date" => "Thu, 12 Mar 2020 GMT", "Content-Type" => "application/json", "Content-Length" => "94", "Connection" => "keep-alive", "Strict-Transport-Security" => "max-age=31536000; includeSubDomains; preload", "Access-Control-Allow-Origin" => "*", "Access-Control-Expose-Headers" => "Content-Length,Content-Type,Date,Server,Connection"], UInt8[0x7b, 0x22, 0x6f, 0x6b, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73  …  0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x7d], HTTP.Messages.Request("POST", "/bot/sendDocument?chat_id=", v"1.1.0", Pair{SubString{String},SubString{String}}["Host" => "api.telegram.org", "User-Agent" => "HTTP.jl/1.3.1", "Content-Length" => "0"], UInt8[], HTTP.Messages.Response(#= circular reference @-2 =#), 1, nothing)))

Я также попытался поместить mp или file в body вместо files, но затем получаю следующее:

┌ Info: Error in @async writebody task. Server likely closed the connection unexpectedly. Only an issue if unable to read the response and this error gets re-thrown. 
│   exception =
│    MethodError: no method matching write(::HTTP.Streams.Stream{HTTP.Messages.Response,HTTP.ConnectionPool.Transaction{MbedTLS.SSLContext}}, ::Pair{String,IOStream})
│    Closest candidates are:
│      write(::IO, ::Any) at io.jl:582
│      write(::IO, ::Any, ::Any...) at io.jl:584
│      write(::IO, ::Complex) at complex.jl:217

Включение файла в query Также я мог бы попробовать, но тогда это было бы в URL, и я был бы очень ограничен в размере файла.

Ошибка 400 выглядит так же, как если бы она пропускала поле, поэтому я предполагаю, что Telegram не может видеть Dict("document" => mp), но в то же время ошибка включает UInt8[0x7b, … 0x7d], который выглядит как содержимое файла. Как мне сделать это правильно?

1 Ответ

1 голос
/ 13 марта 2020

Оказывается, это не HTTP.Multipart, что мне нужно, это HTTP.Form.

Следующая функция работает:

function sendDoc(chat, fileName::String)
    url = string(base_url, "sendDocument")
    file = open(fileName)
    query = Dict("chat_id" => chat)
    HTTP.post(url, query=query; body=HTTP.Form(Dict("document" => file)))

    close(file)
end
...