Bad request error from UrlFetchApp when fetching the API url - spring-boot

I am getting the following error message: Bad request: [URL] when fetching the API URL using UrlFetchApp.
I need to pass the access token which has been received from the authorization server using a GET request.
My code is:-
function run()
{
var service = getOAuthService();
var authorizationUrl = service.getAuthorizationUrl();
Logger.log('Open the following URL and re-run the script: %s',
authorizationUrl);
Logger.log(JSON.stringify(service.getAccessToken(), null, 2));
if (service.hasAccess()) {
var url = 'https://ffa-int-service-lnhtqfum-zgvbwhku.apps.dev.aro.forgeapp.honeywell.com/get_graph_data';
var options =
{
method: 'GET',
headers: {
'Authorization' : 'Bearer ' + service.getAccessToken(),
},
muteHttpExceptions : true,
followRedirects: true
};
var response = UrlFetchApp.fetch(url,options);
var result = JSON.parse(response.getContentText());
Logger.log(JSON.stringify(result, null, 2));
} else {
var authorizationUrl = service.getAuthorizationUrl();
Logger.log('Open the following URL and re-run the script: %s',
authorizationUrl);
}
}

Related

Getting a 403 Forbidden error on plugin request

I'm trying to fire a plugin request from my ICN plugin. The request goes as below. However, I'm getting a 403 Forbidden error from the server.
Forbidden
You don't have permission to access /navigator/jaxrs/plugin on this server.
https://<icnserver.com>/navigator/jaxrs/plugin?repositoryId=Demo&query=%5B%7B%22name%22%3A%22ID%22%2C%22operator%22%3A%22LIKE%22%2C%22values%22%3A%5B%22123434234%22%2C%22%22%5D%7D%5D&className=Checks&plugin=DemoPlugin&action=DemoService&desktop=Demo
Plugin JS:
aspect.around(ecm.model.SearchTemplate.prototype, "_searchCompleted", function advisingFunction(original_searchCompleted){
return function(response, callback, teamspace){
var args = [];
var templateName = response.templates[0].template_name;
var res = response;
var requestParams = {};
requestParams.repositoryId = this.repository.id;
requestParams.query = query;
requestParams.className = templateName;
Request.invokePluginService("DemoPlugin", "DemoService",
{
requestParams: requestParams,
requestCompleteCallback: lang.hitch(this, function(resp) { // success
res.rows = resp.rows;
res.num_results = resp.rows.length;
res.totalCount = resp.rows.length;
args.push(res);
args.push(callback);
args.push(teamspace);
original_searchCompleted.apply(this,args);
})
}
);
}
});
You need to provide a security_token to be able to call your service, so you need to login first.
Then, open your browser's debug and check the requests in the network tab.
There you can see that every request that targets the /navigator/jaxrs/* URI will contain it, so something like this will be among the headers:
security_token: 163594541620199174
So my bet is that you have not set it in your client (I recommend a postman to test your service, or I would add a test (ICN) feature page in the ICN plugin project in order to be able to call it properly). In your feature page, you can call your service directly using the ecm/model/Request OOTB navigator dojo/javascript class, as you can see in CheckinAction.js:
_checkInDocument: function (item, requestData)
{
var self = this;
var payLoadObject = {requestType: "Get", id: item.id};
Request.postPluginService("DocuSignPlugin", "UpdateSignedDocumentService", "application/json", {
requestParams: {
repositoryId : item.repository.id,
serverType : item.repository.type,
docId : item.docid,
envelopeId: item.attributes.DSEnvelopeID,
payLoad: json.stringify(payLoadObject)
},
requestCompleteCallback: function(response) {
if (response.returncode == 0)
{
item.attributeDisplayValues.DSSignatureStatus = "Checkedin";
item.attributes.DSSignatureStatus = 4;
item.update(item);
}
else if (response.returncode == -1)
{
items = [];
items.push(item);
self._showLoginDialog(items);
}
},
backgroundRequest : false,
requestFailedCallback: function(errorResponse) {
// ignore handline failures
}
});
},
As you can see, you don't have to add the security_token to the requestParams, the framework will do it for you.

How to access lex session attributes in AWS lambda function

I wrote the below code to assign session attributes from my application,
var lexruntime = new AWS.LexRuntime();
var params = {
botAlias: 'PizzaOrder', /* required */
botName: 'PizzaOrder', /* required */
inputText: 'profile list', /* required */
userId: '160728846416', /* required */
sessionAttributes: {
//'<token>': cookies['token'],
'token': cookies['token'],
'communityid':cookies['communityid'],
'selectedAuthorId':cookies['selectedAuthorId'],
'kfurl':cookies['kfurl']
/* '<String>': ... */
}
};
//console.log("Cookies in index js "+cookies['token']);
lexruntime.postText(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
I want to access the session attributes in my lambda function using intentRequest.sessionAttributes.seesionattributename in the below code and as shown below
function GetAuthors2(intentRequest,callback) {
const token2 = String(intentRequest.sessionAttributes.token);
const communityid2 = String(intentRequest.sessionAttributes.communityid);
// --------- http start ---------
var options = {
hostname: 'kf6-stage.rit.albany.edu',
port: 443,
path: '/api/communities/'+communityid2+'/authors',
headers: {
'Content-Type' : "application/json",
'Authorization' : "bearer " + token2
}
};
https.get(options, (resp) => {
console.log("#in Http");
let data2 = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data2 += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
var data_2 = JSON.parse(data2);
const cList2 = [];
data_2.forEach(function(i){
cList2.push(i.firstName);
});
callback(close(intentRequest.sessionAttributes, 'Fulfilled',
{
contentType: "PlainText or SSML",
content: "Hi,You have "+cList2.length+" authors registered Bharghav. Here is the list \n"+ cList2.join()
}
));
});
});
}
but after the intent request I am getting the following response "Sorry, I was unable to process your message. Try again later."
If I hardcode the values in the lambda function it works fine.
Can someone kindly tell me where am I doing wrong in accessing the session attributes??
This worked for me. accessing the session attributes from the event/input. Then accessing the attribute by name.
exports.handler = async (event) => {
var attributes = event['sessionAttributes'];
console.log('attrs; ',attributes);
let sessValue;
if( attributes != null)
sessValue = attributes['fileName'];

How to use payload with method get?

I'm trying to learn how to query for data from a local government data site (hoping I can teach my math students to do some data analysis). I'm hoping to get the data and insert them into Google Sheets. The following is a sample provided by the official site on how to do a query:
var data = {
resource_id: '1b702208-44bf-4829-b620-4615ee19b57c', // the resource id
limit: 5, // get 5 results
q: 'jones' // query for 'jones'
};
$.ajax({
url: 'https://data.gov.sg/api/action/datastore_search',
data: data,
dataType: 'jsonp',
success: function(data) {
alert('Total results found: ' + data.result.total)
}
});$
I tried the following code in Google Apps Script:
function testapi(){
var data = {
resource_id: '1b702208-44bf-4829-b620-4615ee19b57c', // the resource id
limit: 5, // get 5 results
q: 'Yishun'
};
var url = "https://data.gov.sg/api/action/datastore_search";
var response = UrlFetchApp.fetch(url,data).getContentText();
}
I receive a 404 error. I think the option "data" was not passed.
Would appreciate some help. I am a math teacher, not a coding expert.
Update: I changed the code to this but still 404 error.
function testapi(){
var data = {
resource_id: '1b702208-44bf-4829-b620-4615ee19b57c', // the resource id
limit: 5, // get 5 results
q: 'Yishun' // query for 'jones'
};
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(data)
};
var url = "https://data.gov.sg/api/action/datastore_search";
var response = UrlFetchApp.fetch(url,options).getContentText();
}
Issue:
Whenever payload key is present in options/params argument of UrlFetchApp, the method is set to post by default. And any attempt to change the method to get is "silently" ignored. Other similar scripting platforms automatically convert the payload to url query parameters. But, UrlFetchApp silently changes the method to post and nothing else.
Solution:
Re-create the data object as a query string. For example, data:{x:1,y:2} should be changed to ?x=1&y=2 and appended to url.
Snippet:
function testapi() {
var options = {
method: 'get',
// 'contentType': 'application/json',
// 'payload' : data,//If set, method is ignored.
headers: { Accept: '*/*', 'Content-Type': 'application/json' },
muteHttpExceptions: true,
};
var url = 'https://data.gov.sg/api/action/datastore_search';
//var url = 'https://httpbin.org/get'; test the method
function objectToQueryParams(obj) {
return (
'?' +
Object.entries(obj)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&')
);
}
var data = {
resource_id: '1b702208-44bf-4829-b620-4615ee19b57c', // the resource id
limit: 5, // get 5 results
q: 'Yishun', // query for 'Yishun'
};
var query = objectToQueryParams(data);
url += query;
var response = UrlFetchApp.fetch(url, options).getContentText();
Logger.log(response);
}
function objectToQueryParams(obj) {
return (
'?' +
Object.entries(obj)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&')
);
}
var data = {
resource_id: '1b702208-44bf-4829-b620-4615ee19b57c', // the resource id
limit: 5, // get 5 results
q: 'Yishun', // query for 'jones'
};
console.log(objectToQueryParams(data));
Related:
UrlSearchParams

Slack WebAPI fails with not_authed

I'm attempting to post interactive messages to slack as a Bot User (using chat.postMessage, etc).
Although I am passing in the Bot Access Token (as received from the initial OAuth) I keep getting an error response stating "not_authed".
I get the same when I attempt auth.test.
I'm doing something like the following with "request" in node.js:
app.get("/testAuth/test", function(req,res){
console.log("in testAuth/test...sending test message to Slack");
var bToken = process.env.TESTBOT_ACCESS_TOKEN;
var slackMessageURL = "https://slack.com/api/auth.test";
var postOptions = {
uri: slackMessageURL,
method: "POST",
token: bToken
};
request(postOptions, (error, response, body) => {
if(error){
console.log("OOPPPPS....we hit an error in auth.test: " + error);
} else {
console.log("auth.test response: " + JSON.stringify(response));
}
});
res.send("Sent Test...check logs");
});
which results with:
auth.test response: {"statusCode":200,"body":"{\"ok\":false,\"error\":\"not_authed\"}",...
According to the Slack WebAPI docs, if I'm posting as the Bot, I should use the Bot's access token (as received from the initial oauth), but figure I'm either formatting my request incorrectly, or the token is not what Slack is expecting.
Ok, after talking with Slack support, it appears (at least) the WebAPIs I am calling don't yet support application/json. These do work with x-www-form-urlencoded.
Looking at this post
I was able to cobble together the following which auth'd successfully:
//up top
var request = require("request");
var querystring = require("querystring");
//...
app.get("/testAuth/test", function(req,res){
console.log("in testAuth/test...sending test message to Slack");
var bToken = process.env.TESTBOT_ACCESS_TOKEN;
var message = {
token: bToken
};
var messageString = querystring.stringify(message);
var messageLength = messageString.length;
var slackMessageURL = "https://slack.com/api/auth.test";
var postOptions = {
headers: {
"Content-length": messageLength,
"Content-type": "application/x-www-form-urlencoded"
},
uri: slackMessageURL,
body: messageString,
method: "POST"
};
request(postOptions, (error, response, body) => {
if(error){
console.log("OOPPPPS....we hit an error in auth.test: " + error);
} else {
console.log("auth.test response: " + JSON.stringify(response));
}
});
res.send("Sent Test...check logs");
});

Parse Response Variable Issues with HTTP Request and Cloud Code

I am trying to run an HTTP Request in an afterSave. It executes correctly, but im getting errors with the response variable I was told to put in the end.
Here is the code
Parse.Cloud.afterSave("ArtPiece", function(request) {
var artistURL = 'http://www.gallery-admin-dev.iartview.com/Gilmans/imageSave.php';
var artPiece = request.object;
if (typeof request.image === "undefined") {
var pieceName = artPiece.get("piece_name");
var url = artPiece.get("imageURL");
Parse.Cloud.httpRequest({
url: artistURL,
params: {
pieceName : pieceName,
url : url
},
success: function(httpResponse) {
response.success();
},
error: function(httpResponse) {
response.error('Request failed with response code ' + httpResponse.status)
}
});
}
});
The problem is the success and error functions.
Things I have tried that have not worked:
Putting response as a second parameter in the afterSave Call (it says can not call .success of an undefined variable)
Getting rid of the response lines of code (Result: success/error was not called)
Calling Response as its own function response('Request failed with response code ' + httpResponse.status) it just says response is undefined.
I dont really care about having any response or not, I just want the code to work properly.
How is this 'response' variable supposed to be set up?
Thank you!
There was an extra url in the parameters, a reference to a probably undefined artistURL...
Parse.Cloud.afterSave("ArtPiece", function(request) {
var artistURL = 'http://www.gallery-admin-dev.iartview.com/Gilmans/imageSave.php';
var artPiece = request.object;
if (typeof request.image === "undefined") {
var pieceName = artPiece.get("piece_name");
var url = artPiece.get("imageURL");
var params = { pieceName : pieceName };
return Parse.Cloud.httpRequest({ url: artistURL, params: params });
}
});

Resources