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

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

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

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

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

إليك طريقة عمل تطبيق Chat لإدارة الحوادث:

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

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

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

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

الأهداف

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

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

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

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

توضّح البنية كيف يعالج تطبيق Google Chat المخصّص للاستجابة للحوادث حادثًا ما وحلّه.

  1. يبدأ المستخدم بلاغًا من موقع إلكتروني خارجي مستضاف على Apps Script.

  2. يرسل الموقع الإلكتروني طلب HTTP غير متزامن إلى تطبيق Google Chat، الذي تتم استضافته أيضًا على Apps Script.

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

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

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

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

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

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

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

    3. تنشئ خدمة DocumentApp في Apps Script مستندًا على "مستندات Google" وتضيف ملخّص Vertex AI إلى المستند.

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

إعداد البيئة

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

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

Google Cloud Console

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

    الانتقال إلى "إنشاء مشروع"

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

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

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

gcloud CLI

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

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

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

Google Cloud Console

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

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

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

gcloud CLI

  1. لعرض قائمة بحسابات الفوترة المتاحة، نفِّذ الأمر التالي:
    gcloud billing accounts list
  2. ربط حساب فوترة بمشروع على Google Cloud:
    gcloud billing projects link PROJECT_ID --billing-account=BILLING_ACCOUNT_ID

    غيِّر القيم في السلسلة على الشكل التالي:

    • PROJECT_ID هو معرّف المشروع الخاص بالمشروع على السحابة الإلكترونية الذي تريد تفعيل الفوترة فيه.
    • BILLING_ACCOUNT_ID هو معرّف حساب الفوترة الذي سيتم ربطه بمشروع Google Cloud.

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

Google Cloud Console

  1. في Google Cloud Console، فعِّل Google Chat API وGoogle Docs API وAdmin SDK API وVertex AI API.

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

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

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

gcloud CLI

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

    gcloud config set project PROJECT_ID

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

  2. فعِّل واجهة Google Chat API وواجهة Google Docs API وواجهة 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، انتقِل إلى "القائمة" > > العلامة التجارية.

    الانتقال إلى "الهوية البصرية للعلامة التجارية"

  2. إذا سبق لك إعداد ، يمكنك إعداد إعدادات "شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth" التالية في العلامة التجارية والجمهور والوصول إلى البيانات. إذا ظهرت لك الرسالة لم يتم الإعداد بعد، انقر على البدء:

    1. ضمن معلومات التطبيق، في اسم التطبيق، اكتب Incident Management.
    2. في البريد الإلكتروني المخصّص لدعم المستخدمين، اختَر عنوان بريدك الإلكتروني أو مجموعة Google المناسبة.
    3. انقر على التالي.
    4. ضمن الجمهور، اختَر داخلي. إذا لم تتمكّن من اختيار داخلي، اختَر خارجي.
    5. انقر على التالي.
    6. ضمن معلومات الاتصال، أدخِل عنوان بريد إلكتروني يمكنك تلقّي إشعارات فيه بشأن أي تغييرات تطرأ على مشروعك.
    7. انقر على التالي.
    8. ضمن إنهاء، راجِع سياسة بيانات المستخدمين في خدمات Google API، ثم انقر على أوافق على سياسة بيانات المستخدمين في خدمات Google API إذا كنت موافقًا عليها.
    9. انقر على متابعة.
    10. انقر على إنشاء.
    11. إذا اخترت خارجي لنوع المستخدم، أضِف مستخدمين تجريبيين:
      1. انقر على الجمهور.
      2. ضمن المستخدمون التجريبيون، انقر على إضافة مستخدمين.
      3. أدخِل عنوان بريدك الإلكتروني وأي مستخدمين آخرين معتمَدين للاختبار، ثم انقر على حفظ.
  3. انقر على الوصول إلى البيانات > إضافة نطاقات أو إزالتها. ستظهر لوحة تتضمّن قائمة بنطاقات كل واجهة برمجة تطبيقات فعّلتها في مشروعك على Google Cloud.

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

      • 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
    2. انقر على إضافة إلى الجدول.

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

    4. بعد اختيار النطاقات التي يتطلّبها تطبيقك، انقر على حفظ في صفحة الوصول إلى البيانات.

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

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

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

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

يمكنك اختياريًا الاطّلاع على المشروع بأكمله على GitHub.

عرض على GitHub

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

Consts.gs

تحدّد هذه السمة الثوابت التي تشير إليها ملفات الرموز البرمجية الأخرى، بما في ذلك رقم تعريف مشروع Cloud ومعرّف الموقع الجغرافي في 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. الحصول على أرقام تعريف المستخدمين باستخدام خدمة &quot;دليل&quot; في Admin SDK ضمن Apps Script

عرض رمز 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 Docs API لإنشاء مستند 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>

العثور على رقم تعريف مشروعك على السحابة الإلكترونية

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

    الانتقال إلى "وحدة تحكّم Google Cloud"

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

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

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

لإنشاء مشروع في &quot;برمجة تطبيقات Google&quot; وربطه بمشروعك على Cloud، اتّبِع الخطوات التالية:

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

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

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

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

  5. في نسختك من مشروع Apps Script، انتقِل إلى الملف Consts.gs واستبدِل YOUR_PROJECT_ID برقم تعريف مشروعك على Cloud.

ضبط مشروع Cloud لمشروع "برمجة التطبيقات"

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

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

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

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

    الانتقال إلى Apps Script

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

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

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

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

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

  7. انقر على نشر. تُبلغ Apps Script عن نجاح عملية النشر، وتوفّر رقم تعريف للنشر وعنوان URL لصفحة الويب الخاصة ببدء الحادث.

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

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

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

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

  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. ضمن إعدادات الاتصال، اختَر Apps Script.

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

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

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

    2. في حقل الاسم، اكتب Close incident.

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

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

    5. ضمن نوع الأمر، اختَر أمر يبدأ بشرطة مائلة.

    6. في اسم الأمر الذي يبدأ بشرطة مائلة، اكتب /closeIncident.

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

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

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

  11. ضمن السجلات، اختَر تسجيل الأخطاء في خدمة تسجيل البيانات.

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

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

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

  1. انتقِل إلى عنوان URL لتطبيق الويب الذي تم تفعيله في Apps Script.

  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 في مساحة الدردشة. سيظهر مربّع حوار لإدارة الحوادث.

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

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

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

تَنظيم

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

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

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

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