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

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

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

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

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

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

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

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

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

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

الأهداف

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

البنية

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

بنية تطبيق Google Chat المخصّص للاستجابة للحالات الأمنية

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

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

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

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

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

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

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

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

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

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

    3. تنشئ خدمة DocumentApp في Apps Script مستندًا في Google Docs وتضيف ملخص 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

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

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

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

Google Cloud Console

  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 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، انتقِل إلى القائمة > واجهات برمجة التطبيقات والخدمات > شاشة موافقة OAuth.

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

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

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

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

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

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

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

  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. يخفي الرمز السفلي الوظيفة من صفحة الويب لبدء تشغيل الحادثة عند فتحها في متصفّح. لمزيد من المعلومات، يُرجى الاطّلاع على الدوالّ الخاصة.

تتوافق خدمة Apps Script مع نوعَي ملفَين، وهما .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. تحصل على أرقام تعريف المستخدمين باستخدام خدمة "دليل 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" لإنشاء مستند في "مستندات 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>

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

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

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

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

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

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

لإنشاء مشروع على Apps Script وربطه بمشروعك على Cloud:

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

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

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

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

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

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

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

إنشاء عملية نشر في Apps Script

بعد أن تم وضع كل الرمز البرمجي، يمكنك نشر project (مشروع) 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، انقر على القائمة > المزيد من المنتجات > 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. في رقم تعريف عملية النشر، الصِق رقم تعريف عملية نشر Apps Script الذي نسخته سابقًا من عملية نشر مشروع Apps Script.

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

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

    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 لتطبيق الويب الذي تم تفعيل برمجة Apps Script فيه.

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

  3. يتم فتح صفحة الويب لبدء الحادث. أدخِل معلومات الاختبار:

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

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

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

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

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

  9. انقر على إغلاق المشكلة.

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

تَنظيم

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

  1. في وحدة تحكُّم Google Cloud، انتقِل إلى صفحة إدارة الموارد. انقر على القائمة &gt; إدارة الهوية وإمكانية الوصول والمشرف &gt; إدارة الموارد.

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

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