使用撰寫動作擴充撰寫 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 動作本身 (這只會導致 Compose UI 顯示),而是個別函式,用於控制選取 Compose UI 的不同元素時會發生的情況。舉例來說,含有按鈕的 UI 資訊卡通常會附帶相關的回呼函式,在使用者按下該按鈕時執行。更新草稿訊息內容的資訊方塊回呼函式應傳回 UpdateDraftActionResponse 物件。

Compose 觸發條件函式

外掛程式的合成 UI 與外掛程式的訊息 UI 採用相同的建構方式,也就是使用 Apps Script Card 服務建構卡片,並用小工具填入卡片。

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

編寫觸發事件物件

選取 Compose 動作時,系統會執行對應的 Compose 觸發事件函式,並將 事件物件做為參數傳遞給函式。事件物件可攜帶關於外掛程式內容和要組合至觸發函式的草稿的資訊。

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

在有效草稿中插入內容

一般來說,Google Workspace 外掛程式撰寫 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

下列程式碼片段說明如何建構可將圖片插入目前草稿電子郵件中的撰寫 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;
    }