Gmail插件无法创建回复草稿:权限错误求助
Let's break down what's causing this error and how to fix it:
The Root Cause
Your current setup uses an unconditional contextual trigger that automatically runs createReplyDraft when the add-on loads. However, Gmail's Compose Actions (like creating a reply draft) require explicit user interaction (e.g., clicking a button) to execute—they can't be triggered automatically in the background. This mismatch is why you're seeing the "Cannot compose without user interaction" error.
Step-by-Step Fix
1. Update Your appsscript.json Configuration
Change the contextual trigger's onTriggerFunction to a new function that will render a card with your "Compose Reply" button (instead of directly running the draft creation logic):
{ "oauthScopes": [ "https://www.googleapis.com/auth/gmail.addons.execute", "https://www.googleapis.com/auth/gmail.addons.current.action.compose" ], "gmail": { "name": "Gmail Add-on Quickstart", "logoUrl": "https://www.gstatic.com/images/icons/material/system/2x/bookmark_black_24dp.png", "contextualTriggers": [{ "unconditional": {}, "onTriggerFunction": "showComposeButton" // Updated function name }], "openLinkUrlPrefixes": [ "https://mail.google.com/" ], "primaryColor": "#4285F4", "secondaryColor": "#4285F4" } }
2. Modify Your Code.gs File
Add a new function showComposeButton that builds and returns a card containing your "Compose Reply" button. This function will be triggered by the contextual trigger to display the button, and clicking the button will then run createReplyDraft:
// New function to render the card with the compose button function showComposeButton() { var composeAction = CardService.newAction().setFunctionName('createReplyDraft'); var composeButton = CardService.newTextButton() .setText('Compose Reply') .setComposeAction(composeAction, CardService.ComposedEmailType.REPLY_AS_DRAFT); var cardSection = CardService.newCardSection().addWidget(composeButton); var card = CardService.newCardBuilder().addSection(cardSection).build(); return [card]; } /** * 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('', { htmlBody: "Kitten!" } ); // 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(); }
Why This Works
- The contextual trigger now runs
showComposeButton, which only renders a card with a button—no automatic draft creation happens here. - When the user clicks the "Compose Reply" button, that explicit interaction triggers
createReplyDraft, which is allowed to generate the draft and open the compose panel.
Additional Notes
- You don't need the full
https://mail.google.com/scope for this functionality—your original scopes are sufficient. - After making these changes, redeploy your add-on and test it by opening an email in Gmail: you'll see your add-on's card with the button, and clicking it will correctly open the reply panel with your pre-filled content.
内容的提问来源于stack exchange,提问作者suyogricha

