Executing an HTTP POST request on Groovy - json

So I got the short straw at work and I have to learn some Groovy. I'm part of the infrastructure team, so I don't know a lot.
Basically what I have to do is:
- Get an event (DONE)
- Parse the event with an specific json format (WORKING ON IT)
- Make a POST request against the API (NOT DONE AT ALL)
So, I'm having some problems to test the POST request I'm making.
This is my code:
//def post = new URL("https://httpbin.org/post").openConnection();
//def message = '{"message":"this is a message"}'
def post = new URL("https://api.duckduckgo.com").openConnection();
def message = '{"q=DuckDuckGo&format=json&pretty=1"}'
post.setRequestMethod("POST")
post.setDoOutput(true)
post.setRequestProperty("Content-Type", "application/json")
post.getOutputStream().write(message.getBytes("UTF-8"));
def postRC = post.getResponseCode();
println(postRC);
if(postRC.equals(200)) {
println(post.getInputStream().getText());
}
This is the response, the first test is from httpbin.org, the second test is from duckduckgo:
root#test:/mnt/c/groovy-dev/test# groovy post.groovy
200
{
"args": {},
"data": "{\"message\":\"this is a message\"}",
"files": {},
"form": {},
"headers": {
"Accept": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2",
"Content-Length": "31",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "Java/1.8.0_221"
},
"json": {
"message": "this is a message"
},
"origin": "190.188.58.175, 190.188.58.175",
"url": "https://httpbin.org/post"
}
root#test:/mnt/c/groovy-dev/test# groovy post.groovy
500
I got a response from httpbin, but not from duckduckgo. I don't know if I'm doing something wrong or there is a problem with the API. Although I tested it with Postman and its working correctly.
What I'm missing?
Also, the API I will have to access in the end, uses authentication. Do you have any suggestion how to handle it?
Thanks

Related

Step Functions: Passing in json to RequestBody to API Gateway via POST method

so I have a json that is being received by another API Gateway that is invoked.
I want to pass this json in another Task that invokes another API Gateway. I tried to include it in the RequestBody via the $ identifier but it literally sends this without the JSON. Attempting to add ResultPath or InputPath on this Task throws error.
{
"ApiEndpoint": "fasdffasd.execute-api.us-east-1.amazonaws.com",
"Method": "POST",
"Headers": {
"Content-Type": [
"application/json"
]
},
"Stage": "uat",
"Path": "/v1/order/create",
"RequestBody": {
"Payload": "$" <---the JSON received by this Task from the previous Task
},
"AuthType": "IAM_ROLE"
}
The issue is checking CloudWatch Logs I can see that literally the dollar sign as a string is returned. I expected a JSON object.

event.body in lambda function is not an object even though application/json header exists

I have an API Gateway / lambda function set up with a LAMBDA_PROXY integration.
I have a POST resource which is sending a JSON object in the body like the following:
{
"version": 123,
"attributes": [
{
"id": 1123,
"type": "integer",
"defaultValue": 88
}
]
}
The POST request is sent with a Content-Type: application/json header.
I expect the lambda function to receive event.body as an object so that I will be able to reference the object like this:
const version = event.body.version;
In fact, this does not work and I am forced to run a JSON.parse() on event.body.
At first I was thinking that the content-type header was not getting to the lambda but then I printed to the log event.headers and the header is in fact there:
{
"Accept": "*/*",
"content-type": "application/json",
"Host": "jfpvip409c.execute-api.eu-west-1.amazonaws.com",
"User-Agent": "curl/7.65.0",
"X-Amzn-Trace-Id": "Root=1-5fe9940a-3f3634ce4ccd26f5211c21d1",
"X-Forwarded-For": "192.118.35.111",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
}
Can somebody please help me understand why this is the case ?
Thanks in advance
nsteiner

How do you pass parameters to a Deployed Google Apps Script API function?

I created a test function (doPost) in a Google Apps Script API using Google Cloud Platform (GCP). I am now trying to call that function from another script in the same project.
I know I am almost there, because this code works:
var token = ScriptApp.getOAuthToken();
var header = {
"Authorization": "Bearer " + token,
"function": "doPost",
"devMode": true,
};
var options = {
"method": "POST",
"headers": header,
"muteHttpExceptions": true,
"payload": {
"function": "doPost",
"devMode": true
}
};
var url = 'https://script.googleapis.com/v1/scripts/xxxxxxxxxxxxxxxxxxxx:run';
var response = UrlFetchApp.fetch(url, options);
However, when I try to include a parameter in payload above, it no longer works:
"payload": {
"function": "doPost",
"parameters": ['1'],
"devMode": true
}
Following other stackoverflow answers, I've tried using in the header:
"contentType": 'application/json',
And accordingly, for the payload:
"payload": JSON.stringify({
"function": "doPost",
"parameters": ['1'],
"devMode": true
})
Whenever I use "JSON.stringify", even without parameters (just like the situation I got to work), it errors out.
With JSON.stringify (and parameters in the payload), I get a worse error, which seems to say it doesn't like any of the payload:
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"{\"function\":\"doPost\",\"parameters\":[1007],\"devMode\":true}\": Cannot bind query parameter. Field '{\"function\":\"doPost\",\"parameters\":[1007],\"devMode\":true}' could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"{\"function\":\"doPost\",\"parameters\":[1007],\"devMode\":true}\": Cannot bind query parameter. Field '{\"function\":\"doPost\",\"parameters\":[1007],\"devMode\":true}' could not be found in request message."
Without JSON.stringify (and with parameters in the payload), I get the error:
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"parameters\": Cannot bind query parameter. 'parameters' is a message type. Parameters can only be bound to primitive types.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"parameters\": Cannot bind query parameter. 'parameters' is a message type. Parameters can only be bound to primitive types."
Finally, it doesn't matter what I do with parameters. I'm pretty sure it should be in the format I put above, but I've also tried:
"parameters": [1]
"parameters": 1
"parameters": "1"
among others.
The doPost script is simple for now:
function doPost(parameters) {
Logger.log('parameters = ' + parameters);
return "Hello";
}
Here is the stackoverflow question that seems to be most like this: Apps Script API returning 404 error for existing project. Error returned as HTML rather than JSON, but doesn't seem to answer my problem.
I've studied the scripts.run page about parameters: https://developers.google.com/apps-script/api/reference/rest/v1/scripts/run#authorization-scopes, along with many other pages, including the URL Fetch Service: https://developers.google.com/apps-script/reference/url-fetch.
This is certainly not my first time using UrlFetchApp in Google Apps Script, but it is when calling my own GAS API.
Any help would be greatly appreciated!
Thanks!
Not long after I posted this, and after continuing to see post after post say that you should use JSON.stringify for the payload and contentType: application/json in the header, in the header I changed:
"contentType": "application/json"
to
"Content-Type": "application/json"
and it works now!

Trying to send access token from loopback to third party api

I have my API in loopback 3.x. First I created an empty project and right after that I ran npm install loopback-connector-rest --save and lb datasource in the console to have a link to an external API called Userlike. It this URL https://www.userlike.com/api/external/message/chat_meta/.
Then I created a model with no parameters called Messages.
I had no problems executing as I used node . and there was no error, and in localhost:3000 I could visualize my API.
But I had a problem when I clicked GET in the page a 401 error because to access the API in Userlike I needed to send my token so I could get the data, so I modified the datasources.json file and I had this:
{
"userlikeRESTdatasource": {
"name": "userlikeRESTdatasource",
"baseURL": "https://www.userlike.com/api/external/message/chat_meta/",
"crud": false,
"connector": "rest",
"operations": [
{
"functions": {
"getMessages": []
},
"template": {
"method": "GET",
"url": "https://www.userlike.com/api/external/message/chat_meta/",
"headers": {
"accepts": "application/json",
"content-type": "application/json",
"authorization": "8c149a3d-4acf-362e-880c-30ec2f5ecaf"
},
"responsePath": "$.results.*"
}
}
]
}
}
The authorization field I put in the header didn't work as I still received
{
"error": {
"statusCode": 401,
"name": "Error",
"message": "Authorization Required",
"stack": "Error: Authorization Required\n
}
}
My idea was to do something like:
headers.append('Authorization', '8c149a3d-4acf-362e-880c-30ec2f5ecaf7');
headers.append('Access-Control-Allow-Origin', '*');
headers.append('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
headers.append('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Authorization, Accept');
But with loopback. So I could receive the data from the Userlike API and next I could modify or just use the data I wanted.
But I still can't figure out how can I modify my datasources.json or if I need to create something in another file to make it possible to send the token as the authorization to that URL I'm using.
Pass access token with HTTP header by using this
headers.append('X-Access-Token', '8c149a3d-4acf-362e-880c-30ec2f5ecaf7');
or also pass this token as a parameter.
?access_token=8c149a3d-4acf-362e-880c-30ec2f5ecaf7
This will help.

api access token post request, where to start

I've been struggling learning Auth for several months now, it comes down to I don't know where to start, it seems there are a bunch of different methods.
I am using an API that provides a token called "Personal Access Token".
Does this mean it's a Bearer or Web Token? I'm lost with this terminology.
They allow you to play with their API in their online tools. I am making a POST request.
The api provides this info:
Link to send Post Request: www.hackerrank.com/restoflink
Request Headers:
{
"Content-Type": "application/json",
"Accept": "application/json",
"Content-Length": 190
}
Request Body:
{
"username": "testing",
"subject": "test",
"message": "test",
"send_email": "true",
"force": "false",
"hide_login_credentials": "true",
"access_token": "Access Token Number"
}
Here is my code:
function onFormSubmission(e){
var accessToken ="ACCESS_TOKEN";
var options = {
method: "post",
headers: {
"Accept": "application/json",
"Authorization": "Bearer " + accessToken
},
payload: {
"username": "testing#gmail.com",
"subject": "test",
"message": "test",
"send_email": "true",
"force": "false",
"hide_login_credentials": "true",
"access_token": "ACCESS TOKEN",
"muteHttpExceptions": "false",
"contentType": "application/json"
}
}
var response = UrlFetchApp.fetch("linkhere", options);
Logger.log(response.getResponseCode())
Logger.log(response.getContentText());
}
When I run this code without the bearer token in the header, I get a "404 truncated server error, "Invalid Access Token"".
This is why I include the token in the in header ("I'm guessing it is a Bearer Token)
The response I get from the request is 200 but it doesn't perform the action I expect it to.
I'm confused on what adjustment I have to make, even though I'm getting at 200 response code, something isn't working with my request from Apps Script.
I tried making the request from POSTMAN and the api's test tools and all my attempts worked, which makes me believe I am doing something wrong in my script.
Any help would be greatly appreciated, this post already helped out a lot!
Here was my error:
UrlFetchApp.fetch("www.hackerrank.com/x/api/v2/tests?duration=-1&access_token=123", options)
URL: ""
I had to add 'https://', for a while I used 'http' and that didn't work.
They call it a permanent OAuth token in their documentation (linked from your comments), but the way they use it is very simple and not like the OAuth implementations I've worked with in the past.
You don't need to include the access token in your headers, simply append &access_token=[your token] to the URL ("linkhere") of your request.
Example:
UrlFetchApp.fetch("www.hackerrank.com/x/api/v2/tests?duration=-1&access_token=123", options)