الاستجابة للحوادث باستخدام Google Chat وVertex AI وApps Script ومصادقة المستخدم

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

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

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

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

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

  • الموقع الإلكتروني الذي يبدأ حادثًا.
    الشكل 1. تمثّل هذه السمة الموقع الإلكتروني الذي يمكن للمستخدم الإبلاغ فيه عن حادثة.
  • إشعار بأنّه تم إنشاء مساحة Chat للحادثة
    الشكل 2. إشعار بأنّه تم إنشاء مساحة Chat للحادثة
  • مساحة Chat للاستجابة للحوادث
    الشكل 3. مساحة Chat المخصّصة للاستجابة للحوادث
  • حلّ المشكلة باستخدام أمر سريع
    الشكل 4. حلّ المشكلة باستخدام أمر سريع
  • مربّع حوار حلّ المشكلة
    الشكل 5. مربّع حوار حلّ الحادث
  • مستند Google Docs لحلّ المشكلة تمت مشاركته في المساحة
    الشكل 6. تمت مشاركة مستند Google Docs الخاص بحلّ المشكلة في المساحة.
  • مستند 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 من خلال خدمة Chat المتقدّمة في "برمجة تطبيقات Google"، ينشئ تطبيق 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: لتفعيل وحدة طرفية على الإنترنت مع إعداد واجهة سطر الأوامر gcloud، فعِّل Cloud Shell.
    تفعيل 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، انتقِل إلى "القائمة" > Google Auth platform > العلامة التجارية.

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

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

    1. ضمن معلومات التطبيق، في اسم التطبيق، اكتب Incident Management with User Auth.
    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، لذا لن تحتاج إلى نسخ كل ملف ولصقه.

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

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

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

عرض على GitHub

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

Consts.gs

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

عرض رمز Consts.gs

apps-script/chat/incident-response-user-auth/Consts.gs
const PROJECT_ID = 'replace-with-your-project-id';
const VERTEX_AI_LOCATION_ID = 'us-central1';
const CLOSE_INCIDENT_COMMAND_ID = 1;
const MODEL_ID = 'gemini-2.5-flash-lite';
ChatApp.gs

يتعامل مع أحداث التفاعل في "محادثة Google"، بما في ذلك الرسائل والنقرات على الأزرار وأوامر التطبيق ومربّعات الحوار. يستجيب للأمر السريع Close incident من خلال فتح مربّع حوار لجمع تفاصيل حلّ المشكلة. يقرأ الرسائل في المساحة من خلال استدعاء الطريقة spaces.messages.list في Chat API. الحصول على أرقام تعريف المستخدمين باستخدام خدمة &quot;دليل&quot; في Admin SDK ضمن Apps Script

عرض رمز ChatApp.gs

apps-script/chat/incident-response-user-auth/ChatApp.gs
/**
 * Responds to a MESSAGE event in Google Chat.
 * 
 * It always responds with a simple "Hello" text message.
 *
 * @param {Object} event the event object from Google Chat
 */
function onMessage(event) {
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "Hello from Incident Response app!"
  }}}}};
}

/**
 * Responds to an APP_COMMAND event in Google Chat.
 *
 * @param {Object} event the event object from Google Chat
 */
function onAppCommand(event) {
  if (event.chat.appCommandPayload.appCommandMetadata.appCommandId != CLOSE_INCIDENT_COMMAND_ID) {
    return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
      text: "Command not recognized. Use the quick command `Close incident` to close the incident managed by this space."
    }}}}};
  }
  return { action: { navigations: [{ pushCard: { 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" }}
      }]}
    }]
  }]}}]}};
}

/**
 * Responds to a BUTTON_CLICKED event in Google Chat from Close Incident dialog.
 *
 * @param {Object} event the event object from Google Chat
 */
function closeIncident(event) {
  if (event.chat.buttonClickedPayload.isDialogEvent) {
    if (event.chat.buttonClickedPayload.dialogEventType == 'SUBMIT_DIALOG') {
      return processSubmitDialog_(event);
    }
    return { action: { navigations: [{ endNavigation: {
      action: "CLOSE_DIALOG" }
    }]}};
  }
}

/**
 * Responds to a BUTTON_CLICKED event in Google Chat from Close Incident dialog submission.
 *
 * 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.commonEventObject.formInputs.description.stringInputs.value[0];
  const space = event.chat.buttonClickedPayload.space;
  const chatHistory = concatenateAllSpaceMessages_(space.name);
  const chatSummary = summarizeChatHistory_(chatHistory);
  const docUrl = createDoc_(space.displayName, resolution, chatHistory, chatSummary);
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { 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.
 *
 * @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
    .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/chat/incident-response-user-auth/ChatSpaceCreator.gs
/**
 * Handles an incident by creating a chat space with the provided title and members, and posting a message.
 * All the actions are done using user credentials.
 *
 * @param {Object} formData - The data submitted by the user. It should contain the fields:
 *                           - title: The display name of the chat space.
 *                           - description: The description of the incident.
 *                           - users: A comma-separated string of user emails to be added to the space.
 * @return {string} The resource name of the new space.
 */
function handleIncident(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 chat space.
 *
 * @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"
    },
    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;
}

/**
 * Creates a chat message.
 *
 * @param {string} spaceName - The resource name of the space.
 * @param {string} message - The text to be posted.
 * @return {string} the resource name of the new message.
 */
function createMessage_(spaceName, message) {
  const request = {
    text: message
  };
  // Call Chat API method spaces.messages.create
  const result = Chat.Spaces.Messages.create(request, spaceName);
  return result.name;
}
DocsApi.gs

يتم استدعاء Google Docs API لإنشاء مستند Google في Google Drive الخاص بالمستخدم، ويتم كتابة ملخّص لمعلومات الحدث التي تم إنشاؤها في VertexAiApi.gs في المستند.

عرض رمز DocsApi.gs

apps-script/chat/incident-response-user-auth/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/chat/incident-response-user-auth/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 API_ENDPOINT = `https://${VERTEX_AI_LOCATION_ID}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${VERTEX_AI_LOCATION_ID}/publishers/google/models/${MODEL_ID}:generateContent`;
  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;
  // Get the access token.
  const accessToken = ScriptApp.getOAuthToken();

  const headers = {
    'Authorization': 'Bearer ' + accessToken,
    'Content-Type': 'application/json',
  };
  const payload = {
    'contents': {
      'role': 'user',
      'parts' : [
        {
          'text': prompt
        }
      ]
    }
  }
  const options = {
    'method': 'post',
    'headers': headers,
    'payload': JSON.stringify(payload),
    'muteHttpExceptions': true,
  };
  try {
    const response = UrlFetchApp.fetch(API_ENDPOINT, options);
    const responseCode = response.getResponseCode();
    const responseText = response.getContentText();

    if (responseCode === 200) {
      const jsonResponse = JSON.parse(responseText);
      console.log(jsonResponse)
      if (jsonResponse.candidates && jsonResponse.candidates.length > 0) {
        return jsonResponse.candidates[0].content.parts[0].text; // Access the summarized text
      } else {
        return "No summary found in response.";
      }

    } else {
      console.error("Vertex AI API Error:", responseCode, responseText);
      return `Error: ${responseCode} - ${responseText}`;
    }
  } catch (e) {
    console.error("UrlFetchApp Error:", e);
    return "Error: " + e.toString();
  }
}
WebController.gs

يعرض الموقع الإلكتروني الخاص بإعداد الحوادث.

عرض رمز WebController.gs

apps-script/chat/incident-response-user-auth/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/chat/incident-response-user-auth/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/chat/incident-response-user-auth/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)
      .handleIncident(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/chat/incident-response-user-auth/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، انتقِل إلى مشروعك على Cloud.

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

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

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

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

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

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

    1. انقر على نسخة من تطبيق Incident Management Chat مع مصادقة المستخدم.

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

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

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

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

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

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

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

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

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

  2. انقر على نشر > اختبار عمليات النشر.

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

  4. توفّر خدمة Apps Script رقم تعريف وعنوان URL لعملية النشر الخاصة بتطبيق الويب.

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

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

ضبط تطبيق 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 with User Auth.

  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. في معرّف الأمر، اكتب 1.

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

    4. ضمن نوع الأمر، اختَر أمر سريع.

    5. في حقل اسم الأمر السريع، اكتب Close incident.

    6. انقر على مربع الحوار.

    7. انقر على تم. يتم تسجيل الأمر وإدراجه.

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

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

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

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

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

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

  2. عندما تطلب Apps Script الإذن بالوصول إلى بياناتك، انقر على مراجعة الأذونات، وسجِّل الدخول باستخدام حساب 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. لإنهاء الاستجابة للحوادث وبدء عملية الحل، شغِّل الأمر السريع Close incident في مساحة الدردشة. يتم فتح مربّع حوار لإدارة الحوادث.

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

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

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

تَنظيم

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

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

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

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