I have some code that I am trying to execute:
function createOrAppendFile(in_Folder, in_FileName, in_Content ) {
var fileName=in_FileName;
//var folderName=in_Folder;
var folderName="TRADEARCHIVE";
var content = in_Content;
// get list of folders with matching name
var folderList = DriveApp.getFoldersByName(folderName);
if (folderList.hasNext()) {
// found matching folder
var folder = folderList.next();
// search for files with matching name
var fileList = folder.getFilesByName(fileName);
[... snip ...]
I have the following defined in appscript.json
{
"timeZone": "America/Chicago",
"dependencies": {},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"webapp": {
"executeAs": "USER_DEPLOYING",
"access": "ANYONE_ANONYMOUS"
},
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets.readonly",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/drive"
]
}
I am getting the following error:
Nov 4, 2022, 12:28:53 AM Error Exception: You do not have permission to call DriveApp.getFoldersByName. Required permissions: (https://www.googleapis.com/auth/drive.readonly || https://www.googleapis.com/auth/drive)
at createOrAppendFile(Code:33:29)
at deleteRows(Code:173:11)
at onMyEdit(Code:390:29)
What am I doing wrong? Any help, hints or advice would be greatly appreciated.
TIA
What seemed to work for me ( in this case ) was to place an "Open" Trigger on
the function doing the search for the Folder.
Deployment Event Function
Head From spreadsheet - On open createOrAppendFile
YOU CAN TRY TO
setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
ADD THIS TO YOUR GOOGLE SCRIPT
THANKS
Related
I have a problem with Apps Script and sending email. I'm using a Google Form and a Google Sheet to collect data. When the survey is send, I linked the main function to a trigger so the main perform some calculation and generate a PDF. At the end of the main, a function for sending an email is called, but I have an error. I also added Gmail API. I tried to add more link into oauthScopes in my appsscript.json, but I had the same result.
This is my appsscript.json:
{
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.send",
"https://www.googleapis.com/auth/gmail.compose",
"https://www.googleapis.com/auth/gmail.modify"
],
"timeZone": "America/Toronto",
"dependencies": {
"enabledAdvancedServices": [
{
"userSymbol": "Gmail",
"version": "v1",
"serviceId": "gmail"
}
]
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
This is my function that's called by my main:
function sendEmail(email, pdfFile){
var subject = "Test";
var message = "Hi";
GmailApp.sendEmail(email, subject, message);
}
When this function is call, I have the following problem:
Exception: The script does not have permission to perform that action. Required permissions: (https://www.googleapis.com/auth/gmail.send || https://www.googleapis.com/auth/gmail.compose || https://www.googleapis.com/auth/gmail.modify || https://mail.google.com/ || https://www.googleapis.com/auth/gmail.addons.current.action.compose)
How can I solve this problem ?
Try:
function sendEmail(email, pdfFile){
var subject = "Test";
var message = "Hi";
GmailApp.sendEmail(email, subject, message, {attachments:[pdfFile]});
}
Goal:
I want to build a custom function in Google Sheet that can auto-generate all sheets name from another Google Sheets (with the filename of "2020-01" and it has multiple tabs inside, like "2020-01-01", "2020-01-02", "2020-01-03" and so on).
With this custom function, I hope I can use the query formula to get the data from the multiple tabs in "2020-01". Here is the code in Google App Script:
Code:
function getsheetnames() {
var out=[];
var ss;
var sheets;
ss = SpreadsheetApp.openById("SHEET_ID");
sheets = ss.getSheets();
for(var i=0;i<sheets.length;i++) {
var sh=sheets[i];
var name=sh.getName();
out.push("'" + name + "'!$A:$O");
}
return '{' + out.join(';') + '}';
}
Problem:
By now, I only get the following error message when I typed the formula =getsheetnames() in the cell, even I had already set the oauthScopes in appscript.json:
Exception: You do not have permission to call SpreadsheetApp.openById. Required permissions: https://www.googleapis.com/auth/spreadsheets
{
"timeZone": "America/New_York",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/spreadsheets.readonly",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive"
]
}
Hence, may I know what wrong with my code and how can I solve the problem of permission? Thank you.
I am trying to create a Google Apps Script, that fetches the version number of a single file. Basically to monitor if the file was changed/opened, etc.
I want to do this by just using the drive.file API, to avoid having to go through the security assessment check, which becomes necessary (?) when using restricted access APIs.
I got it working if I create the file directly in the GAS but couldn't figure out how to get the metadata from user-created files.
This is the code (super-simple, though):
function myFunction() {
var test = {
title: 'myFile',
"parents": [{'id':"[ID]"}],
mimeType: 'text/plain'
};
file = Drive.Files.insert(test);
file_id = file.getId();
i = 0;
while (i<5) {
Utilities.sleep(5000);
output = Drive.Files.get(file_id).version;
Logger.log(output);
i += 1;
}
}
The APIs are set in the appsscript.json file via:
{
"timeZone": "Asia/Tokyo",
"oauthScopes": [
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive.appfolder",
"https://www.googleapis.com/auth/drive.appdata"
],
"dependencies": {
"enabledAdvancedServices": [{
"userSymbol": "Drive",
"serviceId": "drive",
"version": "v2"
}]
},
"exceptionLogging": "STACKDRIVER"
}
Is there any way to achieve getting this info without full API access to the user's Google Drive?
Your help is much appreciated!
- Fabian
You can use Google picker to let the user choose what file he may share with your project with no more permissions than the ones listed in the question.
You can use the drive.metadata.readonly, or drive.metadata scope. Of course you need at least read access to that file.
var params = {
supportsTeamDrives: true,
includeTeamDriveItems: true
};
params.fields = 'modifiedDate, version';
var modTime = Drive.Files.get(fileId, params);
Logger.log(modTime);
I tried to get some data from google sheet and display it in Gmail addons.
When i tried to run getValue() function i am getting error like below.
You do not have permission to call openById (line 29, file "Code")Dismiss
This is my code.gs file code
function createWidgetCard() {
return CardService
.newCardBuilder()
.setHeader(
CardService.newCardHeader()
.setTitle('Widget demonstration')
.setSubtitle('Check out these widgets')
.setImageStyle(CardService.ImageStyle.SQUARE)
.setImageUrl(
'https://www.example.com/images/headerImage.png'))
.addSection(
CardService.newCardSection()
.setHeader('Simple widgets') // optional
.addWidget(CardService.newTextParagraph().setText(
'These widgets are display-only. ' +
'A text paragraph can have multiple lines and ' +
getValue()))
.addWidget(CardService.newImage().setImageUrl(
'https://www.example.com/images/mapsImage.png')))
.addCardAction(CardService.newCardAction().setText('Gmail').setOpenLink(
CardService.newOpenLink().setUrl('https://mail.google.com/mail')))
.build();
}
//get data from sheet
function getValue(){
var ss = SpreadsheetApp.openById("181tnith14lu8ttAvtqsU3gHi32-UjcrPqH5Pjuenk5A");
var sheet = ss.getSheets()[0];
var lastRaw = sheet.getLastRow();
var text = sheet.getRange(lastRaw, 3.0).getValue();
Logger.log("text");
return text;
}
This is my manifest file code(appscript.json)
{
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/gmail.readonly",
"https://www.googleapis.com/auth/script.storage",
"https://www.googleapis.com/auth/script.external_request"
],
"gmail": {
"name": "Finetech Addon",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/2x/bookmark_black_24dp.png",
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "createWidgetCard"
}],
"openLinkUrlPrefixes": [
"https://mail.google.com/"
],
"primaryColor": "#4285F4",
"secondaryColor": "#4285F4",
"version": "TRUSTED_TESTER_V2"
}
}
My requirement is accessing sheet and get some data and display it on Gmail addon. It could be very helpful if anyone can provide correct code snipes.
I think that the scope for using Spreadsheet is required to be added to "oauthScopes" of manifests. So please add https://www.googleapis.com/auth/spreadsheets to "oauthScopes" in appsscript.json. And try again.
If this didn't work, I'm sorry.
I created a GAS script file on my Drive using the example from Packt's book 'Learning Google Apps Script. My question is how do I make this into an Add-On. Not quite sure on the manifest file I need to create (even after reading https://developers.google.com/gmail/add-ons/how-tos/building).
function saveEmailAttachmentsToDrive(){
// Create 'Gmail Attachments' folder if not exists.
createFolder_('Gmail attachments');
// Get inbox threads starting from the latest one to 100.
var threads = GmailApp.getInboxThreads(0, 100);
var messages = GmailApp.getMessagesForThreads(threads);
var folderID = PropertiesService.getUserProperties()
.getProperty("FOLDER");
var file, folder = DriveApp.getFolderById(folderID);
for (var i = 0 ; i < messages.length; i++) {
for (var j = 0; j < messages[i].length; j++) {
if(!messages[i][j].isUnread()){
var msgId = messages[i][j].getId();
// Assign '' if MSG_ID is undefined.
var oldMsgId = PropertiesService.getUserProperties()
.getProperty('MSG_ID') || '';
if(msgId > oldMsgId){
var attachments = messages[i][j].getAttachments();
for (var k = 0; k < attachments.length; k++) {
PropertiesService.getUserProperties()
.setProperty('MSG_ID', messages[i][j].getId());
try {
file = folder.createFile(attachments[k]);
Utilities.sleep(1000);// Wait before next iteration.
} catch (e) {
Logger.log(e);
}
}
}
else return;
}
}
}
};
function createFolder_(name) {
var folder, folderID, found = false;
/*
* Returns collection of all user folders as an iterator.
* That means it do not return all folder names at once,
* but you should get them one by one.
*
*/
var folders = DriveApp.getFolders();
while (folders.hasNext()) {
folder = folders.next();
if (folder.getName() == name) {
folderID = folder.getId();
found = true;
break;
}
};
if (!found) {
folder = DriveApp.createFolder(name);
folderID = folder.getId();
};
PropertiesService.getUserProperties()
.setProperty("FOLDER", folderID);
return folderID;
}
My question is how do I make this into an Add-On. Not quite sure on the manifest file I need to create (even after reading https://developers.google.com/gmail/add-ons/how-tos/building).
The JSON for the manifest file for the gmail part is:
"gmail": {
"name": "My Gmail Add-on",
"logoUrl": "https://www.example.com/hosted/images/2x/my-icon.png",
"primaryColor": "#4285F4",
"secondaryColor": "#00BCD4",
"authorizationCheckFunction": "get3PAuthorizationUrls",
"contextualTriggers": [{
"unconditional": {},
"onTriggerFunction": "buildAddOn"
}]
That must be in addition to what is already there. A manifest file at it's very basic, looks like this:
{
"timeZone": "America/New_York",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER"
}
You are going to make it look like the following:
{
"timeZone": "America/New_York",
"dependencies": {
},
"gmail": {
"name": "My Gmail Add-on",
"logoUrl": "https://www.example.com/hosted/images/2x/my-icon.png",
"primaryColor": "#4285F4",
"secondaryColor": "#00BCD4",
"authorizationCheckFunction": "get3PAuthorizationUrls",
"contextualTriggers": [{
"unconditional": {},
"onTriggerFunction": "buildAddOn"
}]
},
"exceptionLogging": "STACKDRIVER"
}
Use your timeZone, and your settings. Note that there are no dependencies listed, but leave that part in.
manifest.json is generated automatically by the Apps Script engine. It is hidden by default, but you can view it by toggling View > manifest file to see the structure.
When you're ready to test the AddOn, you can go to Publish > Deploy as web add on. If you're uploading from the cloud editor, you do not need to add a separate manifest file in the web store listing.
The development documentation covers deployment methods in detail.