使用 Julia 将文件发送到 Telegram
Send a file to Telegram with Julia
我正在用 Julia 编写 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
我在内容为 abc
的简单 test.txt
文件上进行了尝试,因此文件的大小或名称不能成为任何错误的原因。
我从中得到的结果(以及如果我使用 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]
看起来比如文件的内容。我该如何正确处理?
事实证明,我需要的不是 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
假设您的目录“Foto.jpg”中有一张照片。要发送照片,您需要:
fileName = "Foto.jpg"
url_photo = string("https://api.telegram.org/bot",bot_token,"/sendPhoto")
file = open(fileName)
query = Dict("chat_id" => bot_manu)
HTTP.post(url_photo, query=query; body=HTTP.Form(Dict("photo" => file)))
close(file)
其中 'bot_manu' 应该是您的聊天 ID,'bot_token' 是机器人 ID 标记。希望这对那些想要发送照片的人有所帮助。为了获得 'bot_manu' 和 'bot_token',我使用了 BotFather。
如果需要,您可以使用 Telegram.jl 包,其中特别包括对文档和图像发送的支持。
你可以这样做
using Telegram, Telegram.API
tg = TelegramClient(bot_token; chat_id = chat)
open("picture.png", "r") do io
sendPhoto(photo = io)
end
这里bot_token
和chat
是bot token和聊天id。
我正在用 Julia 编写 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
我在内容为 abc
的简单 test.txt
文件上进行了尝试,因此文件的大小或名称不能成为任何错误的原因。
我从中得到的结果(以及如果我使用 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]
看起来比如文件的内容。我该如何正确处理?
事实证明,我需要的不是 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
假设您的目录“Foto.jpg”中有一张照片。要发送照片,您需要:
fileName = "Foto.jpg"
url_photo = string("https://api.telegram.org/bot",bot_token,"/sendPhoto")
file = open(fileName)
query = Dict("chat_id" => bot_manu)
HTTP.post(url_photo, query=query; body=HTTP.Form(Dict("photo" => file)))
close(file)
其中 'bot_manu' 应该是您的聊天 ID,'bot_token' 是机器人 ID 标记。希望这对那些想要发送照片的人有所帮助。为了获得 'bot_manu' 和 'bot_token',我使用了 BotFather。
如果需要,您可以使用 Telegram.jl 包,其中特别包括对文档和图像发送的支持。
你可以这样做
using Telegram, Telegram.API
tg = TelegramClient(bot_token; chat_id = chat)
open("picture.png", "r") do io
sendPhoto(photo = io)
end
这里bot_token
和chat
是bot token和聊天id。