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.
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"
}
}
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 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.
We've built a Google workspace add on meant for Docs. We've set it up to have a homepageTrigger in the manifest but we're running into an issue where the trigger isn't fired until the doc/page is refreshed. Looking at the executions in our Apps Script project, we're not seeing any runs of our homepage function at all.
It remains stuck on this loading screen when pressing the add on icon the first time. After refreshing and pressing the add on icon, the homepageTrigger gets fired and the add on loads correctly.
This happens on both a test deployment and when installed via the G Suite store. Using Chrome
Any idea what could be happening?
Repro steps (you can get the add on here)
Open up a new Google Doc
Tap the Fable add on icon in the right sidebar
Notice that its stuck on the loading screen
Refresh the page
Tap the Fable add on icon in the right sidebar
Notice that it loads correctly now
This is what the manifest looks like (the 'onHomepage' function is not even being triggered the first time I tap the add on icon. It only gets triggered after refreshing the page/doc and hitting the icon again)
{
"timeZone": "America/New_York",
"dependencies": {
"libraries": [
{
"userSymbol": "FirestoreApp",
"version": "33",
"libraryId": "1VUSl4b1r1eoNcRWotZM3e87ygkxvXltOgyDZhixqncz9lQ3MjfT1iKFw"
}
]
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://www.googleapis.com/auth/documents.currentonly",
"https://www.googleapis.com/auth/script.container.ui",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/script.locale",
"https://www.googleapis.com/auth/userinfo.profile"
],
"urlFetchWhitelist": [
"https://fable-mvp.web.app/",
"https://auth.atlassian.com/",
"https://api.atlassian.com/",
"https://ssl.google-analytics.com/collect"
],
"runtimeVersion": "V8",
"addOns": {
"common": {
"name": "Fable",
"logoUrl": "https://uploads-ssl.webflow.com/5fe143c5b48f8aab75293f8e/60230e8975a93a6b391baaeb_fable_ikon_16x16_transparent2.png",
"useLocaleFromApp": true,
"homepageTrigger": {
"runFunction": "onHomepage",
"enabled": true
},
"layoutProperties": {
"secondaryColor": "#00BFA6"
},
"universalActions": [
{
"label": "Learn more about Fable",
"openLink": "https://tryfable.com"
}
]
},
"docs": {}
}
}
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.