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

بالإضافة إلى توفير واجهة مستندة إلى البطاقة عند قراءة المستخدم لرسالة Gmail، يمكن أن توفّر إضافات Google Workspace التي تعمل على توسيع نطاق Gmail واجهة أخرى عند إنشاء المستخدم لرسائل جديدة أو الرد على رسائل حالية. يسمح هذا الإجراء لإضافات Google Workspace ببرمجة مهمة إنشاء الرسائل الإلكترونية للمستخدم.

الوصول إلى واجهة مستخدم إنشاء الإضافة

هناك طريقتان لعرض واجهة المستخدم لإنشاء الإضافة. الطريقة الأولى هي البدء في إنشاء مسودة أو رد جديد عندما تكون الإضافة مفتوحة بالفعل. الطريقة الثانية هي بدء الإضافة أثناء إنشاء مسودة.

وتؤدي كلتا الحالتين إلى تنفيذ الإضافة لدالة إنشاء دالة المشغِّل المقابلة لها، والتي تم تحديدها في بيان الإضافة. تعمل وظيفة مشغّل الإنشاء على إنشاء واجهة المستخدم لإجراء الإنشاء هذا، والتي يعرضها Gmail بعد ذلك للمستخدم.

إنشاء إضافة إنشاء

يمكنك إضافة وظيفة الإنشاء إلى إحدى الإضافات باتباع الخطوات العامة التالية:

  1. أضِف الحقل gmail.composeTrigger إلى مشروع النصوص البرمجية للإضافة بيان وعدِّل البيان النطاقات لتضمين تلك الإجراءات المطلوبة لتضمينها.
  2. نفِّذ وظيفة مشغِّل الإنشاء التي تنشئ واجهة مستخدم الإنشاء عند تنشيط المشغل. تعرض وظائف تشغيل الإنشاء إما كائن Card واحد أو مصفوفة من كائنات Card التي تشتمل على واجهة مستخدم الإنشاء لإجراء الإنشاء.
  3. يمكنك تنفيذ وظائف معاودة الاتصال المرتبطة واللازمة للاستجابة لتفاعلات واجهة المستخدم التي يتم إنشاؤها. هذه الدوال ليست هي إجراء الإنشاء في حد ذاتها (الأمر الذي يؤدي فقط إلى ظهور واجهة المستخدم لإنشاء المحتوى)، بل الوظائف الفردية التي تحكم ما يحدث عند اختيار عناصر مختلفة من واجهة المستخدم المنشأة. على سبيل المثال، بطاقة واجهة المستخدم التي تحتوي على زر عادةً ما تحتوي على وظيفة استدعاء مرتبطة يتم تنفيذها عندما ينقر المستخدم على هذا الزر. من المفترض أن تعرض وظيفة معاودة الاتصال للتطبيقات المصغّرة التي تعدّل محتوى مسودة الرسالة كائن UpdateDraftActionResponse.

إنشاء دالة المشغِّل

يتم تصميم واجهة المستخدم لإنشاء الإضافات بالطريقة نفسها التي يتم بها تصميم واجهة مستخدم رسالة الإضافة باستخدام خدمة بطاقة "برمجة التطبيقات" لإنشاء البطاقات وتعبئتها بالتطبيقات المصغّرة.

يجب تنفيذ 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;
    }