R curl sending email with attachments - r

I am trying to send an email with attachment using R curl.
If I use the command line, the following succeeds in sending an email via curl from from#mail.com to to#mail.com and attaches the file tester.pdf (note authentication is done using SSL and the password would be horsebatterystaple):
BODY="This is the body of the email..."
SUBJECT="Did you get my last email with the reports?"
curl -v \
--url smtp://the-smtp-server:587 \
--ssl-reqd \
--mail-from from#mail.com \
--mail-rcpt to#mail.com \
--user from#mail.com:horsebatterystaple \
-F '=(;type=multipart/mixed' -F "=$BODY;type=text/plain" \
-F "file=#tester.pdf;type=application/pdf;encoder=base64" -F '=)' \
-H "Subject: $SUBJECT" \
-H "From: Myself <from#mail.com>" \
-H "To: Someone Else <to#mail.com>"
Now I want to translate that to R and the R curl package.
It works without attachments when I use this resource, but I cannot find a way to properly emulate the -F (form) flags.
See my attempt below.
There are no form arguments in the curl options (curl::curl_options("form")) and I do not find example code for curl::form_file() or the mimepost option (=> curl::curl_options("mime")).
Any ideas how to make this work?
Note I am not looking for cmd <- "curl -v --url ..."; system(cmd) type solutions if possible...
h <- curl::new_handle(
verbose = TRUE,
url = "smtp://the-smtp-server:587",
use_ssl = 1,
mail_from = "from#mail.com",
mail_rcpt = "to#mail.com",
username = "from#mail.com",
password = "horsebatterystaple"
)
curl::handle_setheaders(h,
"Subject: Hello World",
"From: Myself <from#mail.com>",
"To: Someone Else <to#mail.com>"
)
curl::curl_fetch_memory(handle = h)
Update
After reading through some more documentation, I also found curl::send_email(), therefore my R code is updated to the following, but the attachment still do not work... (see tries as comments):
conf <- list(smpt_server = "...", ...)
verbose <- TRUE
url <- paste0("smtp://", conf$smtp_server, ":", conf$smtp_port)
message <- glue::glue('From: "{conf$name_from}" <{conf$mail_from}>
To: "{conf$name_to}" <{conf$mail_to}>
Subject: {subject}
Hi there,
this is sent from R curl...')
a <- curl::send_mail(
mail_from = conf$mail_from,
mail_rcpt = conf$mail_to,
message = message, smtp_server = url,
use_ssl = TRUE, verbose = verbose,
username = conf$mail_from, password = conf$password,
# mimepost = "file=#tester.pdf;type=application/pdf;encoder=base64"
# mimepost = form_file("tester.pdf", "application/pdf")
)

Related

How to pass the curl -F parameter in the httr package?

Hi I try to translate this curl instruction using httr
curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -F file=#test.txt -F filename=test.txt -F parent_dir=/ http://cloud.seafile.com:8082/upload-api/73c5d117-3bcf-48a0-aa2a-3f48d5274ae3
Without the -F parameter the instruction is :
httr::POST(
url = "http://cloud.seafile.com:8082/upload-api/73c5d117-3bcf-48a0-aa2a-3f48d5274ae3",
add_headers(Authorization = "Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd")
)
)
I think I have to use the httr::upload_file function but I didn't manage to use this without error.
Do you have any idea how I can do that ?
Regards
Here is how to construct this curl request with httr package. I used httpbin.org to test the request sent.
You'll use POST filling the body with a list. encode argument controls how this list will be handle and by default it is the correct multipart you need.
res <- httr::POST(
url = "http://httpbin.org/post",
httr::add_headers(Authorization = "Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd"),
# Add the file and metadata as body using a list. Default encode is ok
body = list(
file = httr::upload_file("test.txt"),
filename = "test.txt",
parent_dir = "/"
)
)
httr_ouput <- httr::content(res)
One way to check this is ok is to compare output with the curl command you know is working
out <- sys::exec_internal(
'curl -H "Authorization: Token f2210dacd9c6ccb8133606d94ff8e61d99b477fd" -F file=#test.txt -F filename=test.txt -F parent_dir=/ http://httpbin.org/post'
)
curl_output <- jsonlite::fromJSON(rawToChar(out$stdout))
#compare body
identical(curl_output$files, httr_ouput$files)
#> TRUE
identical(curl_output$form, httr_ouput$form)
#> TRUE
You can also do it with the crul package, another wrapper above curl; The logic is identical
con <- crul::HttpClient$new(
url = "http://httpbin.org/post"
)
crul_req <- con$post(
body = list(
file = crul::upload("test.txt"),
filename = "test.ext",
parent_dir = "/"
)
)
crul_output <- jsonlite::fromJSON(crul_req$parse())

Reading API - code from Curl to R

I am trying to read a json from an authenticated API using R, but not sucessfully.
I have the Curl code and tried to convert it to R using "curlconverter" library and also tried to get it using "httr" library.
curl -X GET \
'https://api.cartolafc.globo.com/auth/liga/gurudocartola-com?orderBy=campeonato&page=1' \
-H 'Cache-Control: no-cache' \
-H 'x-glb-token: mytoken'
I would appreciate a solution to write this code in R.
library(curlconverter) # devtools::install_github("hrbrmstr/curlconverter")
u <- "curl -X GET 'https://api.cartolafc.globo.com/auth/liga/gurudocartola-com?orderBy=campeonato&page=1' -H 'Cache-Control: no-cache' -H 'x-glb-token: mytoken'"
straighten(u) %>%
make_req()
That makes:
httr::VERB(verb = "GET", url = "https://api.cartolafc.globo.com/auth/liga/gurudocartola-com?orderBy=campeonato&page=1",
httr::add_headers(`Cache-Control` = "no-cache",
`x-glb-token` = "mytoken"))
which very straightforwardly (if one has done any research before posting a question) translates to:
httr::GET(
url = "https://api.cartolafc.globo.com/auth/liga/gurudocartola-com",
httr::add_headers(
`Cache-Control` = "no-cache",
`x-glb-token` = "mytoken"
),
query = list(
`orderBy` = "campeonato",
`page` = 1L
)
)
The back-ticks are there solely to remind me they are parameters (and, they sometimes contain dashes or other chars which force a back-tick quote).

--user curl equivalent in httr

This is, I presume, some really simple curl code that I am trying to translate into a httr format.
curl -X POST \
--user '<email>:<password>' \
--header 'user-key: <user_key>' \
--url https://api.m.com/v1/clients
So far I have tried
library(httr)
POST(url = "https://api.m.com/v1/clients",
add_headers('user-key' = "userkey",
user = 'email:password'))
But without success. Any hints on what is wrong here? Is there an httr equivalent to --user in the curl code?
library(httr)
username <- 'my_user_name'
password <- 'my_password'
POST(url = "https://api.m.com/v1/clients",
config = authenticate(username, password), add_headers("Content-Type: application/json"),
body = upload_file('./my_file.json'),
encode = 'json')

Writing Curl POST in R

What is the correct way of writing this Curl POST in R?
I would like to have R read the contents of a file as "values" in the post form.
curl -X POST https://api.priceapi.com/jobs \
-d "token=token" \
-d "country=country" \
-d "source=source" \
-d "currentness=currentness" \
-d "completeness=completeness" \
-d "key=key" \
-d 'values=<values>'
So far I have this-
library(RCurl)
library(RJSONIO)
url = "https://api.priceapi.com/jobs"
file.name = ".../output 1 .txt"
results = postForm(url, token="token",
country="country,
source="source",
currentness="currentness",
completeness="completeness,
key="key",
values=fileUpload(filename = file.name))
It returns "Error: Bad Request"
I also tried it using httr post request-
r = POST(url, body = list(token="token",
country="country,
source="source",
currentness="currentness",
completeness="completeness,
key="key",
values=upload_file(file.name)) )
Here upload_file is not uploading the contents of the file but, I am guessing it is passing the path to the file (as a string) into the "values" parmeter.
Naturally that does not return the correct results.
The result of the httr POST request is;
Response [https://api.priceapi.com/jobs]
Date: 2016-12-13 10:11
Status: 400
Content-Type: application/json; charset=utf-8
Size: 228 B
{
"success": false,
"reason": "parameter value invalid",
"parameter": "value",
"valid values": "An array or a string containing values separated by newline",
"comment": "Make sure the parameter 'value' has a valid value!"
I could solve this by using
file=readLines(".../output 1.txt")
inputValues <- paste(file,collapse="\n")
and then passing inputValues in the values parameter.

Using R complete -X POST in command line tool curl

I use the command line tool curl to post data and get response from server, the command is like this:
curl -X POST -H 'Content-Type: application/gpx+xml' -H 'Accept: application/json' --data-binary #gpslog.gpx "http://test.roadmatching.com/rest/mapmatch/?app_id=MY_APPID&app_key=MY_APPKEY" -o output.json
I tried using RCurl package to do the same thing, but it doesn't work. Can someone point me to the right direction? Thanks.
postForm(uri = "http://test.roadmatching.com/rest/mapmatch/?app_id=MYID&app_key=MYKEY",
.ops = list(httpheader = c('Content-type': 'application/gpx','Accept': 'application/json')),
.params = "/Users/data.gpx")
With httr - not tested, you may have to tweak it a bit
url <- "http://test.roadmatching.com/rest/mapmatch"
args <- list(app_id = "MY_APPID", app_key = "MY_APPKEY")
gpxxml <- add_headers(`Content-Type` = "application/gpx+xml")
httr::POST(url, query = args, gpxxml, accept_json(),
write_disk("output.json"), body = upload_file("gpslog.gpx"))

Resources