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.
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]});
}
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.
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 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.