מענה לתקריות שימוש ב-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 עם פתרון האירוע שותף במרחב.
    איור 6. מסמך Google Docs לפתרון אירועים ששותף במרחב.
  • מסמך Google Docs עם סיכום שנוצר על ידי AI לפתרון האירוע.
    איור 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. שירות Apps Script Admin SDK מקבל מידע על חברי הצוות, כמו מזהה משתמש וכתובת אימייל.

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

  4. חברי הצוות דנים בתקרית במרחב ב-Chat.

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

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

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

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

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

הכנת הסביבה

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

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

מסוף Google Cloud

  1. במסוף Google Cloud, עוברים אל תפריט > IAM & Admin > Create a Project (יצירת פרויקט).

    כניסה לדף Create a Project

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

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

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

CLI של gcloud

באחת מסביבות הפיתוח הבאות, ניגשים אל Google Cloud CLI‏ (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. במסוף Google Cloud, נכנסים לדף Billing. לוחצים על תפריט > חיוב > הפרויקטים שלי.

    לדף 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 ולוחצים על הבא.

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

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

  1. במסוף Google Cloud, נכנסים לתפריט > > Branding.

    מעבר לדף 'מיתוג'

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

    1. בקטע App Information (פרטי האפליקציה), בשדה App name (שם האפליקציה), מקלידים Incident Management.
    2. בקטע User support email (כתובת אימייל לתמיכה במשתמשים), בוחרים את כתובת האימייל או קבוצת Google המתאימה.
    3. לוחצים על הבא.
    4. בקטע קהל, בוחרים באפשרות פנימי. אם אי אפשר לבחור באפשרות פנימי, בוחרים באפשרות חיצוני.
    5. לוחצים על הבא.
    6. בקטע פרטים ליצירת קשר, מזינים כתובת אימייל שאליה אפשר לשלוח התראות על שינויים בפרויקט.
    7. לוחצים על הבא.
    8. בקטע סיום, קוראים את המדיניות של Google בנושא נתוני משתמשים בשירותי API. אם אתם מסכימים, מסמנים את התיבה אני מסכים/ה למדיניות של Google בנושא נתוני משתמשים בשירותי API.
    9. לוחצים על המשך.
    10. לוחצים על יצירה.
    11. אם בחרתם באפשרות חיצוני לסוג המשתמש, מוסיפים משתמשי בדיקה:
      1. לוחצים על קהל.
      2. בקטע משתמשי בדיקה, לוחצים על הוספת משתמשים.
      3. מזינים את כתובת האימייל שלכם ושל משתמשים מורשים אחרים לבדיקה, ואז לוחצים על שמירה.
  3. לוחצים על גישה לנתונים > הוספה או הסרה של היקפי הרשאה. מופיעה חלונית עם רשימת היקפי ההרשאות של כל API שהפעלתם בפרויקט ב-Google Cloud.

    1. בקטע Manually add scopes (הוספת היקפי הרשאה באופן ידני), מדביקים את היקפי ההרשאה הבאים:

      • 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

בקטע הבא, מעתיקים ומעדכנים פרויקט שלם בסקריפט של Google Apps שמכיל את כל קוד האפליקציה הנדרש לאפליקציית 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. קבלת מזהי משתמשים באמצעות שירות Admin SDK Directory ב-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. לוחצים על סמל ההגדרות והכלים > הגדרות הפרויקט.

  3. שימו לב לערכים בשדות מספר הפרויקט ומזהה הפרויקט. משתמשים בהם בקטעים הבאים.

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

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

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

    1. לוחצים על עותק של Respond to incidents with Google Chat (תגובה לאירועים באמצעות Google Chat).

    2. בשדה שם הפרויקט, כותבים Incident Management Chat app.

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

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

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

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

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

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

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

    מעבר אל Apps Script

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

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

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

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

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

  7. לוחצים על פריסה. ‫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 > ספריית מוצרים > Google Chat API > ניהול > הגדרה.

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

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

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

    1. בקטע Slash commands, לוחצים על Add a slash command.

    2. בשדה Name, כותבים Close incident.

    3. בשדה Command ID (מזהה הפקודה), מקלידים 1.

    4. בקטע תיאור, מקלידים Closes the incident being discussed in the space.

    5. בקטע סוג הפקודה, בוחרים באפשרות פקודה דרך שורת הפקודות.

    6. בשדה Slash command name, כותבים /closeIncident.

    7. בוחרים באפשרות הקישור פותח תיבת דו-שיח.

    8. לוחצים על סיום. פקודת הסלאש רשומה ומופיעה ברשימה.

  10. בקטע Visibility (חשיפה), בוחרים באפשרות Make this Chat app available to specific people and groups in Your Workspace Domain (הפיכת אפליקציית הצ'אט הזו לזמינה לאנשים ולקבוצות ספציפיים בדומיין שלכם ב-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. כדי לסיים את הטיפול באירוע ולהתחיל בתהליך הפתרון, מקלידים /closeIncident בחדר הצ'אט. תיפתח תיבת דו-שיח של ניהול אירועים.

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

  9. לוחצים על סגירת האירוע.

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

הסרת המשאבים

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

  1. במסוף Google Cloud, עוברים לדף Manage resources. לוחצים על תפריט > IAM & Admin > Manage Resources.

    כניסה ל-Resource Manager

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