Erlang hackney : send a mail in mailgun.com using attachement - erlang

I'm trying to send an email via mailgun.com using the hackney and I have some issues sending attachments (which requires multipart).
https://documentation.mailgun.com/api-sending.html#sending
Basically my interest fields are:
from
to
subject
text
attachment File attachment. You can post multiple attachment values. Important: You must use multipart/form-data encoding when sending attachments.
I tried the following:
PayloadBase =[
{<<"from">>, From},
{<<"to">>, To},
{<<"subject">>, Subject},
{<<"text">>, TextBody},
{<<"html">>, HtmlBody}
],
Payload = case Attachment of
null ->
{form, PayloadBase};
_->
{multipart, PayloadBase ++ [{file, Attachment}]}
end,
But for some reason the attachment is not sent.. Everything else works as expected.
I don't see how I can set the filed name to "attachment" as required by mailgun .. at this this is what I suspect beeing wrong

I haven't used mailgun but I believe that you would need to put attachment as the field name. See examples at the bottom of the page you posted:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
-F from='Excited User <YOU#YOUR_DOMAIN_NAME>' \
-F to='foo#example.com' \
-F cc='bar#example.com' \
-F bcc='baz#example.com' \
-F subject='Hello' \
-F text='Testing some Mailgun awesomness!' \
--form-string html='<html>HTML version of the body</html>' \
-F attachment=#files/cartman.jpg \
-F attachment=#files/cartman.png
It will be easier if you make it working with curl first, then you can debug what headers curl sends to the server. And then you can mimic that in Erlang.
This post explains what multipart/form-data is and points to the W3 document that provides examples how the data should be encoded.

The following code will fix the problem:
Payload2 = case Attachment of
null ->
{form, PayloadBase};
_->
FName = hackney_bstr:to_binary(filename:basename(Attachment)),
MyName = <<"attachment">>,
Disposition = {<<"form-data">>, [{<<"name">>, <<"\"", MyName/binary, "\"">>}, {<<"filename">>, <<"\"", FName/binary, "\"">>}]},
ExtraHeaders = [],
{multipart, PayloadBase ++ [{file, Attachment, Disposition, ExtraHeaders}]}
end,
Silviu

Related

How to send several files via POST using cUrl

I use python requests to send multipart POST:
files = {"file1": open("C:\\Users\\Path\\to\\file1.xml", 'r'),
"file2": open("C:\\Users\\Path\\to\\file2.crt", 'r'),
"file3": open("C:\\Users\\Path\\to\\file3.pem", 'rb'),
"file4": open("C:\\Users\\Path\\to\\file4.elf", 'rb')}
url = "http://some_url.com"
r = requests.post(url, data={"targetName": "Qwerty"}, files=files)
I want to rewrite it using cURL. There's a lot of information about how to do this, but none of found approaches seem to work. For now I have something like:
curl -F 'targetName=Qwerty' -F 'file1=#\"C:\\Users\\Path\\to\\file1.xml\"' -F 'file2=#\"C:\\Users\\Path\\to\\file2.crt\"' -F 'file3=#\"C:\\Users\\Path\\to\\file3.pem\"' -F 'file4=#\"C:\\Users\\Path\\to\\file4.elf\"' http://some_url.com
but this returns
400 Bad Request
<html><head><title>Error</title></head><body>Required MultipartFile parameter 'file1' is not present</body></html>* Closing connection 0
What is wrong with my request? Do I need to specify headers?

Curl request in Ruby for Facebook Api

I'm trying to make a curl call with curb gem equivalent to:
curl \
-F 'name=My new CA' \
-F 'subtype=CUSTOM' \
-F 'description=People who bought from my website' \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.5/act_<AD_ACCOUNT_ID>/customaudiences
So far my code looks like:
cr = Curl::Easy.http_post("https://graph.facebook.com/v2.5/act_XXXXXXXXXXXXXXX/customaudiences?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") do |curl|
curl.headers['name']='My new CA'
curl.headers['subtype']='CUSTOM'
curl.headers['description']='People who bought from my website'
curl.headers['access_token']='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
end
pp cr.body_str
However, as a response I get this:
=> "{\"error\":{\"message\":\"(#100) Missing parameter(s): subtype\",\"type\":\"OAuthException\",\"code\":100,\"fbtrace_id\":\"BOd\\/mmhQkkP\"}}"
Could someone explain me what am I doing wrong?
Thank you!
You can also just use a system call like this:
name = "something"
url = "http://www.example.com"
result = `curl -F 'name=#{name}' #{url}`
result will hold the output of your system call. For more sophisticated http requests, you probably want to take a look at faraday (https://github.com/lostisland/faraday)

How can I use curl to upload a file using paperclip?

I want to upload a file together with some information(e.g. package_type) with curl
in my submission model:
has_attached_file :package
What I tried:
curl -d "submission[package_type]=type1&submission[package]=#/home/ubuntu/Downloads/test.zip" http://localhost:3000/restapi.json
If I leave out the file object, it works(a entry will be inserted into the database)
But I specify the file like above, it gives me an error:
No handler found for "#/home/ubuntu/Downloads/test.zip"
Update:
I just found that that I should use the -F option in curl, but in that case the file information cannot be recorded, is there anyway to include both the file object and file info? Maybe something like curl -d -F ?
I had a similar issue and ended up setting the content-type to multipart/form-data instead of dealing with base64 encoding issues when posting to my REST API. Here is an example which includes headers for auth:
curl -v -H 'Content-Type: multipart/form-data' -H "X-User-Email: <email>" -H "X-User-Token: <token>" -X POST -i -F submission[package_type]=type1 -F submission[image_attributes][image]=#f117.jpg http://localhost:3000/api/v1/submissions

How to send file contents as body entity using cURL

I am using cURL command line utility to send HTTP POST to a web service. I want to include a file's contents as the body entity of the POST. I have tried using -d </path/to/filename> as well as other variants with type info like --data </path/to/filename> --data-urlencode </path/to/filename> etc... the file is always attached. I need it as the body entity.
I believe you're looking for the #filename syntax, e.g.:
strip new lines
curl --data "#/path/to/filename" http://...
keep new lines
curl --data-binary "#/path/to/filename" http://...
curl will strip all newlines from the file. If you want to send the file with newlines intact, use --data-binary in place of --data
I know the question has been answered, but in my case I was trying to send the content of a text file to the Slack Webhook api and for some reason the above answer did not work. Anywho, this is what finally did the trick for me:
curl -X POST -H --silent --data-urlencode "payload={\"text\": \"$(cat file.txt | sed "s/\"/'/g")\"}" https://hooks.slack.com/services/XXX
In my case, # caused some sort of encoding problem, I still prefer my old way:
curl -d "$(cat /path/to/file)" https://example.com
curl https://upload.box.com/api/2.0/files/3300/content -H "Authorization: Bearer $access_token" -F file=#"C:\Crystal Reports\Crystal Reports\mysales.pdf"

Special characters like # and & in cURL POST data

How do I include special characters like # and & in the cURL POST data? I'm trying to pass a name and password like:
curl -d name=john passwd=#31&3*J https://www.mysite.com
This would cause problems as # is used for loading files and & for specifying more than one key/value. Is there some way I can escape these characters? \# and \& don't seem to work.
cURL > 7.18.0 has an option --data-urlencode which solves this problem. Using this, I can simply send a POST request as
curl -d name=john --data-urlencode passwd=#31&3*J https://www.example.com
Summarizing the comments, in case of mixed "good" and "bad" data and exclamation marks inside we can use on Windows:
curl -d "grant_type=client_credentials&client_id=super-client&acr_values=tenant:TNT123" --data-urlencode "client_secret=XxYyZ21D8E&%fhB6kq^mXQDovSZ%Q*!ipINme" https://login.example.com/connect/token
How about using the entity codes...
# = %40
& = %26
So, you would have:
curl -d 'name=john&passwd=%4031%263*J' https://www.mysite.com
Double quote (" ") the entire URL .It works.
curl "http://www.mysite.com?name=john&passwd=#31&3*J"
Just found another solutions worked for me. You can use '\' sign before your one special.
passwd=\#31\&3*J
Try this:
export CURLNAME="john:#31&3*J"
curl -d -u "${CURLNAME}" https://www.example.com
If password has the special characters in it, just round the password with the single quote it will work.
curl -u username:'this|!Pa&*12' --request POST https://www.example.com
I did this
~]$ export A=g
~]$ export B=!
~]$ export C=nger
curl http://<>USERNAME<>1:$A$B$C#<>URL<>/<>PATH<>/

Resources