使用撰寫動作擴充 Compose UI

擴充 Gmail 的 Google Workspace 外掛程式除了可提供以卡片為基礎的介面,還能在使用者撰寫新郵件或回覆現有郵件時提供另一個介面。如此一來,Google Workspace 外掛程式就能自動為使用者撰寫電子郵件。

存取外掛程式 Compose UI

有兩種方式可以查看外掛程式的 Compose UI。第一種方法是在外掛程式開啟時撰寫新草稿或回覆。第二種方式是在撰寫草稿時啟動外掛程式。

無論如何,外掛程式都會執行外掛程式資訊清單中定義的對應 Compose 觸發條件函式。Compose 觸發條件函式會為該撰寫動作建構 Compose UI,以供 Gmail 向使用者顯示。

建立 Compose 外掛程式

您可以遵循以下的一般步驟,在外掛程式中新增撰寫功能:

  1. gmail.composeTrigger 欄位新增至外掛程式指令碼專案資訊清單,並更新資訊清單範圍,納入組合動作所需的項目。
  2. 實作 Compose 觸發條件函式,以便在觸發條件觸發時建構 Compose UI。Compose 觸發條件函式會傳回單一 Card 物件或 Card 物件陣列,這些物件組成 Compose 動作的 Compose UI。
  3. 實作相關的回呼函式,以回應使用者的 Compose UI 互動。這些函式不是組合動作本身 (只會導致 Compose UI 顯示),而是管理 Compose UI 不同元素時,其控制的個別函式。舉例來說,含有按鈕的 UI 資訊卡通常具有相關聯的回呼函式,並在使用者點選該按鈕時執行。更新訊息草稿內容小工具的回呼函式應會傳回 UpdateDraftActionResponse 物件。

Compose 觸發條件函式

外掛程式的 Compose UI 與外掛程式訊息 UI 的建構方式相同:使用 Apps Script 的「Card 服務」建構資訊卡,並以小工具填入資料。

您必須實作在資訊清單中定義的 gmail.composeTrigger.selectActions[].runFunction。Compose 觸發條件函式必須傳回單一 Card 物件或 Card 物件陣列,這些物件構成該動作的 Compose UI。這些函式與情境觸發條件函式非常相似,且應以相同的方式建構資訊卡。

Compose 觸發事件物件

選取組合動作後,系統會執行對應的 Compose 觸發條件函式,並將事件物件做為參數傳遞給函式。事件物件可包含外掛程式結構定義的相關資訊,以及撰寫至觸發條件函式的草稿。

如要進一步瞭解資訊在事件物件中的排列方式,請參閱事件物件結構。事件物件中包含的資訊由 gmail.composeTrigger.draftAccess 資訊清單欄位的值部分控制:

在有效草稿中插入內容

一般來說,Google Workspace 外掛程式 Compose UI 提供使用者選項和控制項,有助於撰寫訊息。針對這些用途,使用者在 UI 中選取選項後,外掛程式會解讀選項,據此更新目前運作的電子郵件草稿。

為了輕鬆更新目前的電子郵件草稿,我們已透過下列類別擴充卡片服務

一般來說,外掛程式撰寫 UI 包含「儲存」或「插入」小工具。使用者可以點選小工具,藉此表示他們已在 UI 中選取內容,且想要將所選設定新增至撰寫的電子郵件。如要新增這項互動,小工具應具有相關聯的 Action 物件,指示外掛程式在使用者點擊小工具時執行特定回呼函式。您必須實作這些回呼函式。每個回呼函式都應傳回一個建構的 UpdateDraftActionResponse 物件,詳述對目前電子郵件草稿所做的變更。

範例 1

下列程式碼片段說明如何建構撰寫 UI 以更新主旨,以及目前電子郵件草稿的收件者、副本、密件副本收件者。

    /**
     * Compose trigger function that fires when the compose UI is
     * requested. Builds and returns a compose UI for inserting images.
     *
     * @param {event} e The compose trigger event object. Not used in
     *         this example.
     * @return {Card[]}
     */
    function getComposeUI(e) {
      return [buildComposeCard()];
    }

    /**
     * Build a card to display interactive buttons to allow the user to
     * update the subject, and To, Cc, Bcc recipients.
     *
     * @return {Card}
     */
    function buildComposeCard() {

      var card = CardService.newCardBuilder();
      var cardSection = CardService.newCardSection().setHeader('Update email');
      cardSection.addWidget(
          CardService.newTextButton()
              .setText('Update subject')
              .setOnClickAction(CardService.newAction()
                  .setFunctionName('applyUpdateSubjectAction')));
      cardSection.addWidget(
          CardService.newTextButton()
              .setText('Update To recipients')
              .setOnClickAction(CardService.newAction()
                  .setFunctionName('updateToRecipients')));
      cardSection.addWidget(
          CardService.newTextButton()
              .setText('Update Cc recipients')
              .setOnClickAction(CardService.newAction()
                  .setFunctionName('updateCcRecipients')));
      cardSection.addWidget(
          CardService.newTextButton()
              .setText('Update Bcc recipients')
              .setOnClickAction(CardService.newAction()
                  .setFunctionName('updateBccRecipients')));
      return card.addSection(cardSection).build();
    }

    /**
     * Updates the subject field of the current email when the user clicks
     * on "Update subject" in the compose UI.
     *
     * Note: This is not the compose action that builds a compose UI, but
     * rather an action taken when the user interacts with the compose UI.
     *
     * @return {UpdateDraftActionResponse}
     */
    function applyUpdateSubjectAction() {
      // Get the new subject field of the email.
      // This function is not shown in this example.
      var subject = getSubject();
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftSubjectAction(CardService.newUpdateDraftSubjectAction()
              .addUpdateSubject(subject))
          .build();
      return response;
    }

    /**
     * Updates the To recipients of the current email when the user clicks
     * on "Update To recipients" in the compose UI.
     *
     * Note: This is not the compose action that builds a compose UI, but
     * rather an action taken when the user interacts with the compose UI.
     *
     * @return {UpdateDraftActionResponse}
     */
    function applyUpdateToRecipientsAction() {
      // Get the new To recipients of the email.
      // This function is not shown in this example.
      var toRecipients = getToRecipients();
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftToRecipientsAction(CardService.newUpdateDraftToRecipientsAction()
              .addUpdateToRecipients(toRecipients))
          .build();
      return response;
    }

    /**
     * Updates the Cc recipients  of the current email when the user clicks
     * on "Update Cc recipients" in the compose UI.
     *
     * Note: This is not the compose action that builds a compose UI, but
     * rather an action taken when the user interacts with the compose UI.
     *
     * @return {UpdateDraftActionResponse}
     */
    function applyUpdateCcRecipientsAction() {
      // Get the new Cc recipients of the email.
      // This function is not shown in this example.
      var ccRecipients = getCcRecipients();
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftCcRecipientsAction(CardService.newUpdateDraftCcRecipientsAction()
              .addUpdateToRecipients(ccRecipients))
          .build();
      return response;
    }

    /**
     * Updates the Bcc recipients  of the current email when the user clicks
     * on "Update Bcc recipients" in the compose UI.
     *
     * Note: This is not the compose action that builds a compose UI, but
     * rather an action taken when the user interacts with the compose UI.
     *
     * @return {UpdateDraftActionResponse}
     */
    function applyUpdateBccRecipientsAction() {
      // Get the new Bcc recipients of the email.
      // This function is not shown in this example.
      var bccRecipients = getBccRecipients();
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftBccRecipientsAction(CardService.newUpdateDraftBccRecipientsAction()
              .addUpdateToRecipients(bccRecipients))
          .build();
      return response;
    }

範例 2

下列程式碼片段說明如何建構 Compose UI,以將圖片插入目前的電子郵件草稿。

    /**
     * Compose trigger function that fires when the compose UI is
     * requested. Builds and returns a compose UI for inserting images.
     *
     * @param {event} e The compose trigger event object. Not used in
     *         this example.
     * @return {Card[]}
     */
    function getInsertImageComposeUI(e) {
      return [buildImageComposeCard()];
    }

    /**
     * Build a card to display images from a third-party source.
     *
     * @return {Card}
     */
    function buildImageComposeCard() {
      // Get a short list of image URLs to display in the UI.
      // This function is not shown in this example.
      var imageUrls = getImageUrls();

      var card = CardService.newCardBuilder();
      var cardSection = CardService.newCardSection().setHeader('My Images');
      for (var i = 0; i < imageUrls.length; i++) {
        var imageUrl = imageUrls[i];
        cardSection.addWidget(
            CardService.newImage()
                .setImageUrl(imageUrl)
                .setOnClickAction(CardService.newAction()
                      .setFunctionName('applyInsertImageAction')
                      .setParameters({'url' : imageUrl})));
      }
      return card.addSection(cardSection).build();
    }

    /**
     * Adds an image to the current draft email when the image is clicked
     * in the compose UI. The image is inserted at the current cursor
     * location. If any content of the email draft is currently selected,
     * it is deleted and replaced with the image.
     *
     * Note: This is not the compose action that builds a compose UI, but
     * rather an action taken when the user interacts with the compose UI.
     *
     * @param {event} e The incoming event object.
     * @return {UpdateDraftActionResponse}
     */
    function applyInsertImageAction(e) {
      var imageUrl = e.parameters.url;
      var imageHtmlContent = '<img style=\"display: block\" src=\"'
           + imageUrl + '\"/>';
      var response = CardService.newUpdateDraftActionResponseBuilder()
          .setUpdateDraftBodyAction(CardService.newUpdateDraftBodyAction()
              .addUpdateContent(
                  imageHtmlContent,
                  CardService.ContentType.MUTABLE_HTML)
              .setUpdateType(
                  CardService.UpdateDraftBodyType.IN_PLACE_INSERT))
          .build();
      return response;
    }