Stay organized with collections
Save and categorize content based on your preferences.
In a Google Workspace add-on you can create widgets
that have linked actions. You can use
an action to compose new email drafts, optionally filling them using
information entered into the add-on UI or information from an open message.
For example, you can have a button in your
add-on's message UI
that creates a reply to the currently opened message prepopulated with
information from the add-on.
When an action that builds messages is triggered, Gmail executes a callback
function to build and return the draft. Gmail then displays that draft in its
UI in a standard email compose window, which the user can then edit and send
as needed.
Configuring an action to build a draft message
To configure a widget to start a draft-building action when selected, you must
do the following:
Implement the callback function that executes the draft-building action. This
function is given an event object
as an argument. The callback function must do the following:
You can prefill the GmailDraft
you create in the callback function with
recipients, a subject, a message body, and attachments. To fill in the draft,
data can come from any source, but typically it derives from information
provided to the add-on itself, information in the open message, or
information gathered from a third-party service. The
event object
passed to the callback function contains the open message ID and other add-on
information you can use to prefill the draft.
You can create the draft as a new standalone message or a reply to
an existing message. This is controlled by the
ComposeEmailType
enum given to the
setComposeAction().
You can create reply drafts as single replies or 'reply-all' messages.
Standalone drafts
A standalone draft starts a new thread and isn't a reply to any existing
message. You can create a standalone draft with one of the following
Gmail service functions:
A reply draft is part of an existing message thread. Reply drafts are either
single replies that only get sent to the sender of a message or "reply all"
drafts that get sent to everyone who received that message. You can create a
reply draft with one of these Gmail service
functions:
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-18 UTC."],[[["\u003cp\u003eThis guide explains how to use Google Workspace add-ons to create new email drafts prefilled with information from the add-on or the currently open message.\u003c/p\u003e\n"],["\u003cp\u003eAdd-ons achieve this functionality by using actions associated with widgets like buttons, triggering callback functions to build and return drafts.\u003c/p\u003e\n"],["\u003cp\u003eTo implement this, you need to include a specific scope in your manifest, create an action object with a callback function, and configure the widget to trigger the action.\u003c/p\u003e\n"],["\u003cp\u003eThe callback function creates a GmailDraft object, builds a ComposeActionResponse, and can prefill the draft with data from various sources.\u003c/p\u003e\n"],["\u003cp\u003eDrafts can be created as standalone messages or replies (single or reply-all) using corresponding Gmail service functions.\u003c/p\u003e\n"]]],["Google Workspace add-ons can create new email drafts via linked actions in widgets. To configure this, the manifest needs the `action.compose` scope. A widget's `setComposeAction()` method links an `Action` object and `ComposeEmailType` to a callback function. This function generates a `GmailDraft` object using a `ComposeActionResponseBuilder`, which is then returned to populate the draft in Gmail's UI. Drafts can be standalone or replies, prefilled with data from various sources, including the event object.\n"],null,["# Composing draft messages\n\n| **Note:** The techniques described in this guide are primarily for creating new draft messages in response to user interactions in a [message UI](/workspace/add-ons/gmail/extending-message-ui). If you want your add-on to alter a draft the user is currently viewing, [extend the compose UI](/workspace/add-ons/gmail/extending-compose-ui) instead.\n\nIn a Google Workspace add-on you can create [widgets](/workspace/add-ons/concepts/widgets)\nthat have linked [actions](/workspace/add-ons/concepts/actions). You can use\nan action to compose new email drafts, optionally filling them using\ninformation entered into the add-on UI or information from an open message.\nFor example, you can have a button in your\n[add-on's message UI](/workspace/add-ons/gmail/extending-message-ui)\nthat creates a reply to the currently opened message prepopulated with\ninformation from the add-on.\n\nWhen an action that builds messages is triggered, Gmail executes a callback\nfunction to build and return the draft. Gmail then displays that draft in its\nUI in a standard email compose window, which the user can then edit and send\nas needed.\n\nConfiguring an action to build a draft message\n----------------------------------------------\n\nTo configure a widget to start a draft-building action when selected, you must\ndo the following:\n\n1. Make sure your [manifest](/workspace/add-ons/concepts/workspace-manifests#manifest_structure_for_g_suite_add-ons)\n includes the\n [`action.compose` scope](/workspace/add-ons/concepts/workspace-scopes#gmail_add-on_scopes):\n\n `https://www.googleapis.com/auth/gmail.addons.current.action.compose`\n\n You can use more a permissive scope instead, but should only do so if\n that scope is absolutely necessary.\n2. Create an [`Action`](/apps-script/reference/card-service/action) object\n and associate it with a [callback function](/workspace/add-ons/concepts/actions#callback_functions)\n you define.\n\n3. Call the widget's [`setComposeAction()`](/apps-script/reference/card-service/button#setComposeAction(Action,ComposedEmailType))\n [widget handler function](/workspace/add-ons/concepts/actions#widget_handler_functions),\n providing it the [`Action`](/apps-script/reference/card-service/action)\n object and specifying the\n [`ComposeEmailType`](/apps-script/reference/card-service/composed-email-type).\n\n4. Implement the callback function that executes the draft-building action. This\n function is given an [event object](/workspace/add-ons/concepts/actions#action_event_objects)\n as an argument. The callback function must do the following:\n\n 1. Create a [`GmailDraft`](/apps-script/reference/gmail/gmail-draft) object.\n 2. Build a [`ComposeActionResponse`](/apps-script/reference/card-service/compose-action-response) object using the [`ComposeActionResponseBuilder`](/apps-script/reference/card-service/compose-action-response-builder) class and the [`GmailDraft`](/apps-script/reference/gmail/gmail-draft) object.\n 3. Return the built [`ComposeActionResponse`](/apps-script/reference/card-service/compose-action-response).\n\nYou can prefill the [`GmailDraft`](/apps-script/reference/gmail/gmail-draft)\nyou create in the callback function with\nrecipients, a subject, a message body, and attachments. To fill in the draft,\ndata can come from any source, but typically it derives from information\nprovided to the add-on itself, information in the open message, or\ninformation gathered from a third-party service. The\n[event object](/workspace/add-ons/concepts/event-objects)\npassed to the callback function contains the open message ID and other add-on\ninformation you can use to prefill the draft.\n\nYou can create the draft as a new standalone message or a reply to\nan existing message. This is controlled by the\n[`ComposeEmailType`](/apps-script/reference/card-service/composed-email-type)\nenum given to the\n[`setComposeAction()`](/apps-script/reference/card-service/button#setComposeAction(Action,ComposedEmailType)).\nYou can create reply drafts as single replies or 'reply-all' messages.\n\n### Standalone drafts\n\nA standalone draft starts a new thread and isn't a reply to any existing\nmessage. You can create a standalone draft with one of the following\n[Gmail service](/apps-script/reference/gmail) functions:\n\n- [`GmailApp.createDraft(recipient, subject, body)`](/apps-script/reference/gmail/gmail-app#createDraft(String,String,String))\n- [`GmailApp.createDraft(recipient, subject, body, options)`](/apps-script/reference/gmail/gmail-app#createdraftrecipient-subject-body-options)\n\n### Reply drafts\n\nA reply draft is part of an existing message thread. Reply drafts are either\nsingle replies that only get sent to the sender of a message or \"reply all\"\ndrafts that get sent to everyone who received that message. You can create a\nreply draft with one of these [Gmail service](/apps-script/reference/gmail)\nfunctions:\n\n- [`GmailMessage.createDraftReply(body)`](/apps-script/reference/gmail/gmail-message#createdraftreplybody)\n- [`GmailMessage.createDraftReply(body, options)`](/apps-script/reference/gmail/gmail-message#createdraftreplybody-options)\n- [`GmailMessage.createDraftReplyAll(body)`](/apps-script/reference/gmail/gmail-message#createdraftreplyallbody)\n- [`GmailMessage.createDraftReplyAll(body, options)`](/apps-script/reference/gmail/gmail-message#createdraftreplyallbody-options)\n- [`GmailThread.createDraftReply(body)`](/apps-script/reference/gmail/gmail-thread#createdraftreplybody)\n- [`GmailThread.createDraftReply(body, options)`](/apps-script/reference/gmail/gmail-thread#createdraftreplybody-options)\n- [`GmailThread.createDraftReplyAll(body)`](/apps-script/reference/gmail/gmail-thread#createdraftreplyallbody)\n- [`GmailThread.createDraftReplyAll(body, options)`](/apps-script/reference/gmail/gmail-thread#createdraftreplyallbody-options)\n\nExample\n-------\n\nThe following code snippet shows how to assign an action that builds a reply\ndraft to a button. \n\n var composeAction = CardService.newAction()\n .setFunctionName('createReplyDraft');\n var composeButton = CardService.newTextButton()\n .setText('Compose Reply')\n .setComposeAction(\n composeAction,\n CardService.ComposedEmailType.REPLY_AS_DRAFT);\n\n // ...\n\n /**\n * Creates a draft email (with an attachment and inline image)\n * as a reply to an existing message.\n * @param {Object} e An event object passed by the action.\n * @return {ComposeActionResponse}\n */\n function createReplyDraft(e) {\n // Activate temporary Gmail scopes, in this case to allow\n // a reply to be drafted.\n var accessToken = e.gmail.accessToken;\n GmailApp.setCurrentMessageAccessToken(accessToken);\n\n // Creates a draft reply.\n var messageId = e.gmail.messageId;\n var message = GmailApp.getMessageById(messageId);\n var draft = message.createDraftReply('',\n {\n htmlBody: \"Kitten! \u003cimg src='cid:kitten'/\u003e\",\n attachments: [\n UrlFetchApp.fetch('https://example.com/images/myDog.jpg')\n .getBlob()\n ],\n inlineImages: {\n \"kitten\": UrlFetchApp.fetch('https://example.com/images/myKitten.jpg')\n .getBlob()\n }\n }\n );\n\n // Return a built draft response. This causes Gmail to present a\n // compose window to the user, pre-filled with the content specified\n // above.\n return CardService.newComposeActionResponseBuilder()\n .setGmailDraft(draft).build();\n }"]]