The problem is that my function receives an undefined event object. Can you tell me what's the problem?
Here's the function:
function onGmailMessageOpen(event) {
const { accessToken, messageId } = event.commonEventObject;
return buildCard();
}
Here's the appsscript.json manifest:
{
"timeZone": "Europe/Kiev",
"dependencies": {
"enabledAdvancedServices": [
{
"userSymbol": "Gmail",
"version": "v1",
"serviceId": "gmail"
}
]
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://mail.google.com/",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/gmail.addons.current.message.readonly",
"https://www.googleapis.com/auth/gmail.addons.current.message.metadata",
"https://www.googleapis.com/auth/gmail.metadata"
],
"gmail": {
"name": "Contacts",
"logoUrl": "https://lh4.googleusercontent.com/dfdvUXkVaB8yVTsrnuFagTy9YDvEPz3jqJWhFNpxKbbJhq7kdOTkwfoSEtn4VBOb9tZ_B6DT3Q-L4wU5Cw-FCcYY4fISn29OkcBOCwp69q5GxI4AM2WXHHk6kaQtgA",
"contextualTriggers": [
{
"unconditional": {},
"onTriggerFunction": "onGmailMessageOpen"
}
],
"primaryColor": "#547dbf"
},
"runtimeVersion": "V8",
"webapp": {
"executeAs": "USER_ACCESSING",
"access": "ANYONE"
}
}
The function declaration function onGmailMessageOpen(event) {/**/} tells that your function is designed to receive a properly populated event object.
Do not run the code directly in the script editor. If you do, theĀ event object will not be properly populated, causing the error you mention.
What you should do is let Google's code call the function when the user opens a message in the UI. When called like this, the event object will be properly populated.
Related
This question already has answers here:
Custom function throws a "You do not have the permission required to setValue" error
(4 answers)
Custom function permissions [duplicate]
(2 answers)
Google Apps Scripts no longer runs getActiveUser() within Sheets custom button triggers
Closed 8 months ago.
This post was edited and submitted for review 8 months ago and failed to reopen the post:
Needs details or clarity Add details and clarify the problem by editing this post.
The following functions used to work but no longer work unless the scripts are ran inside the console. Session.getActiveUser() would usually run inside Google Sheets scripts assigned to an inserted drawing or a time based trigger. When the scripts are ran, Session.getActiveUser() only runs if I (the spreadsheet owner) run the scrip. If it's someone else, it either doesn't work or Session.getActiveUser().getEmail() outputs a blank string. To be clear, all scripts are ran within a spreadsheet environment. NOT a deployed web app.
function printEmail()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Test Stuff");
var outputCell = ss.getRangeByName("testOutput");
Logger.log(Session.getActiveUser().getEmail());
outputCell.setValue( Session.getActiveUser().getEmail());
}
function printAdminEmail()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Test Stuff");
var outputCell = ss.getRangeByName("testOutput");
outputCell.setValue( Session.getEffectiveUser().getEmail());
}
Here is a screenshot of attempting to run the script from a spreadsheet drawing. Returns blank. Drawing assigned to "printEmail"
Here is the JSON Manifest.
{
"timeZone": "America/New_York",
"dependencies": {
"enabledAdvancedServices": [
{
"userSymbol": "Sheets",
"version": "v4",
"serviceId": "sheets"
},
{
"userSymbol": "DocsList",
"version": "v1",
"serviceId": "docs"
},
{
"userSymbol": "Calendar",
"version": "v3",
"serviceId": "calendar"
},
{
"userSymbol": "People",
"version": "v1",
"serviceId": "peopleapi"
},
{
"userSymbol": "Tasks",
"version": "v1",
"serviceId": "tasks"
}
]
},
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets.readonly",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/contacts.readonly",
"https://www.googleapis.com/auth/spreadsheets.currentonly",
"https://www.google.com/m8/feeds",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/calendar",
"https://www.googleapis.com/auth/calendar.readonly",
"https://www.google.com/calendar/feeds",
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/spreadsheets",
"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",
"https://www.googleapis.com/auth/tasks"
],
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"sheets": {
"macros": [
{
"menuName": "sortCaseload",
"functionName": "sortCaseload"
},
{
"menuName": "df",
"functionName": "df"
}
]
},
"webapp": {
"executeAs": "USER_ACCESSING",
"access": "DOMAIN"
}
}
On the current Gmail iPhone app, calling the newUpdateDraftActionResponseBuilder crashes the app. No errors get logged and those crashed calls never appear in the 'Executions' tab in the App Script console.
The same code runs fine on the Android Gmail app or in the browser.
Code to reproduce
index.gs
function attachRecording() {
return CardService.newUpdateDraftActionResponseBuilder()
.setUpdateDraftBodyAction(CardService.newUpdateDraftBodyAction()
.addUpdateContent('<h1>hello</h1>', CardService.ContentType.IMMUTABLE_HTML)
.setUpdateType(CardService.UpdateDraftBodyType.IN_PLACE_INSERT))
.build();
}
appsscript.json
{
"timeZone": "America/New_York",
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.current.action.compose",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/gmail.addons.execute"
],
"addOns": {
"common": {
"name": "Vocal",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/mic_black_48dp.png",
"universalActions": [
{
"label": "Manage account",
"openLink": "https://app.vocal.email"
}
],
"homepageTrigger": {
"runFunction": "onWelcomeClick"
},
"openLinkUrlPrefixes": [
"*"
]
},
"gmail": {
"composeTrigger": {
"selectActions": [
{
"text": "Record voice message",
"runFunction": "attachRecording"
}
],
"draftAccess": "NONE"
}
}
}
}
I tried the different methods of the function listed here: https://developers.google.com/apps-script/reference/card-service/update-draft-action-response-builder
Whether it's adding a subject or text/html in the body. it always crashes the app.
I am trying to call getEmail() from my script but consistently get the following error. The script is triggered by a form submission which otherwise runs successfully:
Exception: You do not have permission to call Session.getEffectiveUser. Required permissions: https://www.googleapis.com/auth/userinfo.email
at onFormSubmit(Code:55:24)
The line of code in question is:
let activeUser = Session.getActiveUser().getEmail ;
This is what I have in my manifest file:
{
"timeZone": "Europe/London",
"dependencies": {
"enabledAdvancedServices": [
{
"userSymbol": "Gmail",
"version": "v1",
"serviceId": "gmail"
}
]
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/script.send_mail",
"https://www.googleapis.com/auth/spreadsheets.currentonly",
"https://www.googleapis.com/auth/userinfo.email"
],
"runtimeVersion": "V8"
}
Any help would be greatly appreciated.
The function below works fine and save "Bla bla" in the target sheet (don't worry about stdParcels) if I run it directly from App Script Editor
function saveParcels(stdParcels) {
var ss = SpreadsheetApp.openById("sheet id");
var test = ss.getSheetByName('sheetname')
test.getRange(4, 1, 1, 1).setValue('Bla Bla!')
}
The same function did not work if it is called from the function
saveParcels(stdParcels) on the same file - error: Requeired permission.
Manifest:
{
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets.currentonly",
"https://www.googleapis.com/auth/spreadsheets"
],
"timeZone": "America/Sao_Paulo",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
Any tip to solve this issue?
I am using Google cloud datastore which is exposed by jersey rest, i have made authentication using oauth2 to access rest APIS.
Now I want to call restful API from my gmail addons to populate some lovs on gmail sidebar.
I have tried oauth2 authentication provided on https://github.com/googlesamples/apps-script-oauth2.
How do i show authorizationUrl on sidebar of gmail using gmail Addons?
CODEBASE
appscript.json
{
"timeZone": "America/Los_Angeles",
"dependencies": {
"enabledAdvancedServices": [{
"userSymbol": "Gmail",
"serviceId": "gmail",
"version": "v1"
}],
"libraries": [{
"userSymbol": "OAuth2",
"libraryId": "1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF",
"version": "24",
"developmentMode": true
}]
},
"oauthScopes": ["https://www.googleapis.com/auth/gmail.addons.execute", "https://www.googleapis.com/auth/gmail.addons.current.message.metadata", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/gmail.readonly", "https://www.googleapis.com/auth/script.external_request", "https://www.googleapis.com/auth/script.storage"],
"gmail": {
"name": "Gmail Add-on Quickstart",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/2x/bookmark_black_24dp.png",
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "buildAddOn"
}],
"primaryColor": "#4285F4",
"secondaryColor": "#4285F4",
"openLinkUrlPrefixes": ["https://mail.google.com/"],
"version": "TRUSTED_TESTER_V2"
}
}
Code.gs
function buildAddOn(e) {
var driveService = createOauthService();
Logger.log('Access'+driveService.hasAccess()); // GETTING FALSE HERE
Logger.log('Auth URL'+driveService.getAuthorizationUrl()); // GETTING PROPER AUTH URL.
Logger.log('Token'+driveService.getAccessToken()); // NEED TOKEN TO BE USED ON REST CALL
}
function createOauthService() {
return OAuth2.createService('drive')
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setClientId('MY CLOUD CONSOLE CLIENT ID')
.setClientSecret('MY SECREAT')
.setCallbackFunction('authCallback')
.setPropertyStore(PropertiesService.getUserProperties())
.setScope('https://www.googleapis.com/auth/drive')
.setParam('login_hint', Session.getActiveUser().getEmail())
.setParam('access_type', 'offline');
.setParam('approval_prompt', 'force');
}
Is this correct way or am i missing something ?
Please suggest.
One documented way to do this is to return a card from your buildAddOn() function which contains a button configured to launch the authorization sequence.
function buildAuthorizeCard() {
var authorizationUrl = getOAuthService().getAuthorizationUrl();
var card = CardService.newCardBuilder();
var section = CardService.newCardSection();
section.addWidget(CardService.newTextButton()
.setText("Authorize MyService")
.setAuthorizationAction(
CardService.newAuthorizationAction()
.setAuthorizationUrl(authorizationUrl)
));
card.addSection(section);
return card.build();
}
You can give that a try.