Please how may we upload a file as described below with Tesla?
For a self-signed certificate an extra parameter is needed, certificate
, with the public certificate in PEM format as data.
A curl example for a self-signed certificate:
curl -F "url=https://<YOURDOMAIN.EXAMPLE>/<WEBHOOKLOCATION>" -F "certificate=@<YOURCERTIFICATE>.pem" https://api.telegram.org/bot<YOURTOKEN>/setWebhook
The -F
means we’re using the multipart/form-data
-type to supply the certificate
(Marvin's Marvellous Guide to All Things Webhook )
I have tried:
mp = Multipart.new()
|> Multipart.add_field("url", "https://my-sever-ip:88/bots/#{token}")
|> Multipart.add_field("certificate", "bots.pem")
|> Multipart.add_file(file, name: "bots.pem")
post("bot#{token}/setwebhook", mp)
But the operation is not successful.
Please how may I achieve the same as this : https://paperlesssolutionsltd.com.ng/bots.htm manual file upload utility using Tesla.
Thanks.
NobbZ
June 19, 2019, 12:37pm
2
In a helper script I use to push files to gitlab, I do use this code:
end
def get_links(config) do
"/projects/#{config.project_id}/releases/#{config.commit_tag}/assets/links"
|> get(headers: [{@token_field, config.token}])
|> case do
{:ok, %Tesla.Env{body: body}} when is_list(body) -> {:ok, body}
end
end
def upload_file(config, file) do
body =
Multipart.new()
|> Multipart.add_file(config.release_path |> Path.expand() |> Path.join(file), name: :file)
"/projects/#{config.project_id}/uploads"
|> post(body, headers: [{@token_field, config.token}])
|> case do
{:ok, %Tesla.Env{body: %{"url" => url}}} -> {:ok, url}
end
end
Basically, you do not need o add_field/2
, but only add_file/2
. :name
has to be the name of the target-field, not of the file.
In your curl
example you aren’t specifiying a name as well… @
reads the file and sends the content properly encoded.
I also need to set the parameter certificate
on the file being uploaded, not sure, but i feel that is where ia ma failing
Parameter
Type
Required
Description
url
String
Yes
HTTPS url to send updates to. Use an empty string to remove webhook integration
certificate
InputFile
Optional
Upload your public key certificate so that the root certificate in use can be checked. See our self-signed guide for details.
NobbZ
June 19, 2019, 12:48pm
4
This curl should translate into this tesla
request (I’ll take your placeholders literally):
body =
Tesla.MultiPart.new
|> MultiPart.add_field("url", "https://<YOURDOMAIN.EXAMPLE>/<WEBHOOKLOCATION>")
|> MultiPart.add_file("<YOURCERTIFICATE>.pem", name: :certificate, filename: "<YOURCERTIFICATE>.pem") # but `:filename` actually defaults to this…
Tesla.post("https://api.telegram.org/bot<YOURTOKEN>/setWebhook", body)
2 Likes
NobbZ:
name: :certificate
no luck,
13:53:28.417 [info] POST https://api.telegram.org/botmy-bot-id/setwebhook -> 200 (968.000 ms)
13:53:28.433 [debug]
>>> REQUEST >>>
(no query)
content-type: application/json
[Tesla.Multipart]
boundary: nhPkmImyzsDqsndbfmgBGRn65glBXisu
content_type_params: []
%Tesla.Multipart.Part{body: "https://173.233.70.70:88/my-bot-id", dispositions: [name: "url"], headers: []}
%Tesla.Multipart.Part{body: "100", dispositions: [name: "max_connections"], headers: []}
%Tesla.Multipart.Part{body: %File.Stream{line_or_bytes: 2048, modes: [:raw, :read_ahead, :read, :binary], path: "c:/Apps/BE/_build/dev/lib/tbe/priv/TBE.pem", raw: true}, dispositions: [name: :certificate, filename: "TBE.pem"], headers: []}
<<< RESPONSE <<<
connection: keep-alive
date: Wed, 19 Jun 2019 12:53:31 GMT
server: nginx/1.12.2
content-length: 68
content-type: application/json
strict-transport-security: max-age=31536000; includeSubDomains; preload
access-control-allow-origin: *
access-control-allow-methods: GET, POST, OPTIONS
access-control-expose-headers: Content-Length,Content-Type,Date,Server,Connection
{"ok":true,"result":true,"description":"Webhook is already deleted"}
NobbZ
June 19, 2019, 1:02pm
6
I do not know the telegram API, all I can tell you is, that from what I can tell both requests should be equivalent.
@NobbZ it only works when i use regular browser upload, like here https://paperlesssolutionsltd.com.ng/bots.htm
Maybe Tesla is not generating multi-part output like a browser would
NobbZ
June 19, 2019, 1:06pm
8
Maybe browser sends some automatic header, like content type, that you don’t? Can you inspect the request in your browsers tool?
Or paste a --verbose
curl
s output here? (sanitized of course!) Then we can compare headers actually sent.
CharlesO:
Multipart
It works now.
Tesla actually works fine.
setting these two affects the post
method, should have used Tesla.post
instead
plug(Tesla.Middleware.Headers, [{"content-type", "application/json"}])
plug(Tesla.Middleware.BaseUrl, "https://api.telegram.org/")
body =
Multipart.new()
|> Multipart.add_field("max_connections", "100")
|> Multipart.add_field("url", "https://173.233.70.70:#{port}/bots/#{token}")
|> Multipart.add_file(file, name: :certificate, filename: name)
x = Tesla.post("https://api.telegram.org/bot#{token}/setWebhook", body)
Thanks
2 Likes