الردّ على الحوادث باستخدام Google Chat وVertex AI وبرمجة التطبيقات

يشرح هذا الدليل التوجيهي كيفية إنشاء تطبيق Google Chat يستجيب للحوادث في الوقت الفعلي. عند الاستجابة لأي حادثة، ينشئ التطبيق مساحة Chat ويملأها، ويسهِّل حلّ الحوادث باستخدام الرسائل والأوامر التي تبدأ بشرطة مائلة ومربّعات الحوار، ويستخدم الذكاء الاصطناعي لتلخيص الاستجابة لمحاولات الاختراق الأمني في مستند "مستندات Google".

الحادثة هي حدث يتطلب الانتباه الفوري من فريق من الأشخاص لحله. تشمل الأمثلة على الحوادث ما يلي:

  • يتم إنشاء حالة حساسة للوقت في منصة إدارة العلاقات مع العملاء (CRM)، وتتطلب من فريق الخدمة التعاون في حل المشكلة.
  • لنفترض أن هناك نظامًا ينقطع اتصاله بالإنترنت، ويتم تنبيه مجموعة من مهندسي موثوقية الموقع (SREs) ليتمكنوا من العمل معًا لإعادته عبر الإنترنت مرة أخرى.
  • يحدث زلزال قوته، ويحتاج عمال الطوارئ إلى تنسيق استجابتهم.

لأغراض هذا البرنامج التعليمي، يبدأ تنبيه الحادث عندما يُبلغ أحد الأشخاص عن الحادثة بنقرة زر من صفحة ويب. تحاكي صفحة الويب حادثًا من خلال مطالبة المستخدمين بإدخال معلومات الحادث الأساسية: العنوان والوصف وعناوين البريد الإلكتروني للمستجيبين.

الاطّلاع على تطبيق Chat لإدارة الحوادث أثناء استخدامه:

  • موقع الويب الذي بدأ الحادث.
    الشكل 1. الموقع الإلكتروني حيث يمكن لأحد الأشخاص الإبلاغ عن حادث.
  • إشعار بإنشاء "مساحة Chat" للحادثة
    الشكل 2. إشعار بإنشاء "مساحة Chat" للحادثة
  • مساحة Chat للاستجابة للحوادث
    الشكل 3. مساحة Chat للاستجابة للحوادث
  • حل الحادث باستخدام أمر شرطة مائلة.
    الشكل 4. وحلّ الحادثة باستخدام أمر شرطة مائلة.
  • مربّع حوار لحلّ الحادث
    الشكل 5. مربّع حوار لحلّ الحادثة
  • تمت مشاركة مستند "مستندات Google" لحل الحوادث في المساحة.
    الشكل 6. تمت مشاركة مستند "مستندات Google" لحل الحوادث في المساحة.
  • مستند Google يعرض معلومات عن حلّ الحوادث المتعلّقة بملخّص الذكاء الاصطناعي (AI)
    الشكل 7. مستند ملخّص "مستندات Google" حول حلّ الحوادث المتعلّقة بالذكاء الاصطناعي

المتطلبات الأساسية

إذا كنت بحاجة إلى تفعيل أي من هذه المتطلبات الأساسية لمؤسستك، اطلب من مشرف Google Workspace تفعيلها:

  • حساب على Google Workspace يمكنه الوصول إلى Google Chat:
  • أن يتم تفعيل الدليل (مشاركة جهات الاتصال) في Google Workspace. يستخدم تطبيق الحوادث الدليل للبحث عن معلومات الاتصال الخاصة بالمستجيبين للحوادث، مثل الاسم وعنوان البريد الإلكتروني. يجب أن يكون مستجيبو الحوادث مستخدمين لديهم حساب Google Chat في مؤسستك على Google Workspace.

الأهداف

  • إنشاء تطبيق Chat للاستجابة للحوادث
  • ساعِد المستخدمين على الاستجابة للحوادث من خلال تنفيذ ما يلي:
    • إنشاء مساحات للاستجابة للحوادث
    • نشر رسائل تلخّص الحوادث والردود
    • تعزيز التعاون من خلال ميزات تطبيق Chat التفاعلية
  • يمكنك تلخيص المحادثات والحلول باستخدام Vertex AI.

هندسة معمارية

يوضّح المخطّط التالي بنية موارد Google Workspace وGoogle Cloud المستخدَمة في تطبيق Google Chat للاستجابة للحوادث.

بنية تطبيق Google Chat للاستجابة للحوادث

توضّح البنية كيفية الاستجابة لمحاولات الاختراق الأمني للاستجابة للحوادث.

  1. بدأ أحد المستخدمين حادثة من موقع إلكتروني خارجي مستضاف على لغة "برمجة تطبيقات Google".

  2. يرسل الموقع الإلكتروني طلب HTTP غير متزامن إلى تطبيق Google Chat المستضاف أيضًا على لغة "برمجة تطبيقات Google".

  3. يعالج تطبيق Google Chat للاستجابة للحوادث الطلب:

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

    2. من خلال مجموعة من طلبات HTTP إلى Chat API باستخدام خدمة "المحادثات المتقدّمة" لبرمجة التطبيقات، ينشئ تطبيق Google Chat مساحة Chat المتعلّقة بالحوادث، ويملأها بأعضاء الفريق، ويرسل رسالة إلى المساحة.

  4. يناقش أعضاء الفريق الحادث في "مساحة Chat".

  5. ويستدعي أحد أعضاء الفريق أمرًا يبدأ بشرطة مائلة للإشارة إلى حل الحادث.

    1. يؤدي طلب HTTP إلى Chat API باستخدام "برمجة التطبيقات" إلى إدراج جميع رسائل مساحة Chat.

    2. يتلقّى Vertex AI الرسائل المدرَجة وينشئ ملخّصًا.

    3. تنشئ خدمة "برمجة تطبيقات Google" DocumentApp مستندًا في "مستندات Google" وتضيف ملخّص Vertex AI إلى المستند.

    4. يطلب تطبيق Google Chat للاستجابة للحوادث واجهة برمجة تطبيقات Chat لإرسال رسالة تشارك رابطًا يؤدي إلى مستند الملخّص في "مستندات Google".

تهيئة البيئة

يوضّح هذا القسم كيفية إنشاء مشروع على Google Cloud وإعداده لتطبيق Chat.

إنشاء مشروع على Google Cloud

وحدة تحكُّم Google Cloud

  1. في Google Cloud Console، انتقِل إلى القائمة > إدارة الهوية وإمكانية الوصول والمشرف > إنشاء مشروع.

    الانتقال إلى صفحة إنشاء مشروع

  2. في حقل اسم المشروع، أدخِل اسمًا وصفيًا لمشروعك.

    اختياري: لتعديل رقم تعريف المشروع، انقر على تعديل. لا يمكن تغيير رقم تعريف المشروع بعد إنشاء المشروع، لذا اختَر معرّفًا يفي باحتياجاتك طوال فترة المشروع.

  3. في حقل الموقع الجغرافي، انقر على تصفّح لعرض المواقع الجغرافية المحتمَلة لمشروعك. بعد ذلك، انقر على اختيار.
  4. انقر على إنشاء. تنتقل وحدة التحكّم في Google Cloud إلى صفحة "لوحة البيانات" وسيتم إنشاء مشروعك في غضون بضع دقائق.

gcloud CLI

في إحدى بيئات التطوير التالية، يمكنك الوصول إلى واجهة سطر الأوامر في Google Cloud (`gcloud`):

  • Cloud Shell: لاستخدام وحدة طرفية على الإنترنت تم إعداد gcloud CLI عليها، فعِّل Cloud Shell.
    تفعيل Cloud Shell
  • Local Shell: لاستخدام بيئة تطوير محلية، عليك تثبيت initialize gcloud CLI.
    لإنشاء مشروع على السحابة الإلكترونية، استخدِم الأمر `gcloud project generate`:
    gcloud projects create PROJECT_ID
    استبدِل PROJECT_ID عن طريق ضبط رقم تعريف المشروع الذي تريد إنشاءه.

تفعيل الفوترة للمشروع على Google Cloud

وحدة تحكُّم Google Cloud

  1. في Google Cloud Console، انتقِل إلى الفوترة. انقر على القائمة > الفوترة > مشاريعي.

    الانتقال إلى صفحة "الفوترة في مشاريعي"

  2. في القسم اختيار مؤسسة، اختَر المؤسسة المرتبطة بمشروعك على Google Cloud.
  3. في صف المشروع، افتح قائمة الإجراءات ()، وانقر على تغيير الفوترة، واختَر حساب فوترة Cloud.
  4. انقر على ضبط الحساب.

gcloud CLI

  1. لإدراج حسابات الفوترة المتاحة، شغِّل:
    gcloud billing accounts list
  2. ربط حساب فوترة بمشروع على Google Cloud:
    gcloud billing projects link PROJECT_ID --billing-account=BILLING_ACCOUNT_ID

    استبدل ما يلي:

    • PROJECT_ID هو رقم تعريف المشروع للمشروع على Google Cloud الذي تريد تفعيل الفوترة له.
    • BILLING_ACCOUNT_ID هو رقم تعريف حساب الفوترة المطلوب ربطه بمشروع Google Cloud.

تفعيل واجهات برمجة التطبيقات

وحدة تحكُّم Google Cloud

  1. في Google Cloud Console، فعِّل واجهة برمجة التطبيقات Google Chat وواجهة برمجة تطبيقات "مستندات Google" وAdmin SDK API وVertex AI API.

    تفعيل واجهات برمجة التطبيقات

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

  3. تأكّد من تفعيل واجهات برمجة التطبيقات الصحيحة، ثم انقر على تفعيل.

gcloud CLI

  1. إذا لزم الأمر، اضبط المشروع الحالي على Google Cloud على المشروع الذي أنشأته باستخدام الأمر gcloud config set project:

    gcloud config set project PROJECT_ID
    

    استبدِل PROJECT_ID برقم تعريف المشروع الخاص بمشروع Cloud الذي أنشأته.

  2. تفعيل واجهة برمجة تطبيقات Google Chat وواجهة برمجة تطبيقات "مستندات Google" وAdmin SDK API وVertex AI API باستخدام الأمر gcloud services enable:

    gcloud services enable chat.googleapis.com docs.googleapis.com admin.googleapis.com aiplatform.googleapis.com
    

إعداد المصادقة والترخيص

تتيح المصادقة والترخيص لتطبيق Chat الوصول إلى الموارد في Google Workspace وGoogle Cloud لمعالجة الحوادث.

في هذا البرنامج التعليمي، تقوم بنشر التطبيق داخليًا بحيث يُسمح باستخدام معلومات العنصر النائب. قبل نشر التطبيق خارجيًا، استبدل معلومات العنصر النائب بمعلومات حقيقية لشاشة الموافقة.

  1. في وحدة تحكُّم Google Cloud، انتقِل إلى القائمة > واجهات برمجة التطبيقات والخدمات > شاشة موافقة OAuth.

    الانتقال إلى شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth

  2. ضمن نوع المستخدم، اختَر داخلي، ثم انقر على إنشاء.

  3. في اسم التطبيق، اكتب Incident Management.

  4. في البريد الإلكتروني لدعم المستخدم، اختَر عنوان بريدك الإلكتروني أو مجموعة مناسبة على Google.

  5. ضمن معلومات الاتصال بالمطوِّر، أدخِل عنوان بريدك الإلكتروني.

  6. انقر على حفظ ومتابعة.

  7. انقر على إضافة نطاقات أو إزالتها. تظهر لوحة تحتوي على قائمة بالنطاقات لكل واجهة برمجة تطبيقات تم تفعيلها في مشروعك على السحابة الإلكترونية.

  8. ضمن إضافة النطاقات يدويًا، ألصِق النطاقات التالية:

    • https://www.googleapis.com/auth/chat.spaces.create
    • https://www.googleapis.com/auth/chat.memberships
    • https://www.googleapis.com/auth/chat.memberships.app
    • https://www.googleapis.com/auth/chat.messages
    • https://www.googleapis.com/auth/documents
    • https://www.googleapis.com/auth/admin.directory.user.readonly
    • https://www.googleapis.com/auth/script.external_request
    • https://www.googleapis.com/auth/userinfo.email
    • https://www.googleapis.com/auth/cloud-platform
  9. انقر على إضافة إلى الجدول.

  10. انقر على تعديل.

  11. انقر على حفظ ومتابعة.

  12. راجع ملخص تسجيل التطبيق، ثم انقر على الرجوع إلى لوحة البيانات.

إنشاء تطبيق Chat ونشره

في القسم التالي، يمكنك نسخ وتعديل مشروع "برمجة تطبيقات Google" بالكامل يحتوي على جميع رموز التطبيق المطلوبة لتطبيق Chat، وبذلك لا تكون هناك حاجة لنسخ كل ملف ولصقه.

وتشمل بعض الدوال شرطات سفلية في نهاية الأسماء، مثل processSlashCommand_() من ChatApp.gs. تخفي الشرطة السفلية الدالة من صفحة ويب تهيئة الحادث عندما تكون مفتوحة في متصفح. لمزيد من المعلومات، راجِع الدوال الخاصة.

تتوافق لغة "برمجة تطبيقات Google" مع نوعَين من الملفات، هما نصوص .gs البرمجية و.html. للالتزام بهذا الدعم، يتم تضمين JavaScript من جهة العميل في التطبيق داخل علامات <script /> ويتم تضمين لغة CSS الخاصة به داخل علامات <style /> داخل ملف HTML.

اختياريًا، يمكنك عرض المشروع بأكمله على جيت هب.

العرض على GitHub

في ما يلي نظرة عامة حول كل ملف:

Consts.gs

تحدِّد هذه السياسة الثوابت التي تشير إليها ملفات الرموز الأخرى، بما في ذلك رقم تعريف المشروع على السحابة الإلكترونية ومعرّف الموقع الجغرافي لـ Vertex AI ومعرّف الأمر الذي يبدأ بشرطة مائلة لإغلاق حادثة.

الاطّلاع على رمز Consts.gs

apps-script/incident-response/Consts.gs
const PROJECT_ID = 'replace-with-your-project-id';
const VERTEX_AI_LOCATION_ID = 'us-central1';
const CLOSE_INCIDENT_COMMAND_ID = 1;
ChatApp.gs

تتعامل مع أحداث التفاعل في Chat، بما في ذلك الرسائل والنقرات على البطاقات والأوامر المائلة ومربّعات الحوار. للاستجابة لأمر الشرطة المائلة /closeIncident من خلال فتح مربّع حوار لجمع تفاصيل التعامل مع الحوادث. تقرأ الرسائل في المساحة من خلال طلب طريقة spaces.messages.list في Chat API. للحصول على أرقام تعريف المستخدمين باستخدام خدمة "دليل SDK للمشرف" في "برمجة التطبيقات".

الاطّلاع على رمز ChatApp.gs

apps-script/incident-response/ChatApp.gs
/**
 * Responds to a MESSAGE event in Google Chat.
 *
 * This app only responds to a slash command with the ID 1 ("/closeIncident").
 * It will respond to any other message with a simple "Hello" text message.
 *
 * @param {Object} event the event object from Google Chat
 */
function onMessage(event) {
  if (event.message.slashCommand) {
    return processSlashCommand_(event);
  }
  return { "text": "Hello from Incident Response app!" };
}

/**
 * Responds to a CARD_CLICKED event in Google Chat.
 *
 * This app only responds to one kind of dialog (Close Incident).
 *
 * @param {Object} event the event object from Google Chat
 */
function onCardClick(event) {
  if (event.isDialogEvent) {
    if (event.dialogEventType == 'SUBMIT_DIALOG') {
      return processSubmitDialog_(event);
    }
    return {
      actionResponse: {
        type: "DIALOG",
        dialogAction: {
          actionStatus: "OK"
        }
      }
    };
  }
}

/**
 * Responds to a MESSAGE event with a Slash command in Google Chat.
 *
 * This app only responds to a slash command with the ID 1 ("/closeIncident")
 * by returning a Dialog.
 *
 * @param {Object} event the event object from Google Chat
 */
function processSlashCommand_(event) {
  if (event.message.slashCommand.commandId != CLOSE_INCIDENT_COMMAND_ID) {
    return {
      "text": "Command not recognized. Use the command `/closeIncident` to close the incident managed by this space."
    };
  }
  const sections = [
    {
      header: "Close Incident",
      widgets: [
        {
          textInput: {
            label: "Please describe the incident resolution",
            type: "MULTIPLE_LINE",
            name: "description"
          }
        },
        {
          buttonList: {
            buttons: [
              {
                text: "Close Incident",
                onClick: {
                  action: {
                    function: "closeIncident"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  ];
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: {
        dialog: {
          body: {
            sections,
          }
        }
      }
    }
  };
}

/**
 * Responds to a CARD_CLICKED event with a Dialog submission in Google Chat.
 *
 * This app only responds to one kind of dialog (Close Incident).
 * It creates a Doc with a summary of the incident information and posts a message
 * to the space with a link to the Doc.
 *
 * @param {Object} event the event object from Google Chat
 */
function processSubmitDialog_(event) {
  const resolution = event.common.formInputs.description[""].stringInputs.value[0];
  const chatHistory = concatenateAllSpaceMessages_(event.space.name);
  const chatSummary = summarizeChatHistory_(chatHistory);
  const docUrl = createDoc_(event.space.displayName, resolution, chatHistory, chatSummary);
  return {
    actionResponse: {
      type: "NEW_MESSAGE",
    },
    text: `Incident closed with the following resolution: ${resolution}\n\nHere is the automatically generated post-mortem:\n${docUrl}`
  };
}

/**
 * Lists all the messages in the Chat space, then concatenate all of them into
 * a single text containing the full Chat history.
 *
 * For simplicity for this demo, it only fetches the first 100 messages.
 *
 * Messages with slash commands are filtered out, so the returned history will
 * contain only the conversations between users and not app command invocations.
 *
 * @return {string} a text containing all the messages in the space in the format:
 *          Sender's name: Message
 */
function concatenateAllSpaceMessages_(spaceName) {
  // Call Chat API method spaces.messages.list
  const response = Chat.Spaces.Messages.list(spaceName, { 'pageSize': 100 });
  const messages = response.messages;
  // Fetch the display names of the message senders and returns a text
  // concatenating all the messages.
  let userMap = new Map();
  return messages
    .filter(message => message.slashCommand === undefined)
    .map(message => `${getUserDisplayName_(userMap, message.sender.name)}: ${message.text}`)
    .join('\n');
}

/**
 * Obtains the display name of a user by using the Admin Directory API.
 *
 * The fetched display name is cached in the provided map, so we only call the API
 * once per user.
 *
 * If the user does not have a display name, then the full name is used.
 *
 * @param {Map} userMap a map containing the display names previously fetched
 * @param {string} userName the resource name of the user
 * @return {string} the user's display name
 */
function getUserDisplayName_(userMap, userName) {
  if (userMap.has(userName)) {
    return userMap.get(userName);
  }
  let displayName = 'Unknown User';
  try {
    const user = AdminDirectory.Users.get(
      userName.replace("users/", ""),
      { projection: 'BASIC', viewType: 'domain_public' });
    displayName = user.name.displayName ? user.name.displayName : user.name.fullName;
  } catch (e) {
    // Ignore error if the API call fails (for example, because it's an
    // out-of-domain user or Chat app)) and just use 'Unknown User'.
  }
  userMap.set(userName, displayName);
  return displayName;
}
ChatSpaceCreator.gs

يتلقى بيانات النموذج التي يدخلها المستخدمون على صفحة الويب لتهيئة الحادث، ويستخدمها لإعداد مساحة Chat من خلال إنشائها وملؤها، ثم ينشر رسالة حول الحادث.

الاطّلاع على رمز ChatSpaceCreator.gs

apps-script/incident-response/ChatSpaceCreator.gs
/**
 * Creates a space in Google Chat with the provided title and members, and posts an
 * initial message to it.
 *
 * @param {Object} formData the data submitted by the user. It should contain the fields
 *                          title, description, and users.
 * @return {string} the resource name of the new space.
 */
function createChatSpace(formData) {
  const users = formData.users.trim().length > 0 ? formData.users.split(',') : [];
  const spaceName = setUpSpace_(formData.title, users);
  addAppToSpace_(spaceName);
  createMessage_(spaceName, formData.description);
  return spaceName;
}

/**
 * Creates a space in Google Chat with the provided display name and members.
 *
 * @return {string} the resource name of the new space.
 */
function setUpSpace_(displayName, users) {
  const memberships = users.map(email => ({
    member: {
      name: `users/${email}`,
      type: "HUMAN"
    }
  }));
  const request = {
    space: {
      displayName: displayName,
      spaceType: "SPACE",
      externalUserAllowed: true
    },
    memberships: memberships
  };
  // Call Chat API method spaces.setup
  const space = Chat.Spaces.setup(request);
  return space.name;
}

/**
 * Adds this Chat app to the space.
 *
 * @return {string} the resource name of the new membership.
 */
function addAppToSpace_(spaceName) {
  const request = {
    member: {
      name: "users/app",
      type: "BOT"
    }
  };
  // Call Chat API method spaces.members.create
  const membership = Chat.Spaces.Members.create(request, spaceName);
  return membership.name;
}

/**
 * Posts a text message to the space on behalf of the user.
 *
 * @return {string} the resource name of the new message.
 */
function createMessage_(spaceName, text) {
  const request = {
    text: text
  };
  // Call Chat API method spaces.messages.create
  const message = Chat.Spaces.Messages.create(request, spaceName);
  return message.name;
}
DocsApi.gs

يتم استدعاء واجهة برمجة تطبيقات "مستندات Google" لإنشاء مستند في "مستندات Google" في Google Drive الخاص بالمستخدم وكتابة ملخص لمعلومات الحادثة، تم إنشاؤها في VertexAiApi.gs، في المستند.

الاطّلاع على رمز DocsApi.gs

apps-script/incident-response/DocsApi.gs
/**
 * Creates a Doc in the user's Google Drive and writes a summary of the incident information to it.
 *
 * @param {string} title The title of the incident
 * @param {string} resolution Incident resolution described by the user
 * @param {string} chatHistory The whole Chat history be included in the document
 * @param {string} chatSummary A summary of the Chat conversation to be included in the document
 * @return {string} the URL of the created Doc
 */
function createDoc_(title, resolution, chatHistory, chatSummary) {
  let doc = DocumentApp.create(title);
  let body = doc.getBody();
  body.appendParagraph(`Post-Mortem: ${title}`).setHeading(DocumentApp.ParagraphHeading.TITLE);
  body.appendParagraph("Resolution").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(resolution);
  body.appendParagraph("Summary of the conversation").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(chatSummary);
  body.appendParagraph("Full Chat history").setHeading(DocumentApp.ParagraphHeading.HEADING1);
  body.appendParagraph(chatHistory);
  return doc.getUrl();
}
VertexAiApi.gs

تلخّص المحادثة في "مساحة Chat" باستخدام Vertex AI. تم نشر هذا الملخّص في وثيقة تم إنشاؤها بشكل خاص في DocsAPI.gs.

الاطّلاع على رمز VertexAiApi.gs

apps-script/incident-response/VertexAiApi.gs
/**
 * Summarizes a Chat conversation using the Vertex AI text prediction API.
 *
 * @param {string} chatHistory The Chat history that will be summarized.
 * @return {string} The content from the text prediction response.
 */
function summarizeChatHistory_(chatHistory) {
  const prompt =
    "Summarize the following conversation between Engineers resolving an incident"
      + " in a few sentences. Use only the information from the conversation.\n\n"
      + chatHistory;
  const request = {
    instances: [
      { prompt: prompt }
    ],
    parameters: {
      temperature: 0.2,
      maxOutputTokens: 256,
      topK: 40,
      topP: 0.95
    }
  }
  const fetchOptions = {
    method: 'POST',
    headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() },
    contentType: 'application/json',
    payload: JSON.stringify(request)
  }
  const response = UrlFetchApp.fetch(
    `https://${VERTEX_AI_LOCATION_ID}-aiplatform.googleapis.com/v1`
      + `/projects/${PROJECT_ID}/locations/${VERTEX_AI_LOCATION_ID}`
      + "/publishers/google/models/text-bison:predict",
    fetchOptions);
  const payload = JSON.parse(response.getContentText());
  return payload.predictions[0].content;
}
WebController.gs

يقدم الموقع الإلكتروني لتهيئة الحوادث.

الاطّلاع على رمز WebController.gs

apps-script/incident-response/WebController.gs
/**
 * Serves the web page from Index.html.
 */
function doGet() {
  return HtmlService
    .createTemplateFromFile('Index')
    .evaluate();
}

/**
 * Serves the web content from the specified filename.
 */
function include(filename) {
  return HtmlService
    .createHtmlOutputFromFile(filename)
    .getContent();
}

/**
 * Returns the email address of the user running the script.
 */
function getUserEmail() {
  return Session.getActiveUser().getEmail();
}
Index.html

رمز HTML الذي يشتمل على الموقع الإلكتروني لتهيئة الحوادث.

الاطّلاع على رمز Index.html

apps-script/incident-response/Index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
    <?!= include('Stylesheet'); ?>
  </head>
  <body>
    <div class="container">
      <div class="content">
        <h1>Incident Manager</h1>
        <form id="incident-form" onsubmit="handleFormSubmit(this)">
          <div id="form">
            <p>
              <label for="title">Incident title</label><br/>
              <input type="text" name="title" id="title" />
            </p>
            <p>
              <label for="users">Incident responders</label><br/>
              <small>
                Please enter a comma-separated list of email addresses of the users
                that should be added to the space.
                Do not include <?= getUserEmail() ?> as it will be added automatically.
              </small><br/>
              <input type="text" name="users" id="users" />
            </p>
            <p>
              <label for="description">Initial message</label></br>
              <small>This message will be posted after the space is created.</small><br/>
              <textarea name="description" id="description"></textarea>
            </p>
            <p class="text-center">
              <input type="submit" value="CREATE CHAT SPACE" />
            </p>
          </div>
          <div id="output" class="hidden"></div>
          <div id="clear" class="hidden">
            <input type="reset" value="CREATE ANOTHER INCIDENT" onclick="onReset()" />
          </div>
        </form>
      </div>
    </div>
    <?!= include('JavaScript'); ?>
  </body>
</html>
JavaScript.html

يعالج سلوك النموذج، بما في ذلك عمليات الإرسال والأخطاء والموافقات لموقع الويب لتهيئة الحوادث. يتم تضمينه في Index.html من خلال دالة include المخصّصة في WebController.gs.

الاطّلاع على رمز JavaScript.html

apps-script/incident-response/JavaScript.html
<script>
  var formDiv = document.getElementById('form');
  var outputDiv = document.getElementById('output');
  var clearDiv = document.getElementById('clear');

  function handleFormSubmit(formObject) {
    event.preventDefault();
    outputDiv.innerHTML = 'Please wait while we create the space...';
    hide(formDiv);
    show(outputDiv);
    google.script.run
      .withSuccessHandler(updateOutput)
      .withFailureHandler(onFailure)
      .createChatSpace(formObject);
  }

  function updateOutput(response) {
    var spaceId = response.replace('spaces/', '');
    outputDiv.innerHTML =
      '<p>Space created!</p><p><a href="https://mail.google.com/chat/#chat/space/'
        + spaceId
        + '" target="_blank">Open space</a></p>';
    show(outputDiv);
    show(clearDiv);
  }

  function onFailure(error) {
    outputDiv.innerHTML = 'ERROR: ' + error.message;
    outputDiv.classList.add('error');
    show(outputDiv);
    show(clearDiv);
  }

  function onReset() {
    outputDiv.innerHTML = '';
    outputDiv.classList.remove('error');
    show(formDiv);
    hide(outputDiv);
    hide(clearDiv);
  }

  function hide(element) {
    element.classList.add('hidden');
  }

  function show(element) {
    element.classList.remove('hidden');
  }
</script>
Stylesheet.html

خدمة مقارنة الأسعار (CSS) الخاصة بموقع الويب لتهيئة الحوادث ويتم تضمينه في Index.html من خلال دالة include المخصّصة في WebController.gs.

الاطّلاع على رمز Stylesheet.html

apps-script/incident-response/Stylesheet.html
<style>
  * {
    box-sizing: border-box;
  }
  body {
    font-family: Roboto, Arial, Helvetica, sans-serif;
  }
  div.container {
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
  }
  div.content {
    width: 80%;
    max-width: 1000px;
    padding: 1rem;
    border: 1px solid #999;
    border-radius: 0.25rem;
    box-shadow: 0 2px 2px 0 rgba(66, 66, 66, 0.08), 0 2px 4px 2px rgba(66, 66, 66, 0.16);
  }
  h1 {
    text-align: center;
    padding-bottom: 1rem;
    margin: 0 -1rem 1rem -1rem;
    border-bottom: 1px solid #999;
  }
 #output {
    text-align: center;
    min-height: 250px;
  }
  div#clear {
    text-align: center;
    padding-top: 1rem;
    margin: 1rem -1rem 0 -1rem;
    border-top: 1px solid #999;
  }
  input[type=text], textarea {
    width: 100%;
    padding: 1rem 0.5rem;
    margin: 0.5rem 0;
    border: 0;
    border-bottom: 1px solid #999;
    background-color: #f0f0f0;
  }
  textarea {
    height: 5rem;
  }
  small {
    color: #999;
  }
  input[type=submit], input[type=reset] {
    padding: 1rem;
    border: none;
    background-color: #6200ee;
    color: #fff;
    border-radius: 0.25rem;
    width: 25%;
  }
  .hidden {
    display: none;
  }
  .text-center {
    text-align: center;
  }
  .error {
    color: red;
  }
</style>

العثور على رقم المشروع ورقم تعريفه على Google Cloud

  1. في وحدة التحكّم في Google Cloud، انتقِل إلى مشروعك على Google Cloud.

    الانتقال إلى Google Cloud Console

  2. انقر على رمز الإعدادات والأدوات > إعدادات المشروع.

  3. دوِّن القيم في حقلَي رقم المشروع ورقم تعريف المشروع. يمكنك استخدامها في الأقسام التالية.

إنشاء مشروع "برمجة تطبيقات Google"

لإنشاء مشروع "برمجة تطبيقات Google" وربطه بمشروعك على السحابة الإلكترونية:

  1. انقر على الزر التالي لفتح مشروع "برمجة تطبيقات Google" بعنوان الاستجابة للحوادث باستخدام Google Chat.
    فتح المشروع
  2. انقر على نظرة عامة.
  3. في صفحة النظرة العامة، انقر على رمز إنشاء نسخة إنشاء نسخة.
  4. أدخِل اسمًا لنسختك من مشروع "برمجة تطبيقات Google":

    1. انقر على نسخة من "الاستجابة للحوادث" باستخدام Google Chat.

    2. في عنوان المشروع، اكتب Incident Management Chat app.

    3. انقر على إعادة تسمية.

  5. في نسختك من مشروع "برمجة تطبيقات Google"، انتقِل إلى ملف Consts.gs واستبدل YOUR_PROJECT_ID بمعرّف مشروعك على Google Cloud.

ضبط مشروع السحابة الإلكترونية لمشروع برمجة التطبيقات

  1. في مشروع "برمجة التطبيقات"، انقر على أيقونة إعدادات المشروع إعدادات المشروع.
  2. ضمن مشروع Google Cloud Platform (GCP)، انقر على تغيير المشروع.
  3. في رقم مشروع Google Cloud Platform، الصِق رقم مشروع مشروعك على Google Cloud.
  4. انقر على ضبط المشروع. تم ربط مشروع Google Cloud ومشروع "برمجة تطبيقات Google".

إنشاء عملية نشر لبرمجة التطبيقات

والآن بعد أن تم وضع الرموز البرمجية بالكامل، يمكنك نشر مشروع برمجة التطبيقات. يمكنك استخدام رقم تعريف النشر عند إعداد تطبيق Chat في Google Cloud.

  1. في "برمجة التطبيقات"، افتح مشروع تطبيق الاستجابة للحوادث.

    الانتقال إلى لغة "برمجة تطبيقات Google"

  2. انقر على نشر > نشر جديد.

  3. إذا لم يسبق اختيار الإضافة وتطبيق الويب، بجانب اختيار نوع، انقر على أنواع النشر أيقونة إعدادات المشروع واختَر إضافة وتطبيق ويب.

  4. في الوصف، أدخِل وصفًا لهذا الإصدار، مثل Complete version of incident management app.

  5. في التنفيذ باسم، اختَر وصول المستخدم إلى تطبيق الويب.

  6. في قسم من لديه إذن الوصول، اختَر أي مستخدم في مؤسستك على Workspace، حيث يكون "مؤسستك على Workspace" هو اسم مؤسستك على Google Workspace.

  7. انقر على نشر. تبلغ "برمجة التطبيقات" عن عملية النشر الناجحة وتقدّم رقم تعريف النشر وعنوان URL لصفحة الويب الخاصة بتهيئة الحادث.

  8. دوِّن عنوان URL لتطبيق الويب للانتقال إليه لاحقًا عند وقوع حادثة. انسخ رقم تعريف النشر. يمكنك استخدام هذا المعرّف أثناء إعداد تطبيق Chat في وحدة التحكّم في Google Cloud.

  9. انقر على تم.

ضبط تطبيق Chat في Google Cloud Console

يوضّح هذا القسم طريقة إعداد Google Chat API في وحدة تحكُّم Google Cloud باستخدام معلومات عن تطبيق Chat، بما في ذلك رقم تعريف عملية النشر الذي أنشأته للتو من مشروع "برمجة تطبيقات Google".

  1. في Google Cloud Console، انقر على القائمة > مزيد من المنتجات > Google Workspace > مكتبة المنتجات > Google Chat API > إدارة > الإعدادات.

    الانتقال إلى إعدادات Chat API

  2. في اسم التطبيق، اكتب Incident Management.

  3. في عنوان URL للصورة الرمزية، اكتب https://developers.google.com/chat/images/quickstart-app-avatar.png.

  4. في الوصف، اكتب Responds to incidents..

  5. انقر على زر التبديل تفعيل الميزات التفاعلية لتفعيل الميزة.

  6. ضمن الوظائف، اختَر تلقّي رسائل بين شخصَين والانضمام إلى المساحات والمحادثات الجماعية.

  7. ضمن إعدادات الربط، اختَر مشروع "برمجة تطبيقات Google".

  8. في رقم تعريف النشر، الصِق رقم تعريف نشر "برمجة تطبيقات Google" الذي نسخته سابقًا من عملية نشر مشروع "برمجة تطبيقات Google".

  9. سجِّل أمرًا شرطة مائلة يستخدمه تطبيق Chat الذي تم تنفيذه بالكامل:

    1. ضمن أوامر Slash، انقر على إضافة أمر شرطة مائلة.

    2. في حقل الاسم، اكتب /closeIncident.

    3. في معرّف الطلب، اكتب 1.

    4. في الوصف، اكتب Closes the incident being discussed in the space.

    5. انقر على فتح مربّع حوار.

    6. انقر على تم. تم تسجيل الأمر الشرطة المائلة وإدراجه.

  10. ضمن إذن الوصول، اختَر إتاحة تطبيق Chat هذا لمستخدمين محدَّدين ومجموعات محدَّدة في نطاق Workspace وأدخِل عنوان بريدك الإلكتروني.

  11. ضمن السجلات، اختَر تسجيل الأخطاء إلى التسجيل.

  12. انقر على حفظ. تظهر رسالة تم حفظ الإعداد، ما يعني أن التطبيق جاهز للاختبار.

اختبار تطبيق Chat

لاختبار تطبيق Chat المخصّص لإدارة الحوادث، ابدأ حادثة من صفحة الويب وتأكَّد من أنّ تطبيق Chat يعمل على النحو المتوقّع:

  1. انتقِل إلى عنوان URL لتطبيق الويب لنشر برمجة التطبيقات.

  2. عندما تطلب "برمجة التطبيقات" إذنًا بالوصول إلى بياناتك، انقر على مراجعة الأذونات، وسجِّل الدخول باستخدام حساب Google مناسب في نطاق Google Workspace، ثم انقر على السماح.

  3. يتم فتح صفحة الويب لتهيئة الحوادث. إدخال معلومات الاختبار:

    1. في عنوان الحادثة، اكتب The First Incident.
    2. اختياريًا، في قسم المستجيبون للحوادث، أدخِل عناوين البريد الإلكتروني لزملائك من جهات الاستجابة للحوادث. ويجب أن يكون هؤلاء المستخدمون لديهم حساب Google Chat في مؤسسة Google Workspace أو أنّه يتعذّر عليهم إنشاء مساحة. لا تُدخل عنوان بريدك الإلكتروني لأنه يتم تضمينه تلقائيًا.
    3. في الرسالة الأولية، اكتب Testing the incident management Chat app..
  4. انقر على إنشاء مساحة Chat. ستظهر رسالة creating space.

  5. بعد إنشاء المساحة، ستظهر رسالة Space created!. انقر على فتح المساحة، والتي تفتح المساحة في Chat في علامة تبويب جديدة.

  6. يمكنك اختياريًا إرسال الرسائل إليك وإلى المستجيبين الآخرين للحوادث في المساحة. يلخص التطبيق هذه الرسائل باستخدام Vertex AI ويشارك مستند جلسة مراجعة.

  7. لإنهاء الاستجابة للحادثة وبدء عملية الحلّ، اكتب /closeIncident في "مساحة Chat". يتم فتح مربع حوار إدارة الحوادث.

  8. في إغلاق الحادث، أدخِل وصفًا لحل الحادثة، مثل Test complete.

  9. انقر على إغلاق الحادث.

يسرد تطبيق "إدارة الحوادث" الرسائل في المساحة ويلخصها باستخدام Vertex AI، ويلصق الملخص في مستند ضمن "مستندات Google" ويشارك المستند في المساحة.

تَنظيم

لتجنّب دفع رسوم من حسابك على Google Cloud مقابل الموارد المستخدمة في هذا البرنامج التعليمي، ننصحك بحذف المشروع على Google Cloud.

  1. في Google Cloud Console، انتقِل إلى صفحة إدارة الموارد. انقر على القائمة > إدارة الهوية وإمكانية الوصول والمشرف > إدارة الموارد.

    الانتقال إلى "مدير الموارد"

  2. في قائمة المشاريع، اختَر المشروع الذي تريد حذفه، ثم انقر على حذف .
  3. في مربّع الحوار، اكتب معرّف المشروع، ثم انقر على إيقاف التشغيل لحذف المشروع.