הרחבת ממשק המשתמש של הכתיבה עם פעולות כתיבה

בנוסף לאספקת ממשק מבוסס כרטיס כאשר המשתמש קורא הודעת Gmail הודעה, תוספים ל-Google Workspace שמרחיבים את Gmail יכול לספק ממשק נוסף כאשר המשתמש כותב הודעות חדשות, או להשיב להודעות קיימות. כך התוספים ל-Google Workspace יכולים להפוך את כתיבת האימיילים של המשתמש לאוטומטיות.

גישה לממשק המשתמש של 'כתיבה' של התוסף

יש שתי דרכים להציג את ממשק המשתמש של תוסף מסוים. הדרך הראשונה היא להתחיל כתיבת טיוטה חדשה או תשובה חדשה בזמן שהתוסף כבר פתוח. השנייה היא להתחיל את התוסף תוך כדי כתיבת טיוטה.

כל אחת מהאפשרויות גורמת לתוסף לבצע את הפונקציה המתאימה הוספת פונקציית טריגר, שמוגדרת בתוסף מניפסט. פונקציית הטריגר מסוג 'כתיבה' בונה את ממשק המשתמש של הכתיבה פעולה, ש-Gmail מציג למשתמש.

פיתוח תוסף לכתיבה

אפשר להוסיף לתוסף את הפונקציונליות של כתיבה מחדש באמצעות ביצוע הפעולות הכלליות הבאות:

  1. מוסיפים את gmail.composeTrigger. שדה לפרויקט הסקריפט של התוסף מניפסט ולעדכן את המניפסט היקפים להכללה האלה שנדרשות לביצוע פעולות הכתיבה.
  2. להטמיע פונקציית טריגר של כתיבה שיוצרת ממשק משתמש לכתיבה כאשר טריגר טריגרים. פונקציות הטריגר ליצירת הרכב מחזירות אובייקט Card או מערך של Card אובייקטים שמרכיבים ממשק המשתמש של הכתיבה עבור פעולת הכתיבה.
  3. להטמיע פונקציות קריאה חוזרת המשויכות כדי להגיב לפעולה של המשתמש ולכתוב אינטראקציות בממשק המשתמש. הפונקציות האלה הן לא פעולת ההרכבה עצמה (דבר שגורם רק להצגת ממשק המשתמש של הכתיבה); במקום זאת, תפקידים נפרדים שקובעים מה קורה כאשר רכיבים שונים נבחרו ממשק המשתמש של הכתיבה. לדוגמה, כרטיס ממשק משתמש שמכיל לחצן בדרך כלל משויכת אליו פונקציית קריאה חוזרת, שמופעלת כשמשתמש לוחץ הלחצן הזה. פונקציית קריאה חוזרת לווידג'טים שמעדכנים את טיוטת ההודעה התוכן צריך להחזיר UpdateDraftActionResponse לאובייקט.

כתיבת פונקציית טריגר

ממשק המשתמש של תוסף ליצירת תוכן זהה לזה של ההודעה של התוסף. ממשק משתמש - שימוש בשירות הכרטיסים של Apps Script כדי להרכיב כרטיסים ולמלא אותם ווידג'טים.

עליך ליישם gmail.composeTrigger.selectActions[].runFunction שאתם מגדירים במניפסט. פונקציית הטריגר מסוג 'כתיבה' צריכה להחזיר אובייקט Card יחיד או מערך של אובייקטים ב-Card שמרכיבים את ממשק המשתמש של הכתיבה לפעולה הזו. הפונקציות האלה דומות מאוד לפונקציות הפעלה לפי הקשר וצריכים ליצור כרטיסים באותו אופן.

הרכבת אובייקטים של אירוע טריגר

כשבוחרים פעולת כתיבה, היא מפעילה את טריגר הכתיבה המתאים פונקציה ומעבירה את הפונקציה אובייקט אירוע בתור פרמטר. אובייקט האירוע יכול לשאת מידע על ההקשר של התוסף ואת הטיוטה שחוברה לפונקציית הטריגר.

מידע נוסף על מבנה אובייקט של אירוע לקבלת פרטים על אופן ארגון המידע באובייקט האירוע. המידע שכלול באובייקט האירוע נשלט באופן חלקי על ידי הערך של gmail.composeTrigger.draftAccess שדה מניפסט:

  • אם gmail.composeTrigger.draftAccess שדה המניפסט הוא NONE או לא כלול, אובייקט האירוע כולל רק מידע מינימלי.

  • אם gmail.composeTrigger.draftAccess מוגדר ל-METADATA, אובייקט האירוע מועבר לפונקציית הטריגר של הרכבה מאוכלסים ברשימות של הנמענים של הודעת האימייל שכותבים.

הוספת תוכן לטיוטות פעילות

בדרך כלל ממשק משתמש של תוסף Google Workspace לכתיבה את האפשרויות למשתמש ואת אמצעי הבקרה שעוזרים לכתוב הודעה. בתרחישים לדוגמה כאלה, אחרי שהמשתמש בוחר אפשרויות בממשק המשתמש, התוסף מפרש את הבחירות ומעדכן את טיוטת האימייל הפעילה הנוכחית בהתאם.

כדי לעדכן בקלות את טיוטת האימייל הנוכחית, שירות הכרטיסים הוא הורחב לסוגים הבאים:

  • ContentType – 'טיפוסים בני מנייה (enum)' שמגדיר אם להוסיף HTML ניתן לשינוי, HTML שלא ניתן לשינוי (שהוא ב-Gmail משתמשים לא יכולים לערוך) או תוכן של טקסט פשוט.
  • UpdateDraftActionResponse – מייצג תגובה לפעולה שמעדכנת את טיוטת האימייל הנוכחית.
  • UpdateDraftActionResponseBuilder – א Builder עבור UpdateDraftActionResponse אובייקטים.
  • UpdateDraftBodyAction – מייצג פעולה שמעדכנת את התוכן של טיוטת האימייל הנוכחית.
  • UpdateDraftBodyType – 'טיפוסים בני מנייה (enum)' שמגדירים את האופן שבו הגוף משתנה.
  • UpdateDraftSubjectAction – מייצג פעולה שמעדכנת את שדה הנושא של טיוטת האימייל הנוכחית.
  • UpdateDraftToRecipientsAction – מייצג פעולה שמעדכנת את הנמענים של טיוטת האימייל הנוכחית.
  • UpdateDraftCcRecipientsAction – מייצג פעולה שמעדכנת את הנמענים בשדה 'עותק' של טיוטת האימייל הנוכחית.
  • UpdateDraftBccRecipientsAction – מייצג פעולה שמעדכנת את הנמענים בשדה 'עותק מוסתר' של טיוטת האימייל הנוכחית.

בדרך כלל ממשק משתמש של תוסף לכתיבה כולל את האפשרות Save (שמירה) או 'Insert' לווידג'ט של המשתמש יכולים ללחוץ כדי לציין שהם מסיימים לבחור אפשרויות בממשק המשתמש, שיצורפו לאימיילים שהם כותבים. כדי להוסיף את הפריט הזה interactivity, בווידג'ט צריך להיות אובייקט Action משויך מורה לתוסף להריץ פונקציית קריאה חוזרת ספציפית כשהווידג'ט בוצעה לחיצה. צריך להטמיע את פונקציות הקריאה החוזרת האלה. כל פונקציית קריאה חוזרת להחזיר מצב שנוצר UpdateDraftActionResponse אובייקט שמציין את השינויים שצריך לבצע בטיוטת האימייל הנוכחית.

דוגמה 1

קטע הקוד הבא מראה איך לבנות ממשק משתמש של כתיבה שמעדכן את הנושא, ואת הנמענים של טיוטת האימייל הנוכחית בשדה 'עותק' או 'עותק מוסתר'.

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