ขยาย UI ของ Compose ด้วยการดำเนินการของ Compose

นอกจากจะแสดงอินเทอร์เฟซแบบการ์ดเมื่อผู้ใช้อ่านข้อความ Gmail แล้ว ส่วนเสริม Google Workspace ที่ขยาย Gmail ยังแสดงอินเทอร์เฟซอีกแบบเมื่อผู้ใช้เขียนข้อความใหม่หรือตอบกลับข้อความที่มีอยู่ได้ด้วย ซึ่งจะช่วยให้ส่วนเสริมทำงานอัตโนมัติในการเขียนอีเมลให้ผู้ใช้ได้

เข้าถึง UI การเขียนของส่วนเสริม Google Workspace

คุณดู UI การเขียนของส่วนเสริมได้ 2 วิธี วิธีแรกคือเริ่มเขียนฉบับร่างใหม่หรือตอบกลับขณะที่ ส่วนเสริมเปิดอยู่แล้ว วิธีที่ 2 คือการเริ่ม ส่วนเสริมขณะเขียนฉบับร่าง

ไม่ว่าในกรณีใดก็ตาม ส่วนเสริมจะเรียกใช้ฟังก์ชันทริกเกอร์การเขียนที่เกี่ยวข้อง ซึ่งกำหนดไว้ในไฟล์ Manifest ของส่วนเสริม ฟังก์ชันทริกเกอร์การเขียนจะสร้าง UI การเขียนสำหรับการดำเนินการเขียนนั้น ซึ่ง Gmail จะแสดงต่อผู้ใช้

สร้างส่วนเสริมการเขียน

คุณเพิ่มฟังก์ชันการเขียนลงในส่วนเสริมได้โดย ทำตามขั้นตอนทั่วไปต่อไปนี้

  1. เพิ่มฟิลด์ gmail.composeTrigger ลงในโปรเจ็กต์สคริปต์ของส่วนเสริม ไฟล์ Manifest และอัปเดตขอบเขตของไฟล์ Manifest ให้รวมขอบเขตที่จำเป็นสำหรับการดำเนินการเขียน
  2. ใช้ฟังก์ชันทริกเกอร์การเขียนที่สร้าง UI การเขียนเมื่อทริกเกอร์ทำงาน ฟังก์ชันทริกเกอร์การเขียนจะแสดงผลออบเจ็กต์ Card รายการเดียวหรืออาร์เรย์ของออบเจ็กต์ Card ที่สร้าง UI การเขียนสำหรับการดำเนินการเขียน
  3. ใช้ฟังก์ชันเรียกกลับที่เชื่อมโยงซึ่งจำเป็นต่อการตอบสนองต่อการโต้ตอบ UI การเขียนของผู้ใช้ ฟังก์ชันเหล่านี้ไม่ใช่การดำเนินการเขียนเอง (ซึ่งจะทำให้ UI การเขียนปรากฏขึ้นเท่านั้น) แต่เป็น ฟังก์ชันแต่ละรายการที่ควบคุมสิ่งที่เกิดขึ้นเมื่อเลือกองค์ประกอบต่างๆ ของ UI การเขียน ตัวอย่างเช่น การ์ด UI ที่มีปุ่มมักจะมีฟังก์ชัน Callback ที่เชื่อมโยงกันซึ่งจะทำงานเมื่อผู้ใช้คลิกปุ่มนั้น ฟังก์ชัน Callback สำหรับวิดเจ็ตที่อัปเดตเนื้อหาข้อความฉบับร่างควรแสดงผลออบเจ็กต์ UpdateDraftActionResponse

ฟังก์ชันทริกเกอร์การเขียน

UI การเขียนของส่วนเสริมสร้างขึ้นในลักษณะเดียวกับ UI ข้อความของส่วนเสริม โดยใช้ Card Service ของ Apps Script เพื่อสร้างการ์ดและใส่วิดเจ็ต

คุณต้องใช้ gmail.composeTrigger.selectActions[].runFunction ที่กำหนดไว้ในไฟล์ Manifest ฟังก์ชันทริกเกอร์การเขียนต้องแสดงผล ออบเจ็กต์ Card รายการเดียวหรือ อาร์เรย์ของออบเจ็กต์ Card ที่สร้าง UI การเขียนสำหรับการดำเนินการนั้น ฟังก์ชันเหล่านี้คล้ายกับฟังก์ชันทริกเกอร์ตามบริบท มาก และควรสร้างการ์ดในลักษณะเดียวกัน

เขียนออบเจ็กต์เหตุการณ์ทริกเกอร์

เมื่อเลือกการดำเนินการเขียน ระบบจะเรียกใช้ฟังก์ชันทริกเกอร์การเขียนที่เกี่ยวข้อง และส่งออบเจ็กต์เหตุการณ์ เป็นพารามิเตอร์ไปยังฟังก์ชัน ออบเจ็กต์เหตุการณ์สามารถส่งข้อมูลเกี่ยวกับ บริบทของส่วนเสริมและฉบับร่างที่กำลังเขียนไปยัง ฟังก์ชันทริกเกอร์ได้

ดูรายละเอียดเกี่ยวกับวิธีจัดเรียงข้อมูลในออบเจ็กต์เหตุการณ์ได้ที่โครงสร้างออบเจ็กต์เหตุการณ์ ข้อมูล ที่อยู่ในออบเจ็กต์เหตุการณ์จะได้รับการควบคุมบางส่วนโดยค่าของฟิลด์ gmail.composeTrigger.draftAccess ในไฟล์ Manifest

  • หากฟิลด์ gmail.composeTrigger.draftAccess manifest เป็น NONE หรือไม่ได้รวมไว้ ออบเจ็กต์เหตุการณ์จะมีข้อมูลเพียงเล็กน้อย เท่านั้น

  • หากตั้งค่า gmail.composeTrigger.draftAccess เป็น METADATA ระบบจะป้อนข้อมูลรายการผู้รับอีเมลที่กำลังเขียนลงในออบเจ็กต์เหตุการณ์ที่ส่งไปยังฟังก์ชันทริกเกอร์การเขียน การใช้สิทธิ์เข้าถึงฉบับร่างMETADATAกำหนดให้ Manifest ของส่วนเสริมต้องมีhttps://www.googleapis.com/auth/gmail.addons.current.message.metadata ขอบเขต Gmail

แทรกเนื้อหาลงในฉบับร่างที่ใช้งานอยู่

โดยปกติแล้ว UI การเขียนของส่วนเสริมจะแสดงตัวเลือกและ การควบคุมที่ช่วยให้ผู้ใช้เขียนข้อความได้ สำหรับกรณีการใช้งานเหล่านี้ เมื่อผู้ใช้เลือกใน UI แล้ว ส่วนเสริมจะตีความตัวเลือกและอัปเดตอีเมลฉบับร่างที่กำลังทำงานอยู่ตามนั้น

เราได้ขยายบริการการ์ด ด้วยคลาสต่อไปนี้เพื่อให้คุณอัปเดตอีเมลฉบับร่างปัจจุบันได้ง่ายขึ้น

  • ContentType - Enum ที่กำหนดว่าจะเพิ่ม HTML ที่แก้ไขได้, HTML ที่แก้ไขไม่ได้ (ซึ่งผู้ใช้ Gmail แก้ไขไม่ได้) หรือเนื้อหาข้อความธรรมดา
  • UpdateDraftActionResponse - แสดงถึง การตอบกลับการดำเนินการที่อัปเดตอีเมลฉบับร่างปัจจุบัน
  • UpdateDraftActionResponseBuilder - เครื่องมือสร้างสำหรับออบเจ็กต์ UpdateDraftActionResponse
  • UpdateDraftBodyAction - แสดงถึง การดำเนินการที่อัปเดตเนื้อหาของอีเมลฉบับร่างปัจจุบัน
  • UpdateDraftBodyType - Enum ที่กำหนดวิธีเปลี่ยนเนื้อหา
  • UpdateDraftSubjectAction - แสดงถึง การดำเนินการที่อัปเดตช่องเรื่องของอีเมลฉบับร่างปัจจุบัน
  • UpdateDraftToRecipientsAction - แสดงถึง การดำเนินการที่อัปเดตผู้รับในฟิลด์ "ถึง" ของอีเมลฉบับร่างปัจจุบัน
  • UpdateDraftCcRecipientsAction - แสดงถึง การดำเนินการที่อัปเดตผู้รับสำเนาของอีเมลฉบับร่างปัจจุบัน
  • UpdateDraftBccRecipientsAction - แสดงถึง การดำเนินการที่อัปเดตผู้รับสำเนาลับของอีเมลฉบับร่างปัจจุบัน

โดยปกติแล้ว UI การเขียนของส่วนเสริมจะมีวิดเจ็ต "บันทึก" หรือ "แทรก" ที่ผู้ใช้คลิกเพื่อระบุว่าได้เลือกใน UI เสร็จแล้ว และต้องการเพิ่มตัวเลือกของตนลงในอีเมลที่กำลังเขียน หากต้องการเพิ่มการโต้ตอบนี้ วิดเจ็ตควรมีออบเจ็กต์ Action ที่เชื่อมโยงซึ่งสั่งให้ ส่วนเสริมเรียกใช้ฟังก์ชัน Callback ที่เฉพาะเจาะจงเมื่อมีการคลิกวิดเจ็ต คุณต้องใช้ฟังก์ชันการเรียกกลับเหล่านี้ ฟังก์ชันเรียกกลับแต่ละรายการควรคืนค่าออบเจ็กต์ UpdateDraftActionResponse ที่สร้างขึ้น ซึ่งแสดงรายละเอียดการเปลี่ยนแปลงที่จะทำกับอีเมลฉบับร่างปัจจุบัน

ตัวอย่างที่ 1

ข้อมูลโค้ดต่อไปนี้แสดงวิธีสร้าง UI ของ Compose ที่อัปเดตเรื่อง รวมถึงผู้รับในช่องถึง สำเนา และสำเนาลับของฉบับร่างอีเมลปัจจุบัน

/**
 * 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 ที่แทรกรูปภาพลงในอีเมลฉบับร่างปัจจุบัน

/**
 * 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;
}