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

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

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

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

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

إنشاء إضافة خاصة بكتابة الرسائل

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

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

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

يتم إنشاء واجهة المستخدم الخاصة بإنشاء الرسائل في الإضافة بالطريقة نفسها التي يتم بها إنشاء واجهة المستخدم الخاصة بالرسائل في الإضافة، وذلك باستخدام خدمة البطاقات في Apps Script لإنشاء بطاقات وملؤها بالعناصر.

يجب تنفيذ gmail.composeTrigger.selectActions[].runFunction الذي تحدّده في بيان التطبيق. يجب أن تعرض دالة مشغّل الإنشاء إما كائن Card واحدًا أو مصفوفة من كائنات Card التي تشكّل واجهة مستخدم الإنشاء لهذا الإجراء. وتتشابه هذه الدوال كثيرًا مع دوال التشغيل السياقي، ويجب أن تنشئ البطاقات بالطريقة نفسها.

إنشاء عناصر حدث التشغيل

عند تحديد إجراء إنشاء، يتم تنفيذ دالة مشغّل الإنشاء المقابلة، ويتم تمرير عنصر حدث إلى الدالة كمعلَمة. يمكن أن يحمل عنصر الحدث معلومات حول سياق الإضافة والمسودة التي يتم إنشاؤها لتشغيل الدالة.

اطّلِع على بنية عنصر الحدث للحصول على تفاصيل حول كيفية ترتيب المعلومات في عنصر الحدث. تخضع المعلومات الواردة في عنصر الحدث جزئيًا لقيمة حقل gmail.composeTrigger.draftAccess في ملف البيان، وذلك على النحو التالي:

  • إذا كان حقل gmail.composeTrigger.draftAccess في ملف البيان هو NONE أو لم يتم تضمينه، سيحتوي عنصر الحدث على معلومات بسيطة فقط.

  • إذا تم ضبط gmail.composeTrigger.draftAccess على METADATA، سيتم ملء عنصر الحدث الذي تم تمريره إلى دالة مشغّل الإنشاء بقوائم المستلمين للرسالة الإلكترونية التي يتم إنشاؤها. يتطلّب استخدام METADATA الوصول إلى المسودّة أن يتضمّن بيان الإضافة https://www.googleapis.com/auth/gmail.addons.current.message.metadata نطاق Gmail.

إدراج محتوى في المسودات النشطة

عادةً ما توفّر واجهة مستخدم إنشاء الإضافة خيارات للمستخدم وعناصر تحكّم تساعد في إنشاء رسالة. في حالات الاستخدام هذه، بعد أن يحدّد المستخدم خيارات في واجهة المستخدم، تفسّر الإضافة هذه الخيارات وتعدّل مسودة الرسالة الإلكترونية الحالية وفقًا لذلك.

لتسهيل تعديل مسودة الرسالة الإلكترونية الحالية، تم توسيع نطاق خدمة البطاقات لتشمل الفئات التالية:

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

عادةً ما تتضمّن واجهة مستخدم إضافة الإنشاء عنصر واجهة مستخدم "حفظ" أو "إدراج" يمكن للمستخدم النقر عليه للإشارة إلى أنّه انتهى من إجراء اختيارات في واجهة المستخدم ويريد إضافة خياراته إلى الرسالة الإلكترونية التي يكتبها. لإضافة هذه التفاعلية، يجب أن يحتوي التطبيق المصغّر على Action مرتبط يطلب من الإضافة تنفيذ دالّة رد الاتصال محدّدة عند النقر على التطبيق المصغّر. يجب تنفيذ دوال رد الاتصال هذه. يجب أن تعرض كل دالة ردّ UpdateDraftActionResponse عنصرًا يوضّح بالتفصيل التغييرات التي يجب إجراؤها على مسودة الرسالة الإلكترونية الحالية.

مثال 1

يوضّح مقتطف الرمز التالي كيفية إنشاء واجهة مستخدم 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

يوضّح مقتطف الرمز التالي كيفية إنشاء واجهة مستخدم متوافقة مع 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;
}