Requests to AWS Lambda HTTPS endpoint from R - r

I am trying to use the recently released AWS Lambda HTTPS endpoints feature: https://aws.amazon.com/blogs/aws/announcing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices
I have created an AWS Lambda function called multiply that expects an x and a y in the request body and returns the product. I created the HTTPS endpoint and set it to IAM authentication. Now, I'd like to call it from R with help of the aws.signature package.
The expected result is an HTTP response containing the Lambda function's output.
But I run into error "400 Bad Request". I suspect that the action parameter for aws.signature::signature_v4_auth must be set, but I can't figure out what it should be.
library(httr)
library(jsonlite)
function_url <- "https://<url-id>.lambda-url.eu-central-1.on.aws"
region <- "eu-central-1"
request_body <- toJSON(list(x = 2, y = 4), auto_unbox = TRUE)
headers <- list()
headers[["x-amz-date"]] <- format(Sys.time(), "%Y%m%dT%H%M%SZ", tz = "UTC")
headers[["host"]] <- function_url
headers[["content-type"]] <- "application/json"
signature <- aws.signature::signature_v4_auth(
datetime = headers[["x-amz-date"]],
region = region,
action = "",
service = "lambda",
verb = "POST",
canonical_headers = headers,
request_body = request_body,
key = "***",
secret = "***"
)
headers[["Authorization"]] <- signature[["SignatureHeader"]]
POST(
url = function_url,
body = request_body,
do.call(add_headers, headers)
)

There are two errors in the request:
The host should not include "https://". So the correct host is <url-id>.lambda-url.eu-central-1.on.aws
An empty action is not permitted. Use "/" instead.

Related

Body of a POST request

i'm trying to make a request to get the Acess Token, as described in the second step at https://developers.anbima.com.br/en/visao-geral/autenticacao/
The problem is with the variable body_anbima, the value expected at the server is like
REQUEST BODY
{
"grant_type": "client_credentials"
}
I tried many differents ways to write, but the better i could get was
"grant_type:client_credentials"
"{\"grant_type\":\"client_credentials\"}"
This is the code i'm using
library(httr)
library(jsonlite)
token_anbima <- base64_enc("aC2yaac23:1bhS45TT")
body_anbima <- {"grant_type:client_credentials"}
res <- POST('https://api.anbima.com.br/oauth/access-token',
add_headers("Content-Type"="application/json",
"Authorization"= paste("Basic", token_anbima)),
body = toJSON(body_anbima, auto_unbox=TRUE),
encode = 'json',
verbose()
)
res
rawToChar(res$content)
Using this code
library(httr)
base64_value <- openssl::base64_encode("your_client_id:your_client_secret")
response <-
POST(url = "https://api.anbima.com.br/oauth/access-token",
add_headers(Authorization = paste("Basic", base64_value)),
body = list(grant_type = "client_credentials"),
encode = "form")
response$status
content(response, "text")
Result
$ rscript token.R
[1] 201
[1] "{\"access_token\":\"**real_token**\",\"token_type\":\"access_token\",\"expire
s_in\":3600}"
You can test by Postman

Import data using API and httr (GET function) library

I want to import data using httr library using the code below. However, it gives strange output, which is not satisfied according to input in RequestTokenBody.
Additionally, there is a direct link, which works perfectly (and output using httr should be the same) -
https://ummapi.nordpoolgroup.com/messages?messageTypes=TransmissionUnavailability&statusActive&IncludeOutdated=false&publicationStartDate=2022-09-27&publicationStopDate=2022-10-28&areas=10Y1001A1001A39I
How can I import the same output as in a link , but using httr library?
library(httr)
url_message <- "https://ummapi.nordpoolgroup.com/messages"
#get response
RequestTokenBody <- list(messageTypes = "TransmissionUnavailability",
status = "Active",
publicationStartDate = "2022-09-27", #"eventStart": "2017-01-01T00:00:00.000Z"
publicationStopDate = "2022-10-28",
IncludeOutdated = "false",
areas = "10Y1001A1001A39I"
#limit = "1"
)
RequestResponse <- httr::GET(url_message,
#add_headers(Authorization = paste0(" Bearer ", token)),
body = RequestTokenBody,
encode = "json")
TokenContent <- httr::content(RequestResponse, "parsed", "application/json", encoding="json")
TokenContent

How do I fix "The query parameter [expansion] is not one of [usernames,expansions,tweet.fields,user.fields]" in twitter R Script

I am running the following code which is taken from https://developer.twitter.com/en/docs/tutorials/getting-started-with-r-and-v2-of-the-twitter-ap with some slight changes because it is doesn't seem to work.
library(rjson)
#https://developer.twitter.com/en/docs/tutorials/getting-started-with-r-and-v2-of-the-twitter-ap
Sys.setenv(BEARER_TOKEN="{mybearertoken}")
require(httr)
require(jsonlite)
require(dplyr)
bearer_token <- Sys.getenv("TWITTER_BEARER")
headers <- c(`Authorization` = sprintf('Bearer %s', bearer_token))
params <- list(`user.fields` = 'description',
`expansion` = 'pinned_tweet_id')
handle <- "codewryte"
url_handle <- paste("https://api.twitter.com/2/tweets/", handle)
#url_handle <-"https://twitter.com/TwitterDev/status/1228393702244134912"
response <-
httr::GET(url = url_handle,
httr::add_headers(.headers = headers),
query = params)
obj <- httr::content(response, as = "text")
x <- fromJSON(obj)
I get the following error:
$errors[[2]]$message
[1] "The query parameter [expansion] is not one of [usernames,expansions,tweet.fields,user.fields]"
$title
[1] "Invalid Request"
$detail
[1] "One or more parameters to your request was invalid."
$type
[1] "https://api.twitter.com/2/problems/invalid-request"
I also tried https://api.twitter.com/2/users/by/username/codewryte which is my user handle with the same message.
Does anyone understand what this message means and how I can fix it?
The problem was I was sending a list where a string needed to be sent.
response <-httr::GET(url = url_handle,
httr::add_headers(.headers = headers),
query="expansions=pinned_tweet_id&user.fields=created_at&tweet.fields=created_at")
I am not sure why the tutorial had this list.

Authorising access to Xero after 403 code using the Oauth2 in r

This is the step after the question that can be found here
I've run the following code:
pack <- c('curl','xml2','XML', 'plyr', 'dplyr','tidyr', 'httr', 'tools', 'lubridate',
'jsonlite', 'stringr', 'data.table', 'anytime', 'RCurl', 'rvest', 'opnessl', 'jose')
sapply(pack, function(x){
if(!require(x,character.only = T, quietly = T)) {install.packages(x, quiet = T)}
require(x, quietly = T, character.only = T)
})
#New Xero & WFM Api OAuth 2.0 credentials
Client_ID <- 'Your_Client_ID '
Client_secret<- 'Your_Client_secret'
XTID_Xero <- 'x30rscript'#Referral_ID
Redirect_URI <- 'https://developer.xero.com/' #OAuth 2.0 redirect URI
# Create the app
app <- oauth_app("RScript",
key = Client_ID,
secret = Client_secret,
redirect_uri = Redirect_URI
)
# Create the endpoint
create_endpoint <- function()
{
request <- "https://identity.xero.com/connect/token"
authorize <- "https://login.xero.com/identity/connect/authorize"
access <- "https://identity.xero.com/connect/token"
httr::oauth_endpoint(request, authorize, access)
}
api <- create_endpoint()
header <- httr::add_headers(Authorization=paste0("Basic ", RCurl::base64Encode(charToRaw(paste0(Client_ID, ":", Client_secret)))))
content_type <- httr::content_type("application/x-www-form-urlencoded")
# Define the scope - https://developer.xero.com/documentation/oauth2/scopes
scope_WFM <- "openid profile offline_access payroll.employees.read payroll.payruns.read payroll.payslip.read payroll.timesheets.read accounting.transactions.read accounting.reports.read accounting.journals.read"
# Get the code
httr::BROWSE(oauth2.0_authorize_url(api, app, scope = scope_WFM))
#get the code from the URL displayed in your browser
code_xero <- 'code_xero'
state_xero <- 'state_xero'
token <- httr::oauth2.0_token(
endpoint = api,
app = app,
scope = scope_WFM,
config_init = c(header, content_type),
use_basic_auth = TRUE,
query_authorize_extra = list(prompt = "login"),
type = "code",
credentials = oauth2.0_access_token(api, app, code_xero),
cache = FALSE
)
#get your xero-tenant-id
access <- GET("https://api.xero.com/connections", config = token)
connections <- content(access, 'text')
connections <- fromJSON(connections, flatten = T)
connections
# This is where I get an error....
GET("https://api.xero.com/api.xro/2.0/banktransactions",
config = token,
authenticate(Client_ID, Client_secret))
This returns the following:
Response [https://api.xero.com/api.xro/2.0/banktransactions]
Date: 2020-12-01 10:59
Status: 403
Content-Type: application/json
Size: 150 B
I'm trying to access Xero to pull out the current cash position, Debtors Days, Turnover/Profit/Growth and I'm struggling to a response from any of the areas I need in R.
Any help would be much appreciated.
I was actually searching too see if anyone else is trying to use R with Xero when this popped up.
So in case anyone else needs this, the solution is to pass the token with the headers. Using httr::add_headers this would be like so:
httr::GET("https://api.xero.com/api.xro/2.0/Invoices", config = token, httr::add_headers(`Xero-tenant-id` = tenant_id))

API OAuth 2.0 - XERO acces with R receiving status 400

We have to migrate to Oauth 2.0. However, I am facing the following issues. Status 400 I believe due to some parameters that may not be entered right. If anyone know what could be wrong or have any idea please let me know.
and this is my code:
pack <- c('curl','xml2','XML', 'plyr', 'dplyr','tidyr', 'httr', 'tools', 'lubridate',
'jsonlite', 'stringr', 'data.table', 'anytime')
sapply(pack, function(x){
if(!require(x,character.only = T, quietly = T)) {install.packages(x, quiet = T)}
require(x, quietly = T, character.only = T)
})
#New Xero & WFM Api OAuth 2.0 credentials
Client_ID <- 'YOUR_CLIENT_ID'
Client_secret<- 'YOUR_CLIENT_SECRET'
XTID <- 'YOUR_REFERAL_ID'#Referral_ID
Redirect_URI <- 'https://xero.com/' #OAuth 2.0 redirect URI
response <- GET(paste0('https://login.xero.com/identity/connect/authorize?response_type=code&client_id=',
Client_ID,'&redirect_uri=',Redirect_URI,'&scope=workflowmax%20offline_access'))
browseURL(response$url)
It works till here I am able to retrieve the first code, but I can't get the tokens
This is what Xero Doc said:
Xero Doc request:
POST https://identity.xero.com/connect/token
authorization: "Basic " + base64encode(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=xxxxxx
&redirect_uri=https://myapp.com/redirect
Now trying to get the token I tried several forms. however, they all look really similar.
code <- 'YOUR_CODE'
credentials = list();
credentials['grant_type'] <- "authorization_code"
credentials['code'] <- code
credentials['redirect_uri'] <- Redirect_URI
b64_id_secret <- base64_enc('YOUR_CLIENT_ID:YOUR_CLIENT_SECRET')
# user <- paste("Basic", user, sep = " ")
url <- 'https://identity.xero.com/connect/token'
POST(url, add_headers('Authorization'= paste0('Basic ', b64_id_secret)),
body = credentials,
verbose(), encode = 'form')
Response:
Response [https://identity.xero.com/connect/token?grant_type=authorization_code&code=YOUR_CODE&redirect_uri=https://waterlineprojects.com/]
Date: 2020-11-20 02:48
Status: 400
Content-Type: application/json; charset=UTF-8
Size: 27 B
XERO DOCUMENTATION: https://developer.xero.com/documentation/oauth2/overview
I did my workaround and got it running. This is the way to access the Oauth 2.0.
pack <- c('curl','xml2','XML', 'plyr', 'dplyr','tidyr', 'httr', 'tools', 'lubridate',
'jsonlite', 'stringr', 'data.table', 'anytime', 'RCurl', 'rvest', 'opnessl', 'jose')
sapply(pack, function(x){
if(!require(x,character.only = T, quietly = T)) {install.packages(x, quiet = T)}
require(x, quietly = T, character.only = T)
})
#New Xero & WFM Api OAuth 2.0 credentials
Client_ID <- 'YOUR_ID'
Client_secret<- 'YOUR_SECRET'
XTID_Xero <- 'YOUR_XTID'#Referral_ID
Redirect_URI <- 'YOUR_CALL_BACK_URL' #OAuth 2.0 redirect URI
# Create the app
app <- oauth_app("YOUR_API_NAME",
key = Client_ID,
secret = Client_secret,
redirect_uri = Redirect_URI
)
# Create the endpoint
create_endpoint <- function()
{
request <- "https://identity.xero.com/connect/token"
authorize <- "https://login.xero.com/identity/connect/authorize"
access <- "https://identity.xero.com/connect/token"
httr::oauth_endpoint(request, authorize, access)
}
api <- create_endpoint()
header <- httr::add_headers(Authorization=paste0("Basic ", RCurl::base64Encode(charToRaw(paste0(Client_ID, ":", Client_secret)))))
content_type <- httr::content_type("application/x-www-form-urlencoded")
# Define the scope
scope_WFM <- "openid profile offline_access payroll.employees.read payroll.payruns.read payroll.payslip.read payroll.timesheets.read accounting.transactions.read accounting.reports.read accounting.journals.read"
# Get the code
httr::BROWSE(oauth2.0_authorize_url(api, app, scope = scope_WFM))
#get the code from the URL displayed in your browser
code_xero <- 'YOR_CODE'
state_xero <- 'YOUR_STATE'
token <- httr::oauth2.0_token(
endpoint = api,
app = app,
scope = scope_WFM,
config_init = c(header, content_type),
use_basic_auth = TRUE,
query_authorize_extra = list(prompt = "login"),
type = "code",
credentials = oauth2.0_access_token(api, app, code_xero),
cache = FALSE
)
#get your xero-tenant-id
access <- GET("https://api.xero.com/connections", config = token)
connections <- content(access, 'text')
connections <- fromJSON(connections, flatten = T)
looks like you are close. Like MrFlick said without your client ID and starting a case with Xero API tech support (email api#xero.com with your client id and dat of log) its hard to know for sure.
One tip might be it, your redirect URI has to match exactly same value that is in your https://developer.xero.com/myapps/details?appId=<app_uuid> dashboard including an end slash.
Also - what is the body of the 400 error, there should be something like
{
"error": "invalid_grant"
}
Which will help you deduce what is wrong more easily.
https://developer.xero.com/documentation/oauth2/troubleshooting

Resources