I have developed the following code based on other code I found on the internet, but it does not work.
Can someone help me to understand my issue?
I get an error saying I don't have the right.
What is the problem?
Thank you very much for your support, that will be well appreciated.
var tokenService_ = function(){return ScriptApp.getOAuthToken()};
function exe() {
var listObj = reportTeamDrivePermissions('id of the folder');
console.log(listObj.toString());
}
function reportTeamDrivePermissions(driveId) {
// Reading the Drive permissions
var options = {"supportsAllDrives": true, "fields": 'permissions,nextPageToken', "pageSize":100};
var paramString = Object.keys(options).map(function(key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(options[key]);
}).join('&');
var url = "files/"+driveId+"/permissions";
url = url + (url.indexOf('?') >= 0 ? '&' : '?') + paramString;
url = "https://www.googleapis.com/drive/v3/" + url;
var fetchOptions = {method:"GET",muteHttpExceptions:true, contentType:"application/json", headers:{Authorization:"Bearer "+tokenService_()}};
var response = UrlFetchApp.fetch(url, fetchOptions);
if(response.getResponseCode() != 200){
throw new Error(response.getContentText());
} else {
var PermissionListResource = JSON.parse(response.getContentText());
}
var myPermisionList = PermissionListResource.permissions;
var nextPageToken = PermissionListResource.nextPageToken;
while (nextPageToken != null) {
// Reading the Drive permissions
options = {"supportsAllDrives": true, "fields": 'permissions,nextPageToken', "pageSize":100, 'pageToken': nextPageToken};
paramString = Object.keys(options).map(function(key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(options[key]);
}).join('&');
url = "files/"+driveId+"/permissions";
url = url + (url.indexOf('?') >= 0 ? '&' : '?') + paramString;
url = "https://www.googleapis.com/drive/v3/" + url;
fetchOptions = {method:"GET",muteHttpExceptions:true, contentType:"application/json", headers: {Authorization:"Bearer "+tokenService_()}}
response = UrlFetchApp.fetch(url, fetchOptions)
if(response.getResponseCode() != 200){
throw new Error(response.getContentText());
} else {
var PermissionListResource2 = JSON.parse(response.getContentText());
}
myPermisionList = myPermisionList.concat(PermissionListResource2.permissions);
nextPageToken = myPermisionObject2.nextPageToken;
}
return myPermisionList;
}
Related
I am trying to implement twitter media upload on google apps script via OAuth1.0a... as there has been no oauth2 for media uploads since 2 years. Following is the code. Still facing 401, 402, 403 , 400... all such return codes since last one week. Is this end point not working? anyone has any info? any ideas why its failing again and again.
using OAuth1 (https://github.com/googleworkspace/apps-script-oauth1/tree/3f3a6697d95a3ed9a91d09c65ffc34941136f587)
var url = 'https://upload.twitter.com/1.1/media/upload.json?media_category=tweet_image';
var baseUrl = 'https://upload.twitter.com/1.1/media/upload.json';
var params = {
'payload': {'media': imageBlob},
'method': 'POST',
'muteHttpExceptions' : true
};
var token = JSON.parse(PropertiesService.getUserProperties().getProperty("oauth1."+ account));
var oauth_token = token.oauth_token
var oauth_token_secret = token.oauth_token_secret
var oauth_consumer_key = PropertiesService.getUserProperties().getProperty("TWITTER_CONSUMER_KEY");
var oauth_consumer_secret = PropertiesService.getUserProperties().getProperty("TWITTER_CONSUMER_SECRET");
const method = params['method'] || 'post';
params['method'] = method;
const oauthParameters = {
oauth_version: "1.0",
oauth_token: oauth_token,
oauth_consumer_key: oauth_consumer_key,
oauth_signature_method: "HMAC-SHA1",
oauth_timestamp: (Math.floor((new Date()).getTime() / 1000)).toString(),
};
oauthParameters.oauth_nonce = oauthParameters.oauth_timestamp + Math.floor(Math.random() * 100000000);
const payload = params['payload'] || {};
const q = {"media_category": "tweet_image"} //parms from url
const queryKeys = Object.keys(oauthParameters).concat(Object.keys(payload)).concat(Object.keys(q)).sort();
const baseString = queryKeys.reduce(function(acc, key, idx) {
if (idx) acc += encodeURIComponent("&");
if (oauthParameters.hasOwnProperty(key))
acc += _encode(key + "=" + oauthParameters[key]);
else if (payload.hasOwnProperty(key))
acc += _encode(key + "=" + _encode(payload[key]));
return acc;
}, method.toUpperCase() + '&' + _encode(baseUrl) + '&');
oauthParameters.oauth_signature = Utilities.base64Encode(
Utilities.computeHmacSignature(
Utilities.MacAlgorithm.HMAC_SHA_1,
baseString, oauth_consumer_secret + '&' + oauth_token_secret
)
);
if (!params['headers']) params['headers'] = {};
params['headers']['authorization'] = "OAuth " + Object.keys(oauthParameters)
.sort().reduce(function(acc, key) {
acc.push(key + '="' + _encode(oauthParameters[key]) + '"');
return acc;
}, []).join(', ');
params['payload'] = Object.keys(payload).reduce(function(acc, key) {
acc.push(key + '=' + _encode(payload[key]));
return acc;
}, []).join('&');
console.log(params)
response = UrlFetchApp.fetch(url, params);
for info...other than this, I also tried this repo - https://github.com/airhadoken/twitter-lib
still facing similar issues.
EDIT: on postman it works.. somethings wrong with the code then.. :(
I am attempting to authenticate with a service account to work on behalf of a user account on the domain. I have delegated admin access and added to the GSuite console. I can get an access token with the below but the making batch requests to copy drive files returns "code: 404, message: 'File not found:". The below code is writted in Google Apps Script. Am I missing something form the process to creating and authenticating the service account?
var CREDENTIALS = {
private_key: "-----BEGIN PRIVATE KEY----- XXXXXXX \n-----END PRIVATE KEY-----\n",
client_email: "XXXXXX#fXXXXXX.iam.gserviceaccount.com",
client_id: "1XXXXXXXXXXXXXXXX",
user_email: "XXXXX#XXXX.XXX.XXX",
scopes: ["https://www.googleapis.com/auth/drive","https://www.googleapis.com/auth/spreadsheets","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/script.external_request"]
};
function oAuthToken(){
var url = "https://www.googleapis.com/oauth2/v3/token";
var header = {
alg: "RS256",
typ: "JWT",
};
var now = Math.floor(Date.now() / 1000);
var claim = {
iss: CREDENTIALS.client_id,
sub: CREDENTIALS.user_email,
scope: CREDENTIALS.scopes.join(" "),
aud: url,
exp: (now + 3600).toString(),
iat: now.toString(),
};
var signature = Utilities.base64Encode(JSON.stringify(header)) + "." + Utilities.base64Encode(JSON.stringify(claim));
var jwt = signature + "." + Utilities.base64Encode(Utilities.computeRsaSha256Signature(signature, CREDENTIALS.private_key));
var params = {
method: "post",
payload: {
assertion: jwt,
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
},
};
var res = UrlFetchApp.fetch(url, params).getContentText();
return JSON.parse(res)
}
The batch process is a bit rough but this is the gist of it.
var request={
batchPath:
requests:[]
}
var backoff =0
function batch(request) {
var oAuth=oAuthToken().access_token
var url ='https://www.googleapis.com/'+request.batchPath
var body =request.requests
if(body.length<1){
return []
}
var boundary = 'xxxxxxxxxx';
var contentId = 0;
var data = '--' + boundary + '\r\n';
for (var i in body) {
if(typeof body[i]=='object'){
data += 'Content-Type: application/http\r\n';
data += 'Content-ID: ' + ++contentId + '\r\n\r\n';
data += body[i].method + ' ' + body[i].endpoint + '\r\n';
data += body[i].requestBody ? 'Content-Type: application/json; charset=utf-8\r\n\r\n' : '\r\n';
data += body[i].requestBody ? JSON.stringify(body[i].requestBody) + '\r\n' : '';
data += "--" + boundary + '\r\n';
}
}
var parseBatchRes = function(res) {
var splittedRes = res.split('--batch');
return splittedRes.slice(1, splittedRes.length - 1).map(function(e) {
return {
contentId: Number(e.match(/Content-ID: response-(\d+)/)[1]),
status: Number(e.match(/HTTP\/\d+.\d+ (\d+)/)[1]),
object: JSON.parse(e.match(/{[\S\s]+}/)[0]),
};
});
};
var payload = Utilities.newBlob(data).getBytes();
var head = {Authorization: 'Bearer ' + oAuth}
var options = {
method: 'POST',
contentType: 'multipart/mixed; boundary=' + boundary,
payload: payload,
headers: head,
muteHttpExceptions: false
};
var complete=false;
var finalResponse=[];
for (var n=0; n<=backoff; n++) {
if(complete){
break;
}
var complete = true
console.log('backoff',n);
var response =UrlFetchApp.fetch(url, options).getContentText();
for(var j=0;j<response.length;j++){
if(response[r].status!=200){
var complete = false
}
}
}
}
Add the supportsAllDrives = true query parameter to the request.
The parameters indicates whether the requesting application supports both My Drives and shared drives and the default value for this is false.
Reference
Drive API Parameters
I have a bit of GAS code that is failing when executing UrlFetchApp.fetch(url) - I think.
Are there limits to the character length of a url when used in UrlFetchApp.fetch(url). My function is failing and I suspect that it has something to do with the length of the url. It is over 100 chars.
The code below refers...
function uploadToDrive(url, folderid, filename, fileDesc) {
var msg = '';
try {
var response = UrlFetchApp.fetch(url);
} catch(err) {
};
if (response.getResponseCode() === 200) {
var folder = DriveApp.getRootFolder();
if (folderid) {
folder = DriveApp.getFolderById(folderid);
}
var blob = response.getBlob();
var file = folder.createFile(blob);
file.setName(filename);
file.setDescription(fileDesc);
var headers = response.getHeaders();
var content_length = NaN;
for (var key in headers) {
if (key.toLowerCase() == 'Content-Length'.toLowerCase()) {
content_length = parseInt(headers[key], 10);
break;
}
}
var blob_length = blob.getBytes().length;
msg += 'Saved "' + filename + '" (' + blob_length + ' bytes)';
if (!isNaN(content_length)) {
if (blob_length < content_length) {
msg += ' WARNING: truncated from ' + content_length + ' bytes.';
} else if (blob_length > content_length) {
msg += ' WARNING: size is greater than expected ' + content_length + ' bytes from Content-Length header.';
}
}
msg += '\nto folder "' + folder.getName() + '".\n';
}
else {
msg += 'Response code: ' + response.getResponseCode() + '\n';
}
return file.getUrl();
}
That link generates a response code 404, but you set the response variable only if the fetch method is successful in your try block. Try validating the response variable before assuming it has properties and methods to access:
function fetching() {
var url = "<some url resource>";
try {
var response = UrlFetchApp.fetch(url);
} catch (err) {
// why catch the error if you aren't going to do anything with it?
Logger.log(err);
} finally {
if (response && response.getResponseCode() === 200) {
Logger.log("Should be 200, got " + response.getResponseCode());
} else {
Logger.log("Fetching Failed: Exception thrown, no response.");
}
}
}
However, I would go farther and guarantee a response from UrlFetchApp.fetch. This is done with the "muteHttpExceptions" paramater set to true.
function fetching() {
//dns exception
//var = "googqdoiqijwdle.com"
//200
var url = "google.com";
//404
//var url = "https://www.jotform.com/uploads/Administrator_System_sysadmin/92960977977584/4480552280228238115/BoE%20Test%20File.docx"
try {
var response = UrlFetchApp.fetch(url, {
muteHttpExceptions: true
});
} catch (err) {
Logger.log(err);
}
if (response) {
response.getResponseCode() === 200 ?
Logger.log("Should be 200, got " + response.getResponseCode()) :
Logger.log("Anything but 200, got " + response.getResponseCode());
}
}
Hope this helped!
Docs: Google Developers
I have read online that the unexpected token issue can come from using JSON.parse().
I am getting this error Uncaught SyntaxError: Unexpected token u
What I am doing wrong?
My code look like this
var t=null;
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function(responseText)
{
if (xmlhttp.readyState == 4 &&xmlhttp.status==200)
var obj = JSON.parse(xmlhttp.responseText);
var str=JSON.stringify(obj);
var newArr = JSON.parse(str);
var len=newArr.length;
$.mobile.pageContainer.pagecontainer( "change","sales_home.html");
$(document).on('pageshow', "#temp", function (event, data) {
while (len > 0) {
len--;
}
});
}
xmlhttp.onerror=function(E)
{
alert("error"+ E);
}
xmlhttp.open("GET","url",true);
xmlhttp.send();
The problem becomes apparent if you indent the code consistently and correctly:
var t = null;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(responseText) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
var obj = JSON.parse(xmlhttp.responseText);
var str = JSON.stringify(obj); // <====
var newArr = JSON.parse(str); // <====
var len = newArr.length;
$.mobile.pageContainer.pagecontainer("change", "sales_home.html");
$(document).on('pageshow', "#temp", function(event, data) {
while (len > 0) {
len--;
}
});
}
xmlhttp.onerror = function(E) {
alert("error" + E);
}
xmlhttp.open("GET", "url", true);
xmlhttp.send();
Note how the code does
var str = JSON.stringify(obj);
var newArr = JSON.parse(str);
no matter what the value of readyState and status are. That causes the error, because obj will be undefined, so JSON.stringify(obj) will return undefined, so JSON.parse will coerce that to the string "undefined", which it then cannot parse, failing on the first character, u.
You probably want to add a block:
var t = null;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(responseText) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { // Block starts here
var obj = JSON.parse(xmlhttp.responseText);
var str = JSON.stringify(obj);
var newArr = JSON.parse(str);
var len = newArr.length;
$.mobile.pageContainer.pagecontainer("change", "sales_home.html");
$(document).on('pageshow', "#temp", function(event, data) {
while (len > 0) {
len--;
}
});
} // Block ends here
}
xmlhttp.onerror = function(E) {
alert("error" + E);
}
xmlhttp.open("GET", "url", true);
xmlhttp.send();
Not quite following why you're parsing, then stringifying, then parsing again though... Or why you have an empty while loop...
I am trying to do cookie stuff in jquery
but it not getting implemented can you guys fix my problem
html code
<a rel="en_CA" class="selectorCountries marginUnitedStates locale-link" href="http://www.teslamotors.com/en_CA">united states</a>
<a rel="en_US" class="selectorCountries marginSecondCountry locale-link" href="http://www.teslamotors.com/en_CA">canada</a>
<a rel="en_BE" class="selectorCountries marginCanadaFrench locale-link" href="http://www.teslamotors.com/en_BE">canada(french)</a>
i am providing my js code below
http://jsfiddle.net/SSMX4/76/
when i click the different country links in the pop up it should act similar to this site
http://www.teslamotors.com/it_CH
$('.locale-link').click(function(){
var desired_locale = $(this).attr('rel');
createCookie('desired-locale',desired_locale,360);
createCookie('buy_flow_locale',desired_locale,360);
closeSelector('disappear');
})
$('#locale_pop a.close').click(function(){
var show_blip_count = readCookie('show_blip_count');
if (!show_blip_count) {
createCookie('show_blip_count',3,360);
}
else if (show_blip_count < 3 ) {
eraseCookie('show_blip_count');
createCookie('show_blip_count',3,360);
}
$('#locale_pop').slideUp();
return false;
});
function checkCookie(){
var cookie_locale = readCookie('desired-locale');
var show_blip_count = readCookie('show_blip_count');
var tesla_locale = 'en_US'; //default to US
var path = window.location.pathname;
// debug.log("path = " + path);
var parsed_url = parseURL(window.location.href);
var path_array = parsed_url.segments;
var path_length = path_array.length
var locale_path_index = -1;
var locale_in_path = false;
var locales = ['en_AT', 'en_AU', 'en_BE', 'en_CA',
'en_CH', 'de_DE', 'en_DK', 'en_GB',
'en_HK', 'en_EU', 'jp', 'nl_NL',
'en_US', 'it_IT', 'fr_FR', 'no_NO']
// see if we are on a locale path
$.each(locales, function(index, value){
locale_path_index = $.inArray(value, path_array);
if (locale_path_index != -1) {
tesla_locale = value == 'jp' ? 'ja_JP':value;
locale_in_path = true;
}
});
// debug.log('tesla_locale = ' + tesla_locale);
cookie_locale = (cookie_locale == null || cookie_locale == 'null') ? false:cookie_locale;
// Only do the js redirect on the static homepage.
if ((path_length == 1) && (locale_in_path || path == '/')) {
debug.log("path in redirect section = " + path);
if (cookie_locale && (cookie_locale != tesla_locale)) {
// debug.log('Redirecting to cookie_locale...');
var path_base = '';
switch (cookie_locale){
case 'en_US':
path_base = path_length > 1 ? path_base:'/';
break;
case 'ja_JP':
path_base = '/jp'
break;
default:
path_base = '/' + cookie_locale;
}
path_array = locale_in_path != -1 ? path_array.slice(locale_in_path):path_array;
path_array.unshift(path_base);
window.location.href = path_array.join('/');
}
}
// only do the ajax call if we don't have a cookie
if (!cookie_locale) {
// debug.log('doing the cookie check for locale...')
cookie_locale = 'null';
var get_data = {cookie:cookie_locale, page:path, t_locale:tesla_locale};
var query_country_string = parsed_url.query != '' ? parsed_url.query.split('='):false;
var query_country = query_country_string ? (query_country_string.slice(0,1) == '?country' ? query_country_string.slice(-1):false):false;
if (query_country) {
get_data.query_country = query_country;
}
$.ajax({
url:'/check_locale',
data:get_data,
cache: false,
dataType: "json",
success: function(data){
var ip_locale = data.locale;
var market = data.market;
var new_locale_link = $('#locale_pop #locale_link');
if (data.show_blip && show_blip_count < 3) {
setTimeout(function(){
$('#locale_msg').text(data.locale_msg);
$('#locale_welcome').text(data.locale_welcome);
new_locale_link[0].href = data.new_path;
new_locale_link.text(data.locale_link);
new_locale_link.attr('rel', data.locale);
if (!new_locale_link.hasClass(data.locale)) {
new_locale_link.addClass(data.locale);
}
$('#locale_pop').slideDown('slow', function(){
var hide_blip = setTimeout(function(){
$('#locale_pop').slideUp('slow', function(){
var show_blip_count = readCookie('show_blip_count');
if (!show_blip_count) {
createCookie('show_blip_count',1,360);
}
else if (show_blip_count < 3 ) {
var b_count = show_blip_count;
b_count ++;
eraseCookie('show_blip_count');
createCookie('show_blip_count',b_count,360);
}
});
},10000);
$('#locale_pop').hover(function(){
clearTimeout(hide_blip);
},function(){
setTimeout(function(){$('#locale_pop').slideUp();},10000);
});
});
},1000);
}
}
});
}
This will help you ALOT!
jQuery Cookie Plugin
I use this all the time. Very simple to learn. Has all the necessary cookie functions built-in and allows you to use a tiny amount of code to create your cookies, delete them, make them expire, etc.
Let me know if you have any questions on how to use (although the DOCS have a decent amount of instruction).