توسيع واجهة مستخدم الإنشاء باستخدام إجراءات الإنشاء

بالإضافة إلى توفير واجهة مستندة إلى البطاقات عندما يقرأ المستخدم رسائل 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: تمثل ملفًا شخصيًا يحدّد ما إذا كان سيتم إضافة محتوى HTML قابل للتغيير أو محتوى HTML غير القابل للتغيير (الذي لا يمكن لمستخدمي Gmail تعديله) أو محتوى نصي عادي.
  • UpdateDraftActionResponse: يمثّل ردًا على إجراء يؤدي إلى تعديل مسودة الرسالة الإلكترونية الحالية.
  • UpdateDraftActionResponseBuilder: أداة لإنشاء عناصر UpdateDraftActionResponse
  • UpdateDraftBodyAction: يمثّل إجراءً يعدّل نص مسودة الرسالة الإلكترونية الحالية.
  • UpdateDraftBodyType: تمثل ملفًا شخصيًا يحدّد كيفية تغيير النص.
  • UpdateDraftSubjectAction: يمثّل إجراءً يعدّل حقل الموضوع في مسودة الرسالة الإلكترونية الحالية.
  • UpdateDraftToRecipientsAction: يمثّل إجراءً يعدّل مستلمي "إلى" المسودة الحالية للرسالة الإلكترونية.
  • UpdateDraftCcRecipientsAction: يمثّل إجراءً يعدّل مستلمي نسخة إلى مسودة الرسالة الإلكترونية الحالية.
  • UpdateDraftBccRecipientsAction: يمثّل إجراءً يعدّل مستلمي نسخة مخفية الوجهة من مسودة الرسالة الإلكترونية الحالية.

عادةً ما تتضمّن واجهة المستخدم لإنشاء الرسائل الإلكترونية الإضافية تطبيقًا مصغّرًا "حفظ" أو "إدراج" يمكن للمستخدم النقر عليه للإشارة إلى أنّه قد انتهى من إجراء اختيارات في واجهة المستخدم ويريد إضافة اختياراته إلى الرسالة الإلكترونية التي ينشئها. لإضافة هذه الميزة التفاعلية، يجب أن يحتوي التطبيق المصغّر على عنصر 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;
    }