google qpx query in Google script - google-apps-script

i'm tryng to request a (simple) flight-query trough google flight service via Apps Script
this is my code
function myFunction() {
var api_key = "XXXXXXXXXXXXXXX";
var url2= "https://www.googleapis.com/qpxExpress/v1/trips/search?key=" + api_key;
var param2 ={
"method" : "POST",
"contentType":"application/json",
"headers" : {"Content-Type": "application/json"
},
"request": {"passengers": {"adultCount": 1},
"slice": [{"origin": "BOS","destination": "LAX","date": "2015-03-01"}]
},
muteHttpExceptions : true
};
try {
var response = UrlFetchApp.fetch(url2,param2);
Logger.log(response)
} catch (e) {
Logger.log(e)
}
}
this request send me error code
"error": {"errors": [{
"domain": "global",
"reason": "badRequest",
"message": "Invalid inputs: received empty request."
}
],
"code": 400,
"message": "Invalid inputs: received empty request."
}
The qpx Api is loaded in my developer console....anyone has any idea?
thanks in advance

Two things, the body of the request must be specified with the "payload" property, not "request", and you must actually convert your Javascript Object to a JSON string before posting it. (You also don't need the "headers" property, "contentType" will suffice, but I don't think it hurts anything)
var param2 ={
"method" : "post",
"contentType":"application/json",
"payload": JSON.stringify({"passengers": {"adultCount": 1},
"slice": [{"origin": "BOS",
"destination": "LAX",
"date": "2015-03-01"
}]
}
),
muteHttpExceptions : true
};
It's all documented here: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)
However, the need to JSON.stringify() usually throws people off, if you pass a Javascript Object directly in the payload it is posted as form-encoded key/value pairs.

thanks very much...you put me in the right direction!
this is the right syntax:
var param2 ={
"method" : "post",
"contentType":"application/json",
"payload": JSON.stringify
(
{"request":
{"passengers": {"adultCount": 1},
"slice": [{"origin": "BOS",
"destination": "LAX",
"date": "2015-03-01"
}]
}
}
),
muteHttpExceptions : true
};

Related

Calling an Apps Script API Executable function with parameters from another Apps script issues

I developed an Apps Script called "sudofunctions" which execute sensitive commands using an elevated account. It is shared with the entire domain and executes as the author.
I then developed "clientFunctions" which can be run by any authenticated user and needs to invoke funcntions in sudofunctions.
sudofunctions has 2 functions so far
function test()
{
createUser("email#domain.com", "Full name")
}
function createUser(email, name)
{
console.log("Checkpoint Alpha")
}
clientFunctions then tries to call both these functions, calling test() works perfectly
var token = ScriptApp.getOAuthToken();
var options = {
"method" : "POST",
"headers": {"Authorization": "Bearer "+ token },
"payload" : {
"function": "test",
"devMode": "true"
},
muteHttpExceptions:true
}
var rest = UrlFetchApp.fetch("https://script.googleapis.com/v1/scripts/ABCXYZ:run", options)
However, calling createUser fails
var token = ScriptApp.getOAuthToken();
var options = {
"method" : "POST",
"headers": {"Authorization": "Bearer "+ token },
"payload" : {
"function": "createUser",
"parameters":["john#domain.com", "John Doe"],
"devMode": "true"
},
muteHttpExceptions:true
}
var rest = UrlFetchApp.fetch("https://script.googleapis.com/v1/scripts/ABCXYZ:run", options)
With 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."
}
]
}
]
}
}
According to the documentation, it should work.
https://developers.google.com/apps-script/api/reference/rest/v1/scripts/run#request-body
Any ideas where I am going wrong?
Thanks for the help.
In your script, from your error message, how about the following modification?
From:
var options = {
"method" : "POST",
"headers": {"Authorization": "Bearer "+ token },
"payload" : {
"function": "createUser",
"parameters":["john#domain.com", "John Doe"],
"devMode": "true"
},
muteHttpExceptions:true
}
To:
var options = {
"method": "POST",
"headers": { "Authorization": "Bearer " + token },
"contentType": "application/json",
"payload": JSON.stringify({
"function": "createUser",
"parameters": ["john#domain.com", "John Doe"],
"devMode": "true"
}),
"muteHttpExceptions": true
}
Reference:
Method: scripts.run

Cloud build API deploy:run on Google Apps Script doesn't work

I confirmed authorization with service account on GAS. "list" is work, but "run" method never work. Error msg is "source must not be empty". What kind of json should I attach?
This is on standalone GAS using GSApp library. (Apps-Script-GSApp-Library : MJ5317VIFJyKpi9HCkXOfS0MLm9v2IJHf)
function deploy() {
var jsonKey = JSON.parse(PropertiesService.getScriptProperties().getProperty("jsonKey"));
var serverToken = new GSApp.init(jsonKey.private_key, ["https://www.googleapis.com/auth/cloud-platform"], jsonKey.client_email);
var tokens = serverToken.addUser(jsonKey.client_email).requestToken().getTokens();
var url = "https://cloudbuild.googleapis.com/v1/projects/{ProjectId}/triggers/{TriggerId}:run";
var options = {
"muteHttpExceptions": true,
"method": "POST",
"headers": {
"Authorization":"Bearer "+tokens[jsonKey.client_email].token,
},
"source": {
"projectId": "{ProjectId}",
"branchName": "master",
"repoName": "repo"
}
}
Logger.log(UrlFetchApp.fetch(url,options));
}
{
"error": {
"code": 400,
"message": "source must not be empty",
"status": "INVALID_ARGUMENT"
}
}
UrlFetchApp.fetch() does not recognize "source" as a valid property. Use "payload" instead. Also you'll need to JSON.stringify() your payload and set the contentType property as application/json as follows:
var options = {
"muteHttpExceptions": true,
"method": "POST",
"contentType":"application/json",
"headers": {
"Authorization":"Bearer "+tokens[jsonKey.client_email].token,
},
"payload": JSON.stringify({
"projectId": "{ProjectId}",
"branchName": "master",
"repoName": "repo"
})
};

How to Retrieve (not create) Tasks from Asana using Apps Script & Personal Access Token

I am attempting to retrieve, but not create, tasks from Asana using Google Apps Script.
Using the Asana API Explore, I have constructed a URL that returns the data I desire: https://app.asana.com/api/1.0/tasks?opt_fields=name,assignee_status&assignee=987654321987654&completed_since=2018-02-22&limit=100&workspace=456789123456
This URL returns the desired data, in the following format:
{
"data": [
{
"id": 147258369147258,
"assignee_status": "inbox",
"name": "An example task name"
},
{
"id": 963852741963852,
"assignee_status": "upcoming",
"name": "And second example task name."
},
//etc...
]
}
With that URL as a model, I have created a Personal Access Token and executed the following function within Apps Script:
function getTasks5() {
// Asana Personal Token
var bearerToken = "Bearer " + "asdf123456789asdf456789456asdf";
//Request
var request = {
data: {
opt_fields: ["name", "assignee_status"],
assignee: "987654321987654",
completed_since: "2018-02-22",
limit: "100",
workspace: "456789123456"
}
};
// Request options
var options = {
method: "GET",
headers: {
"Authorization": bearerToken
},
contentType: "application/json",
payload: JSON.stringify(request)
};
var url = "https://app.asana.com/api/1.0/tasks";
var result = UrlFetchApp.fetch(url, options);
var reqReturn = result.getContentText();
Logger.log(reqReturn);
}
Instead of returning the desired data as the aforementioned URL does, the function creates an unnamed task in Asana, which is undesirable. It also returns this response containing undesired data:
{
"data": {
"id": 123456789123456,
"created_at": "2018-02-22T20:59:49.642Z",
"modified_at": "2018-02-22T20:59:49.642Z",
"name": "",
"notes": "",
"assignee": {
"id": 987654321987654,
"name": "My Name Here"
},
"completed": false,
"assignee_status": "inbox",
"completed_at": null,
"due_on": null,
"due_at": null,
"projects": [],
"memberships": [],
"tags": [],
"workspace": {
"id": 456789123456,
"name": "Group Name Here"
},
"num_hearts": 0,
"num_likes": 0,
"parent": null,
"hearted": false,
"hearts": [],
"followers": [
{
"id": 987654321987654,
"name": "My Name Here"
}
],
"liked": false,
"likes": []
}
}
Is it possible to simply GET a list of tasks in the manner exemplified by my first JSON example above without creating a task, and without resorting to using OAuth? If so, what changes to the Apps Script function need to be made?
Alright, the problem was with the approach I was taking. Rather than format the request with a payload (which infers a POST request), I needed to structure it more traditionally as a GET request, like so:
var requestUrl = "https://app.asana.com/api/1.0/tasks?opt_fields=name,assignee_status&assignee=123456789123&completed_since=2018-02-22&limit=100&workspace=987654321987";
var headers = {
"Authorization" : "Bearer " + AUTH_TOKEN
};
var reqParams = {
method : "GET",
headers : headers,
muteHttpExceptions: true
};
Then I was able to perform:
UrlFetchApp.fetch(requestUrl, reqParams);
And obtain the data I was after.

Use Apps Script URLFetchApp to access Google Datastore Data

I want to experiment with Google Datastore via Apps Script because I have a current solution based on Google sheets that runs into timeout issues inherent in constantly transacting with Drive files. I've created a test project in Google cloud with a service account and enabled library MZx5DzNPsYjVyZaR67xXJQai_d-phDA33
(cGoa) to handle the Oauth2 work. I followed the guide to start it up here and got all the pertinent confirmation that it works with my token (and that removing the token throws an 'authentication failed prompt').
Now I want to start with a basic query to display the one entity I already put in. I can use the API Explorer here and run this query body:
{
"query": {}
}
and get this result:
{
"batch": {
"entityResultType": "FULL",
"entityResults": [
{
"entity": {
"key": {
"partitionId": {
"projectId": "project-id-5200707333336492774"
},
"path": [
{
"kind": "Transaction",
"id": "5629499534213120"
}
]
},
"properties": {
"CommentIn": {
"stringValue": "My First Test Transaction"
},
"Status": {
"stringValue": "Closed"
},
"auditStatus": {
"stringValue": "Logged"
},
"User": {
"stringValue": "John Doe"
},
"Start": {
"timestampValue": "2017-08-17T18:07:04.681Z"
},
"CommentOut": {
"stringValue": "Done for today!"
},
"End": {
"timestampValue": "2017-08-17T20:07:38.058Z"
},
"Period": {
"stringValue": "08/16/2017-08/31/2017"
}
}
},
"cursor": "CkISPGogc35whh9qZWN0LWlkLTUyMDA3MDcwODA1MDY0OTI3NzRyGAsSC1RyYW5zYWN0aW9uGICAgICAgIAKDBgAIAA=",
"version": "1503004124243000"
}
],
"endCursor": "CkISPGogc35wcm9qZWN0LWlkLTUyMDAxxDcwODA1MDY0OTI3NzRyGAsSC1RyYW5zYWN0aW9uGICAgICAgIAKDBgAIAA=",
"moreResults": "NO_MORE_RESULTS"
}
}
I try to do the same thing with this code:
function doGet(e)
{
var goa = cGoa.GoaApp.createGoa('Oauth2-Service-Account',
PropertiesService.getScriptProperties()).execute(e);
if(goa.hasToken()) {var token = goa.getToken();}
var payload = {"query":{}}
;
var result = UrlFetchApp.fetch('https://datastore.googleapis.com/v1/projects/project-id-5200707333336492774:runQuery',
{
method: "POST",
headers: {authorization: "Bearer " + goa.getToken()},
muteHttpExceptions : true,
payload: payload
});
Logger.log(result.getBlob().getDataAsString());
}
and get this error in the logger:
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"query\": Cannot bind query parameter. 'query' 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 \"query\": Cannot bind query parameter. 'query' is a message type. Parameters can only be bound to primitive types."
}
]
}
]
}
}
If I try to use another word such as 'resource' or 'GqlQuery', I get this error:
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"GqlQuery\": Cannot bind query parameter. Field 'GqlQuery' 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 \"GqlQuery\": Cannot bind query parameter. Field 'GqlQuery' could not be found in request message."
}
]
}
]
}
}
I can't tell from the API Documentation what my syntax is supposed to be. Can anyone tell me how to compile a functional request body from Apps Script to Datastore?
You need to set the contentType of your payload as well as stringify your JSON payload as follows:
var result = UrlFetchApp.fetch(
'https://datastore.googleapis.com/v1/projects/project-id-5200707333336492774:runQuery',
{
'method':'post',
'contentType':'application/json',
'headers': {authorization: "Bearer " + goa.getToken()},
'payload':JSON.stringify(payload)
}
);

Insert post Blogger API failed in GAS

hi all iam trying insert post using GAS but failed.. can you tell me what im wrong... thx in advance....
here my code
`function sendHttpPost() {
var API_KEY = 'my api key';
var scope = "http://www.blogger.com/feeds/";
var oAuthConfig = UrlFetchApp.addOAuthService("blogger");
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey("anonymous");
oAuthConfig.setConsumerSecret("anonymous");
var payload =
{
"kind": "blogger#post",
"blog": {
"id": "486683248036684073"
},
"title": "A new post",
"content": "With <b>exciting</b> content..."
}
var options =
{
"contentType":"application/json",
"oAuthServiceName" : "blogger",
"oAuthUseToken" : "always",
"method" : "POST",
"payload" : payload
};
var respon = UrlFetchApp.fetch("https://www.googleapis.com/blogger/v3/blogs/486683248036684073/posts?key="+API_KEY, options);
and here is error message
Request failed for returned code 400. Server response: { "error": {
"errors": [ { "domain": "global", "reason": "parseError", "message":
"Parse Error" } ], "code": 400, "message": "Parse Error" } }
I believe you are trying to use oauth1 when oauth2 is required.
there already is a unanswered request about that here.
Implementing oauth 2 with Google app script is really a pain, so I made an attempt to build a library that could answer the need (dioxygen library) - it work a little bit like the oauth2 playground but it's less pretty.
With a little work you should be able to adapt it to your need with blogger.
I tried Harold's library, but after successfully retrieving OAuth token, I ended up with the same error.
But, when I issued the same JSON request as in my script through the API Explorer, it was processed:
https://developers.google.com/blogger/docs/3.0/reference/posts/insert
[UPDATE]
I am taking it back. This code works. I just replaced the payload variable and put the JSON request straight into URL fetch options. So there was some problem with passing that payload variable into options variable.
function testBlogger() {
var payload =
{
"kind": "blogger#post",
"blog": {
"id": "YOUR_BLOG_ID"
},
"title": "New post",
"content": "With content..."
};
var options =
{
"method" : "post",
"headers" : { "Authorization" : "Bearer YOUR_ACTIVE_TOKEN"},
"contentType" : "application/json",
"payload" : '{ "kind": "blogger#post", "blog": { "id": "YOUR_BLOG_ID" }, "title": "New post", "content": "With content..." }'
};
try {
var result = UrlFetchApp.fetch(
"https://www.googleapis.com/blogger/v3/blogs/YOUR_BLOG_ID/posts",
options);
Logger.log(result);
} catch (e) {
Logger.log(e);
}
}