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]});
}
Related
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
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 write a standalone Google Apps script that uses the Google Apps Script API to update the the bound script contents of many Google Sheets.
I have the Sheet IDs of roughly 200 Google Sheets that I've created from a template. I would like to update the project contents of the bound scripts on each of these sheets to be identical to a set of master scripts.
I am stuck with an authentication error while using the urlFetchApp to get the contents of the bound script of one sheet as a test. The error looks like:
Request failed for
https://script.googleapis.com/v1/projects/<SCRIPTID>/content returned code 401.
Truncated server response: { "error": { "code": 401,
"message": "Request is missing required authentication credential.
Expected OAuth 2 access token, login cookie ...
(use muteHttpExceptions option to examine full response) (line 34, file "AddScriptsToSheets")
The test function I'm using looks like:
function getSheetScriptContent(sheetId) {
var sheet = SpreadsheetApp.openById(sheetId);
// Make a POST request with a JSON payload.
// Make a GET request and log the returned content.
var url = PROJECTS_GET_CONTENT_URL.format(sheetId);
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
I think this OAuth2 library may be useful in this case, I'm just not sure how to use it. Could anyone point me in the right direction?
If you own all the files, then you don't need to use an OAuth library or any special code to get the access token. You can get the access token from the ScriptApp class.
var theAccessTkn = ScriptApp.getOAuthToken();
You may need to manually edit the appsscript.json manifest file and add the scope:
https://www.googleapis.com/auth/script.projects
appsscript.json
{
"timeZone": "Yours will display here",
"dependencies": {
},
"webapp": {
"access": "MYSELF",
"executeAs": "USER_DEPLOYING"
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/script.projects",
"https://www.googleapis.com/auth/drive.scripts",
"https://www.googleapis.com/auth/script.container.ui",
"https://www.googleapis.com/auth/script.external_request"
],
"runtimeVersion": "DEPRECATED_ES5"
}
Code to overwrite an Apps Script file:
function updateContent(scriptId,content,theAccessTkn) {
try{
var options,payload,response,url;
if (!content) {
//Error handling function
return;
}
if (!theAccessTkn) {
theAccessTkn = ScriptApp.getOAuthToken();
}
//https://developers.google.com/apps-script/api/reference/rest/v1/projects/updateContent
url = "https://script.googleapis.com/v1/projects/" + scriptId + "/content";
options = {
"method" : "PUT",
"muteHttpExceptions": true,
"headers": {
'Authorization': 'Bearer ' + theAccessTkn
},
"contentType": "application/json",//If the content type is set then you can stringify the payload
"payload": JSON.stringify(content)
};
response = UrlFetchApp.fetch(url,options);
//Logger.log('getResponseCode ' + response.getResponseCode())
//Logger.log("Response content: " + response.getContentText())
} catch(e) {
console.log("Error: " + e + "\nStack: " + e.stack)
}
};
We implemented a function to create drafts using Compose Actions.
However, the subject is garbled.
If the subject is あいうえお, it will be Re: BDFHJ.
I want to prevent garbled characters.
this code.
Code.js
function buildCard (e) {
var card = CardService.newCardBuilder();
card.setHeader(CardService.newCardHeader().setTitle("タイトル"));
var section = CardService.newCardSection();
var composeAction = CardService.newAction()
.setFunctionName('createReplyDraft');
var composeButton = CardService.newTextButton()
.setText('Compose Reply')
.setComposeAction(composeAction, CardService.ComposedEmailType.REPLY_AS_DRAFT);
section.addWidget(composeButton);
card.addSection(section);
return card.build();
}
/**
* Creates a draft email (with an attachment and inline image)
* as a reply to an existing message.
* #param {Object} e data passed by the compose action.
* #return {ComposeActionResponse}
*/
function createReplyDraft(e) {
// Activate temporary Gmail add-on scopes, in this case to allow
// a reply to be drafted.
var accessToken = e.messageMetadata.accessToken;
GmailApp.setCurrentMessageAccessToken(accessToken);
// Creates a draft reply.
var messageId = e.messageMetadata.messageId;
var message = GmailApp.getMessageById(messageId);
var draft = message.createDraftReply('あいうえお'); //There is no problem with body.
// Return a built draft response. This causes Gmail to present a
// compose window to the user, pre-filled with the content specified
// above.
return CardService.newComposeActionResponseBuilder()
.setGmailDraft(draft).build();
}
appsscript.json
{
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/gmail.readonly"
],
"gmail": {
"name": "Gmail Add-on Quickstart",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/2x/bookmark_black_24dp.png",
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "buildCard"
}],
"openLinkUrlPrefixes": [
"https://mail.google.com/"
],
"primaryColor": "#4285F4",
"secondaryColor": "#4285F4"
},
"oauthScopes":[
"https://mail.google.com/",
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/script.external_request"]
}
this flow.
step1.
You've got mail.
step2.
Click the Compose Reply
step3.
Edit Subject.
step4.
Subject is garbled.
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.