Implement curl request in R - r

I am trying to access the Amadeus travel API
To obtain a token, the given curl is:
curl "https://test.api.amadeus.com/v1/security/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}"
My RScript Attempt is:
library("httr")
# Get Token
response <- POST("https://test.api.amadeus.com/v1/security/oauth2/token",
add_headers("Content-Type" = "application/x-www-form-urlencoded"),
body = list(
"grant_type" = "client_credentials",
"client_id" = API_KEY,
"client_secret" = API_SECRET),
encode = "json")
response
rsp_content <- content(response, as = "parsed", type = "application/json")
rsp_content
Resulting in the error:
Response [https://test.api.amadeus.com/v1/security/oauth2/token]
Date: 2021-07-23 00:59
Status: 400
Content-Type: application/json
Size: 217 B
{
"error":"invalid_request",
"error_description": "Mandatory grant_type form parameter missing",
"code": 38187,
"title": "Invalid parameters"
}
>
What is the correct way to call this API to obtain a token using R?

The curl -d option is used to send data in the same way an HTML form would. To match that format, use encode="form" rather than encode="json" in the call to POST().

Related

POST request with httr fails while shell request works

I am trying to get data from an API with a POST request. The request works well with a direct shell command :
system(sprintf('curl POST -k --tlsv1.2 -v "https://api-gateway.inpi.fr/services/apidiffusion/api/marques/search" -H "X-XSRF-TOKEN: %s" -H \'accept: application/xml\' -H "Content-Type: application/json" -H "Cookie: XSRF-TOKEN=%s; access_token=%s; session_token=%s" -d \'%s\' > test.xml',token,token,access_token,refresh_token,json_request))
However, I would like to use httr for many reasons. I use the following code :
test <- httr::POST(
"https://api-gateway.inpi.fr/services/apidiffusion/api/marques/search",
httr::set_config(config(ssl_verifypeer = 0L)),
config = (add_headers(
"X-XSRF-TOKEN" = token,
"accept" = "application/xml",
"Content-Type" = "application/json",
"Cookie" = sprintf("XSRF-TOKEN=%s; access_token=%s; session_token=%s",token,access_token,refresh_token)
))
,set_cookies(`X-XSRF-TOKEN` = token,
`XSRF-TOKEN` = token,
access_token = access_token,
session_token = refresh_token)
,body = json_request
)
But this returns a 403 Forbidden error (my_token being the token I use) :
$error
[1] "access_denied"
$error_description
[1] "Invalid CSRF Token '*my_token*' was found on the request parameter '_csrf' or header 'X-XSRF-TOKEN'.
It seems like httr did not take into account my cookies because the token is different inside the test object I create :
> test2$cookies
domain flag path secure expiration name value
1 api-gateway.inpi.fr FALSE / FALSE <NA> XSRF-TOKEN *another_token*
Any idea ? I am sorry that I can't create a reproducible example for obvious security reasons.
Thank you !
The solution was wierd.
I had to rid off from httr, I used UNIX system commands instead, and it worked with the same request.
system(sprintf('curl POST -k --tlsv1.2 "https://api-gateway.inpi.fr/services/apidiffusion/api/marques/search" -H "X-XSRF-TOKEN: %s" -H \'accept: application/json\' -H "Content-Type: application/json" -H "Cookie: XSRF-TOKEN=%s; access_token=%s; session_token=%s" -d \'%s\' > %s/res.json',tokens$xsrf_token,tokens$xsrf_token,tokens$access_token,tokens$refresh_token,json_request,tempdir()))
It seems like httr tries to handle cookies by its own, so maybe that's what caused my problem.

Send email with MailerSend API and R

I am trying to use the transaction email service MailerSend to send an email from R.
They have cURL instructions as to how to do this.
I don't think I have the formatting quite right as I get the error:
> response
Response [https://api.mailersend.com/v1/email]
Date: 2021-02-26 19:49
Status: 401
Content-Type: application/json
Size: 30 B
> rsp_content <- content(response, as = "parsed", type = "application/json")
> rsp_content
$message
[1] "Unauthenticated."
R Script to send an email
library("httr")
# MailerSend API Key
apiKeyMS <- Sys.getenv("MS_KEY")
# Email header info
email_from = "noreply#example.ca"
email_from_name = "Joe"
email_subject <- "Joe Update"
email_to <- "joe#gmail.com"
# Email Body
email_text <- "This is my email"
email_html <- "This is my email"
# Send Email
ms_url <- paste0("https://api.mailersend.com/v1/email")
response <- POST(ms_url,
add_headers("Authorization: Bearer" = apiKeyMS,
"X-Requested-With" = "XMLHttpRequest",
"Content-Type" = "application/json"),
body = list(
"subject" = email_subject,
"from" = email_from,
"from_name" = email_from_name,
"to" = email_to,
"text" = email_text,
"html" = email_html
), encode = "json")
#############################################################
Basic MailerSend cURL instructions
curl -X POST \
https://api.mailersend.com/v1/email \
-H 'Content-Type: application/json' \
-H 'X-Requested-With: XMLHttpRequest' \
-H 'Authorization: Bearer {place your token here without brackets}' \
-d '{
"from": {
"email": "your#email.com"
},
"to": [
{
"email": "your#email.com"
}
],
"subject": "Hello from MailerSend!",
"text": "Greetings from the team, you got this message through MailerSend.",
"html": "Greetings from the team, you got this message through MailerSend."
}'
I don't know R at all, but I would guess your bearer token is incorrect.
The header key is Authorization and the value should be "Bearer {place your token here without brackets}"
You have to have these three headers
-H 'Content-Type: application/json' \
-H 'X-Requested-With: XMLHttpRequest' \
-H 'Authorization: Bearer {place your token here without brackets}' \`

How to make a POST request with header and data options in R using httr::POST?

I am trying make a POST request with data and header information using httr::POST. I can see how to make a POST request, but I am unable to get it to work with curl's data (-d) and header (-H) options.
This works perfectly in my terminal (obviously with different data/api, but exactly the same format)
curl -H "Accept: application/json" -H "Content-type: application/json" -d '{"name": "Fred", "age": "5"}' "http://www.my-api.com"
Question
How can the above POST request be made (with headers and data) using httr::POST ?
What I've tried so far
library(jsonlite)
my_data <- list(name="Fred", age="5") %>% toJSON
post_url <- "http://www.my-api.com"
r <- POST(post_url, body = my_data) # Data goes in body, I guess?
stop_for_status(r)
I get
Error: Bad Request (HTTP 400).
Inspecting r further
r
Response ["http://www.my-api.com"]
Date: 2019-07-09 17:51
Status: 400
Content-Type: text/html; charset=UTF-8
<EMPTY BODY>
You could try this; with content type and headers added:
link <- "http://www.my-api.com"
df <- list(name="Fred", age="5")
httr::POST(url = link,
body = jsonlite::toJSON(df, pretty = T, auto_unbox = T),
httr::add_headers(`accept` = 'application/json'),
httr::content_type('application/json'))

Translating a curl command to R using httr (specifically '--data-binary #')

I am trying to transcribe some sound files to text using bing speech-to-text.
The following command works in command line (using git bash on Windows 10):
curl -v -X POST "https://speech.platform.bing.com/speech/recognition/interactive/
cognitiveservices/v1?language=<LANG>&format=detailed" -H "Transfer-Encoding:
chunked" -H "Ocp-Apim-Subscription-Key: <MY KEY>" -H "Content-type:
audio/wav; codec=audio/pcm; samplerate=16000" --data-binary #<MY .WAV-FILE>
I've tried this, but it doesnt work:
httr::POST(url = myURL,
add_headers("Ocp-Apim-Subscription-Key" = key,
"Content-type" = "audio/wav; codec=audio/pcm; samplerate=16000",
"Transfer-Encoding" = "chunked"),
body = (list("file" = upload_file("PATH_TO_FILE.wav"))),
verbose())
It returns this output:
Response
[https://speech.platform.bing.com/speech/recognition/dictation/
cognitiveservices/v1?language=<LANG>&format=detailed]
Date: 2017-11-29 13:29
Status: 200
Content-Type: text/plain
Size: 75 B
I believe that the request is related to the interpretation of the .wav file, and that I need to somehow add the '--data-binary' tag to the httr-request. I can see that my "content-type" is plain text, although i've specified. Furthermore: the API documentation specifies that i need to prefix my wav-file with an at-sign.
Any help would be much appreciated.
cheers.
EDIT: Link to API documentation
https://learn.microsoft.com/da-dk/azure/cognitive-services/speech/getstarted/getstartedrest?tabs=curl#tabpanel_AFC9x30-dR_curl
I figured it out.
The key is to set the proper MIME type in the body. Not setting this MIME type can result in wrongful interpretation on the receiving end, even though we get a response 200 back.
body <- list(file = httr::upload_file(
paste0(path, "/", f),
type = "audio/wav; codec=audio/pcm; samplerate=16000"))
where paste0(path, "/", f) is a path to an audio file.
myURL <- sprintf('https://speech.platform.bing.com/speech/recognition/%s/cognitiveservices/v1?language=%s&format=%s',
"dictation",
"da-DK",
"detailed")
rs <- httr::POST(
url = myURL,
httr::add_headers(.headers = c("Ocp-Apim-Subscription-Key" = key)),
httr::add_headers(.headers = c("Transfer-Encoding" = "chunked")),
body = body)

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.

Resources