מענה לתקריות שימוש ב-Google Chat, ב-Vertex AI וב-Apps Script

במדריך הזה תלמדו איך ליצור אפליקציית Google Chat מגיבים לאירועים בזמן אמת. כשמגיבים לתקרית, האפליקציה יוצרת ומאכלסת מרחב משותף ב-Chat, מאפשרת לטפל בתקרית באמצעות הודעות, פקודות קו נטוי ודיאלוגים, ומשתמשת ב-AI כדי לסכם את התגובה לתקרית במסמך ב-Google Docs.

אירוע הוא אירוע שמחייב טיפול מיידי של צוות. של אנשים לפתור. דוגמאות לאירועים:

  • בקשת תמיכה תלוית זמן נוצרת במערכת לניהול קשרי לקוחות (CRM) כך שצוות השירות צריך לשתף פעולה כדי להגיע לפתרון.
  • מערכת עוברת למצב אופליין ומתריעה לקבוצה של מהנדסי Site Reliability (SRE) כדי שיוכלו לפעול יחד כדי להחזיר אותו לאינטרנט.
  • מתרחשת רעידת אדמה בעוצמה גבוהה, ועובדי החירום צריכים לתאם את התגובה שלהם.

למטרות המדריך הזה, ההתראה על אירוע מתחילה כשמישהו מדווח על התקרית בלחיצה על לחצן מדף אינטרנט. בדף האינטרנט מתבצעת סימולציה של אירוע, והמשתמשים מתבקשים להזין מידע בסיסי על האירוע: שם, תיאור וכתובות האימייל של צוות התגובה.

רוצה לראות את אפליקציית Chat לניהול אירועים?

  • האתר שבו מתחיל האירוע.
    איור 1. האתר שבו אפשר לדווח על אירוע.
  • התראה על יצירת המרחב המשותף ב-Chat של התקרית.
    איור 2. הודעה על יצירת המרחב המשותף ב-Chat של התקרית.
  • המרחב ב-Chat של התגובה לאירוע.
    איור 3. המרחב ב-Chat של התגובה לאירוע.
  • פתרון התקרית באמצעות פקודה של שורת הפקודה.
    איור 4. פתרון התקרית באמצעות פקודה של שורת הפקודה.
  • תיבת דו-שיח לפתרון האירוע.
    איור 5. תיבת הדו-שיח של פתרון אירוע.
  • מסמך Google Docs של Google Docs משותף במרחב המשותף.
    איור 6. מסמך Google Docs של Google Docs משותף במרחב.
  • סיכום האירוע שנוצר על ידי ה-AI במסמך Google Docs.
    איור 7. מסמך Google Docs עם סיכום האירוע ותוצאת הטיפול באמצעות AI.

דרישות מוקדמות

אם אתם צריכים להפעיל בארגון אחת מהדרישות המוקדמות האלה, תוכלו לבקש מהאדמין ב-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. משתמש מתחיל אירוע מאתר חיצוני שמתארח ב- Apps Script.

  2. האתר שולח בקשת HTTP אסינכרונית אל אפליקציית Google Chat, גם מתארחת ב-Apps Script.

  3. אפליקציית Google Chat לתגובה לתקריות מעבדת את הבקשה:

    1. שירות Admin SDK של Apps Script מקבל מידע על חברי הצוות, כמו מזהה משתמש וכתובת אימייל.

    2. באמצעות קבוצה של בקשות HTTP ל-Chat API באמצעות השירות Advanced Chat של Apps Script, אפליקציית Google Chat לטיפול בתקריות יוצרת מרחב Chat לתקרית, מאכלסת אותו עם חברי הצוות ושולחת הודעה למרחב.

  4. חברי הצוות מדברים על התקרית במרחב המשותף ב-Chat.

  5. חבר צוות מפעיל פקודת לוכסן כדי לסמן שיש פתרון נוסף לתקרית.

    1. קריאה ל-HTTP ל-Chat API באמצעות השירות המתקדם של Apps Script ל-Chat מציגה את כל ההודעות במרחב המשותף ב-Chat.

    2. Vertex AI מקבל את ההודעות שברשימה ויוצר סיכום.

    3. שירות Apps Script DocumentApp יוצר ב-Docs ומוסיף את הסיכום של Vertex AI מהמסמך.

    4. התגובות לשיחות באפליקציית Google Chat Chat API לשליחת הודעה עם קישור לסיכום ב-Docs.

מכינים את הסביבה

בקטע הזה נסביר איך ליצור ולהגדיר פרויקט ב-Google Cloud עבור אפליקציית Chat.

יצירת פרויקט של Google Cloud

מסוף Google Cloud

  1. במסוף Google Cloud, נכנסים לתפריט > IAM & אדמין > יצירת פרויקט.

    כניסה לדף Create a Project

  2. בשדה Project Name, מזינים שם תיאורי לפרויקט.

    אופציונלי: כדי לערוך את Project ID, לוחצים על Edit. אי אפשר לשנות את מזהה הפרויקט אחרי היצירה שלו, לכן חשוב לבחור מזהה שיעמוד בצרכים שלכם לכל משך חיי הפרויקט.

  3. בשדה מיקום לוחצים על עיון כדי להציג את המיקומים האפשריים של פרויקט. לאחר מכן לוחצים על בחירה.
  4. לוחצים על יצירה. במסוף Google Cloud עוברים לדף Dashboard ונוצר הפרויקט תוך כמה דקות.

CLI של gcloud

ניגשים ל-CLI של Google Cloud (gcloud) באחת מסביבות הפיתוח הבאות:

  • Cloud Shell: כדי להשתמש בטרמינל אונליין שבו כבר מוגדר ה-CLI של gcloud, צריך להפעיל את Cloud Shell.
    הפעלת Cloud Shell
  • מעטפת מקומית: כדי להשתמש בסביבת פיתוח מקומית צריך להתקין ולהפעיל את ה-CLI של gcloud.
    כדי ליצור פרויקט ב-Cloud, משתמשים בפקודה gcloud projects create:
    gcloud projects create PROJECT_ID
    מחליפים את PROJECT_ID על ידי הגדרת המזהה של הפרויקט שרוצים ליצור.

הפעלת החיוב בפרויקט ב-Cloud

מסוף Google Cloud

  1. נכנסים לקטע Billing במסוף Google Cloud. לוחצים על תפריט > חיוב > הפרויקטים שלי.

    כניסה לדף Billing for My Projects

  2. בקטע Select an organization, בוחרים את הארגון שמשויך לפרויקט ב-Google Cloud.
  3. בשורת הפרויקט, פותחים את התפריט Actions (), לוחצים על Change billing ובוחרים את החשבון לחיוב ב-Cloud.
  4. לוחצים על Set account.

CLI של gcloud

  1. כדי להציג רשימה של החשבונות הזמינים לחיוב, מריצים את הפקודה:
    gcloud billing accounts list
  2. מקשרים חשבון לחיוב לפרויקט ב-Google Cloud:
    gcloud billing projects link PROJECT_ID --billing-account=BILLING_ACCOUNT_ID

    מחליפים את מה שכתוב בשדות הבאים:

    • PROJECT_ID הוא מזהה הפרויקט של הפרויקט ב-Cloud שרוצים להפעיל בו חיוב.
    • BILLING_ACCOUNT_ID הוא מזהה החשבון לחיוב שאליו יש לקשר בפרויקט ב-Google Cloud.

הפעלת ממשקי ה-API

מסוף Google Cloud

  1. במסוף Google Cloud, מפעילים את Google Chat API, את Google Docs API, Admin SDK API ו-Vertex AI API.

    הפעלת ממשקי ה-API

  2. עליכם לוודא שאתם מפעילים את ממשקי ה-API פרויקט ב-Cloud ולוחצים על Next.

  3. מוודאים שאתם מפעילים את ממשקי ה-API הנכונים ולוחצים על Enable.

CLI של gcloud

  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 לעיבוד התגובה לאירוע.

במדריך הזה תפרסמו את האפליקציה באופן פנימי, כך שאפשר להשתמש במידע של placeholder. לפני פרסום האפליקציה באופן חיצוני, צריך להחליף את המידע של התוויות למידע אמיתי במסך ההסכמה.

  1. במסוף Google Cloud, נכנסים אל תפריט > APIs & Services> OAuth consent screen.

    מעבר למסך ההסכמה של OAuth

  2. בקטע סוג משתמש, בוחרים באפשרות פנימי ולוחצים על יצירה.

  3. בשדה App name, מקלידים Incident Management.

  4. בקטע User support email, בוחרים את כתובת האימייל שלכם או קבוצת Google מתאימה.

  5. בקטע פרטים ליצירת קשר עם המפתח, מזינים את כתובת האימייל שלכם.

  6. לוחצים על שמירה והמשך.

  7. לוחצים על הוספה או הסרה של היקפים. תופיע חלונית עם רשימה של היקפים לכל API שהפעלתם בפרויקט ב-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

בקטע הבא מעתיקים ומעדכנים חשבון שלם פרויקט Apps Script שמכיל את כל האפליקציות הנדרשות לאפליקציה ל-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, כולל הודעות, קליקים על כרטיסים, פקודות קו נטוי (slash) ודיאלוגים. התגובה לפקודת ה-slash‏ /closeIncident היא פתיחת תיבת דו-שיח כדי לאסוף פרטים לגבי פתרון התקרית. קריאת ההודעות במרחב באמצעות קריאה לשיטה spaces.messages.list ב-Chat API. הצגת מזהי משתמשים באמצעות שירות הספרייה של 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 Docs ב-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. לוחצים על 'הגדרות ותוכניות שירות'. &gt; הגדרות הפרויקט.

  3. שימו לב לערכים בשדות Project number ו-Project ID. תוכלו להשתמש בהם בקטעים הבאים.

יצירת פרויקט Apps Script

כדי ליצור פרויקט ב-Apps Script ולחבר אותו אל פרויקט ב-Cloud:

  1. לוחצים על הלחצן הבא כדי לפתוח את פרויקט Apps Script‏ מענה על אירועים באמצעות Google Chat.
    פתיחת הפרויקט
  2. לוחצים על סקירה כללית.
  3. בדף הסקירה הכללית לוחצים על הסמל של יצירת עותק יצירת עותק.
  4. נותנים שם להעתקה של פרויקט Apps Script:

    1. לוחצים על עותק של 'מענה לתקריות באמצעות Google Chat'.

    2. בשדה Project title, כותבים Incident Management Chat app.

    3. לוחצים על Rename.

  5. עוברים לקובץ Consts.gs בעותק של הפרויקט ב-Apps Script ומחליפים את YOUR_PROJECT_ID במזהה של הפרויקט ב-Cloud.

הגדרת פרויקט Cloud של פרויקט Apps Script

  1. בפרויקט Apps Script, לוחצים על הסמל של הגדרות הפרויקט Project Settings (הגדרות הפרויקט).
  2. בקטע פרויקט ב-Google Cloud Platform (GCP), לוחצים על שינוי פרויקט.
  3. בקטע מספר הפרויקט ב-GCP, מדביקים את מספר הפרויקט ב-Cloud.
  4. לוחצים על Set project. הפרויקט ב-Cloud ו-Apps Script הפרויקטים מחוברים עכשיו.

יצירת פריסה של Apps Script

עכשיו, אחרי שכל הקוד מוכן, פורסים את הפרויקט ב-Apps Script. משתמשים במזהה הפריסה כשמגדירים את של אפליקציית Chat ב-Google Cloud.

  1. ב-Apps Script, פותחים את הפרויקט של אפליקציית התגובה לתקרית.

    כניסה לדף Apps Script

  2. לוחצים על פריסה > פריסה חדשה.

  3. אם האפשרויות Add-on ו-Web app עדיין לא מסומנות, לוחצים על סוגים של פריסה הסמל של הגדרות הפרויקט לצד Select type ובוחרים באפשרויות Add-on ו-Web app.

  4. בשדה Description, מזינים תיאור של הגרסה הזו, למשל Complete version of incident management app.

  5. בקטע Execute as, בוחרים באפשרות User accessing the web app.

  6. בקטע למי יש גישה, בוחרים באפשרות כל אחד בארגון ב-Workspace. שבו 'הארגון ב-Workspace' הוא השם של ארגון ב-Google Workspace.

  7. לוחצים על Deploy (פריסה). הדוחות של Apps Script בוצעו בהצלחה של האירוע, ומספק את מזהה הפריסה וכתובת ה-URL של האירוע דף האינטרנט לאתחול.

  8. שימו לב לכתובת ה-URL של אפליקציית האינטרנט כדי להיכנס אליה מאוחר יותר כשתפתחו אירוע. מעתיקים את מזהה הפריסה. משתמשים במזהה הזה כשמגדירים את אפליקציית Chat במסוף Google Cloud.

  9. לוחצים על סיום.

איך מגדירים את אפליקציית Chat במסוף Google Cloud

בקטע הזה נסביר איך להגדיר את Google Chat API במסוף Google Cloud עם מידע על אפליקציית Chat, כולל מזהה הפריסה שיצרתם זה עתה מהפרויקט ב-Apps Script.

  1. במסוף Google Cloud, לוחצים על תפריט > מוצרים נוספים > Google Workspace > Product Library > Google Chat API > Manage > Configuration.

    כניסה להגדרת Chat API

  2. בשדה App name, מקלידים Incident Management.

  3. בשדה כתובת URL של הדמות, מקלידים https://developers.google.com/chat/images/quickstart-app-avatar.png.

  4. בקטע תיאור, מקלידים Responds to incidents..

  5. מעבירים את המתג הפעלת תכונות אינטראקטיביות למצב פעיל.

  6. בקטע פונקציונליות, בוחרים באפשרות קבלת הודעות אישיות והצטרפות למרחבים משותפים ולשיחות קבוצתיות.

  7. בקטע Connection settings (הגדרות חיבור), בוחרים באפשרות Apps Script (סקריפט של Apps).

  8. בשדה Deployment ID, מדביקים את מזהה הפריסה של Apps Script שהועתק קודם מהפריסה של פרויקט Apps Script.

  9. רושמים פקודת של קו נטוי אפליקציית Chat שהוטמעה במלואה כוללת:

    1. בקטע פקודות דרך שורת הפקודות, לוחצים על הוספת פקודה דרך שורת הפקודות.

    2. בשדה Name, מקלידים /closeIncident.

    3. בשדה Command ID, מקלידים 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. כאשר Apps Script מבקש הרשאה לגשת לנתונים שלכם, לוחצים על בדיקת הרשאות ונכנסים באמצעות חשבון Google מתאים. בדומיין Google Workspace, ולוחצים על אישור.

  3. דף האינטרנט של הפעלת התקרית ייפתח. מזינים את פרטי הבדיקה:

    1. בשדה Incident title, מקלידים The First Incident.
    2. אם רוצים, אפשר להזין את כתובות האימייל של שאר המשתתפים בתקרית בשדה Incident responders. הם צריכים להיות משתמשים עם חשבון Google Chat בארגון שלכם ב-Google Workspace, אחרת לא תוכלו ליצור את המרחב המשותף. אל תזין את כתובת האימייל שלך, כי נכללים אוטומטית.
    3. בהודעה הראשונית, צריך להקליד Testing the incident management Chat app.
  4. לוחצים על יצירת מרחב משותף. תופיע ההודעה creating space.

  5. אחרי יצירת המרחב המשותף, תופיע ההודעה Space created!. לוחצים על פתיחת מרחב. המרחב המשותף ב-Chat ייפתח בכרטיסייה חדשה.

  6. אופציונלי: אתם ושאר המגיבים לאירוע תוכלו לשלוח הודעות המרחב המשותף. האפליקציה מסכם את ההודעות האלה באמצעות Vertex AI ומשתפת מסמך רטרוספקטיבי.

  7. כדי לסיים את התגובה לאירוע ולהתחיל בתהליך הפתרון, מרחב ב-Chat, מסוג /closeIncident. תיפתח תיבת דו-שיח לניהול אירועים.

  8. בקטע Close incident, מזינים תיאור של פתרון התקרית, למשל Test complete.

  9. לוחצים על Close Incident.

באפליקציית Incident Management מופיעות ההודעות במרחב המשותף, הן מסוכמות באמצעות Vertex AI, המערכת מדביקה את הסיכום במסמך ב-Google Docs ומשתפת את המסמך במרחב המשותף.

הסרת המשאבים

כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, מומלץ למחוק את הפרויקט ב-Cloud.

  1. במסוף Google Cloud, עוברים לדף Manage resources. לוחצים על תפריט &gt; IAM & Admin (אדמין) &gt; לניהול משאבים

    כניסה ל-Resource Manager

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete .
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.