Google calendarList not returning calendars - google-apps-script

The following Apps Script code in a Chrome extension does not error, but return no calendars:
chrome.identity.getAuthToken({interactive: true}, function(token)
{
var init =
{
method: 'GET',
async: true,
headers:
{
Authorization: 'Bearer ' + token,
'Content-Type': 'application/json'
},
'contentType': 'json'
};
fetch('https://www.googleapis.com/calendar/v3/users/me/calendarList?minAccessRole=writer&key=' + apiKey, init)
.then(function(data)
{
log('Object ' + JSON.stringify(data));
});
});
I just get this in the console: Object {}
I saw this post and tried the suggestions, no luck. The apiKey came from the API console, and works in a different call. Thanks for any tips or pointers.
Edit #2: Here is my current manifest.json:
"oauth2": {
"client_id": "123456780416-17ur6mlc88sfot8e4s2pq05ehtkd8klh.apps.googleusercontent.com",
"scopes":[
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/contacts.readonly",
"https://www.googleapis.com/auth/calendar"
]
}

If you are passing a token into the options of the fetch request, you do not need an API key.
Modify
fetch('https://www.googleapis.com/calendar/v3/users/me/calendarList?minAccessRole=writer&key=' + apiKey, init)
to
fetch('https://www.googleapis.com/calendar/v3/users/me/calendarList?minAccessRole=writer', init)
and define init as
var init = {
"method":"get",
"async": true,
"muteHttpExceptions": true,
"headers": {
"Authorization": "Bearer " + token
},
"contentType": "application/json",
}
Also make sure that your token contains the necessary scopes.

Related

Google Apps Script call Address Validation API

Simple code and straightforward. It works with postman but fails with Apps Script.
function validateAddress () {
const url = 'https://addressvalidation.googleapis.com/v1:validateAddress?key=';
const apikey = '...';
let payload, options, temp;
payload = JSON.stringify({
"address": {
"addressLines": "1600 Amphitheatre Pkwy"
}
});
options = {
'muteHttpExceptions': true,
'method': 'POST',
'Content-Type': 'application/json',
'body': payload
}
temp = UrlFetchApp.fetch(url + apikey, options);
Logger.log(temp)
}
Error:
{
"error": {
"code": 400,
"message": "Address is missing from request.",
"status": "INVALID_ARGUMENT"
}
}
EDIT:
Change options to
options = {
'muteHttpExceptions': true,
'method': 'POST',
'Content-Type': 'application/json',
'payload': payload
}
Gives error:
{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"{\"address\":{\"addressLines\":\"1600 Amphitheatre Pkwy\"}}\": Cannot bind query parameter. Field '{\"address\":{\"addressLines\":\"1600 Amphitheatre Pkwy\"}}' 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 \"{\"address\":{\"addressLines\":\"1600 Amphitheatre Pkwy\"}}\": Cannot bind query parameter. Field '{\"address\":{\"addressLines\":\"1600 Amphitheatre Pkwy\"}}' could not be found in request message."
}
]
}
]
}
}
Documentation:
https://developers.google.com/maps/documentation/address-validation/requests-validate-address
From the documentation, it seems that addressLines is an array of string, not a string. Does that change something ? (I don't have a key, so I cannot try myself).
And more important, your options object is incorrect (check doc). It should be
options = {
'muteHttpExceptions': true,
'method': 'POST',
'contentType': 'application/json',
'payload': payload
}
I don't know why it works but changed options to
options = {
'muteHttpExceptions': true,
'method': 'POST',
'headers': {
'Content-Type': 'application/json'
},
'payload': payload
}
Solves the problem.

Obtain Access token to Docusign using Google Apps Script

I am tying to obtain Access Token using Google Apps Script.
Ref: https://developers.docusign.com/platform/auth/jwt/jwt-get-token/
Using Postman, I can get the ACCESS TOKEN by posting a request using this URL: https://account-d.docusign.com/oauth/token
and this two fields in the body:
grant_type : urn:ietf:params:oauth:grant-type:jwt-bearer
assertion : MY_JSON_WEB_TOKEN
How do I replicate tis in Apps script?
After endless hours of trial and error I still get this error: {"error":"invalid_grant","error_description":"unsupported_grant_type"}
The script:
function obtainAccessToken(){
const JWT = MY_JSON_WEB_TOKEN;
const URL = 'https://account-d.docusign.com/oauth/token';
const PARAMS = {
"muteHttpExceptions": true,
"method": "POST",
"contentType": "application/json",
"payload": {
"body":{
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": JWT
}
}
};
return UrlFetchApp.fetch(URL, PARAMS);
}
This is the correct function:
function obtainAccessToken(){
const JWT = MY_JSON_WEB_TOKEN;
const URL = 'https://account-d.docusign.com/oauth/token';
const PARAMS = {
"method": "POST",
"headers":{
"Accept": "application/json",
"contentType": "application/x-www-form-urlencoded"
},
"payload": {
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": JWT
}
};
return UrlFetchApp.fetch(URL, PARAMS);
}

Using my personal clickup token to make a clickup api call from Google Apps Script

function getClickupTeam() {
let response = UrlFetchApp.fetch(clickupUrl + "team", {
"method": "GET",
"Authorization": clickupToken,
"muteHttpExceptions": true
})
Logger.log(response)
let json = JSON.parse(response);
Logger.log(json);
}
This URLFetchApp call returns {ECODE=OAUTH_017, err=Authorization header required} even though I am including my personal clickup token in the request. Am I missing something? Any help would be appreciated.
It looks like your request is malformed (be sure to check out the reference documentation for the UrlFetchApp.fetch(url, params) method.) The Authorization header should be in an explicit headers object. Plus, you don't need to set method to GET since its the default.
Something else to keep in mind for when you're making POST requests - Google Apps Script has this funny quirk where you have to define the Content-Type header using the contentType property. If you try to set that header in the headers object if will just get overridden by the default (application/x-www-form-urlencoded I believe).
So here's how you'd set up your GET request:
function getClickupTeam() {
let response = UrlFetchApp.fetch(clickupUrl + "team", {
"muteHttpExceptions": true,
"headers": {
"Authorization": clickupToken
}
}
console.log(response.getContentText());
let json = JSON.parse(response.getContentText());
console.log(json);
);
And for POST requests with a JSON payload you'd do something like this:
function getClickupTeam() {
let response = UrlFetchApp.fetch(clickupUrl + "team", {
"method": "POST",
"contentType": "application/json",
"muteHttpExceptions": true,
"headers": {
"Authorization": clickupToken
},
"payload": JSON.stringify({
"key": "value"
});
}
console.log(response.getContentText());
let json = JSON.parse(response.getContentText());
console.log(json);
);
While doing some research on the topic through https://clickup.com/api, I stumbled across some code. There are a couple of different ones for different things, I'd recommend the first, JavaScript (as that's whats closest to what your currently doing). In a comment you said it was for editing tasks so that's what this code is aimed for.
javascript
var request = new XMLHttpRequest();
request.open('PUT', 'https://api.clickup.com/api/v1/task/{task_id}');
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('Authorization', '"access_token"');
request.onreadystatechange = function () {
if (this.readyState === 4) {
console.log('Status:', this.status);
console.log('Headers:', this.getAllResponseHeaders());
console.log('Body:', this.responseText);
}
};
var body = {
'name': 'New Task Name',
'content': 'New Task Content',
'assignees': {
'add': [
1
],
'rem': [
2
]
},
'status': 'Closed',
'priority': 3,
'due_date': '1508369194377'
};
request.send(JSON.stringify(body));
curl
curl --include \
--request PUT \
--header "Content-Type: application/json" \
--header "Authorization: "access_token"" \
--data-binary "{
\"name\": \"New Task Name\",
\"content\": \"New Task Content\",
\"assignees\": {
\"add\" : [
1
],
\"rem\" : [
2
]
},
\"status\": \"Closed\",
\"priority\": 3,
\"due_date\": \"1508369194377\"
}" \
'https://api.clickup.com/api/v1/task/{task_id}'
node.js
var request = require('request');
request({
method: 'PUT',
url: 'https://api.clickup.com/api/v1/task/{task_id}',
headers: {
'Content-Type': 'application/json',
'Authorization': '\'access_token\''
},
body: "{ \"name\": \"New Task Name\", \"content\": \"New Task Content\", \"assignees\": { \"add\": [ 1 ], \"rem\": [ 2 ] }, \"status\": \"Closed\", \"priority\": 3, \"due_date\": \"1508369194377\"}"
}, function (error, response, body) {
console.log('Status:', response.statusCode);
console.log('Headers:', JSON.stringify(response.headers));
console.log('Response:', body);
});
This is aimed for production let me know if you need mock server or debugging proxy

Create new Apps Script file with the Apps Script API - Error - Invalid JSON payload received

I'm getting the error:
Invalid JSON payload received
When trying to create a new Apps Script file with the Apps Script API.
How do I fix that error?
function createNewFile() {
var d,options,payload,response,theAccessTkn,url;
theAccessTkn = ScriptApp.getOAuthToken();
//See https://developers.google.com/apps-script/api/reference/rest/v1/projects/create
url = "https://script.googleapis.com/v1/projects";
d = new Date().toString().slice(0,10);
payload = {
"title": "AA_" + d
}
options = {
"method" : "POST",
"muteHttpExceptions": true,
"headers": {
'Authorization': 'Bearer ' + theAccessTkn
},
"payload": JSON.stringify(payload)
};
response = UrlFetchApp.fetch(url,options);
Logger.log(response)
return response;
}
I have set the authorization scopes in the manifest file to avoid needing to add an OAuth library:
{
"timeZone": "America/New_York",
"oauthScopes": [
"https://www.googleapis.com/auth/script.projects",
"https://www.googleapis.com/auth/script.external_request"
],
"dependencies": {
},
"exceptionLogging": "STACKDRIVER"
}
I needed to add "contentType": "application/json" to the options.
options = {
"method" : "POST",
"muteHttpExceptions": true,
"headers": {
'Authorization': 'Bearer ' + theAccessTkn
},
"contentType": "application/json",
"payload": JSON.stringify(payload)
};

Update item in another site collection in sharepoint 2013

I need to update item in another site collection according to this article I make my code like this
<script type="text/javascript">
$(document).ready(function () {
var otherSiteUrl = "<sitecollectionurl>";
var listName = "TestList";
var itemType = GetItemTypeForListName(listName);
var item = {
"__metadata": {
"type": itemType
},
"Title": "updated title"
};
$.ajax({
url: otherSiteUrl + "/_api/contextinfo",
type: "POST",
headers: {
"Accept": "application/json;odata=verbose"
},
success: function (contextData) {
alert(contextData.d.GetContextWebInformation.FormDigestValue);
$.ajax({
url: otherSiteUrl + "/_api/web/lists/getbytitle('" + listName + "')/items?#target='" + otherSiteUrl + "'",
method: "POST",
contentType: "application/json;odata=verbose",
data: JSON.stringify(item),
async: false,
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": contextData.d.GetContextWebInformation.FormDigestValue
},
success: function (data) {
alert('success');
},
error: function (jqXHR, textStatus, errorThrown) {
alert('error');
}
});
},
error: function (jqXHR, textStatus, errorThrown) {
alert('error');
}
});
});
function GetItemTypeForListName(name) {
return "SP.Data." + name.charAt(0).toUpperCase() + name.split(" ").join("").slice(1) + "ListItem";
}
</script>
I used
"X-RequestDigest":
contextData.d.GetContextWebInformation.FormDigestValue
after that I chenge ajax header like
"X-RequestDigest":
$("#__REQUESTDIGEST").val(contextData.d.GetContextWebInformation.FormDigestValue)
for both RequestDigest I got this error:
Invalid JSON. A token was not recognized in the JSON content
after that I chenge ajax header as
How can I update item successfully in another site collection with api?
eventually, I can edit item in another site collection.I just little change in my code.
first, most important part is library full name dose not contain List I use this url to find out library full name .
[Site url]/_api/web/lists/GetByTitle('List Name')/ListItemEntityTypeFullName
then I change metadate as
"__metadata": { "type": 'SP.Data.DocumentsItem' },
second I added
"X-HTTP-Method": "MERGE" , "If-Match": "*"
to header like:
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": contextData.d.GetContextWebInformation.FormDigestValue,
"X-HTTP-Method": "MERGE",
"If-Match": "*"
},