פיתוח בוט של Slack באמצעות Node.js ב-Cloud Run

1. סקירה כללית

5f529fb87abc11c9.png

ב-Codelab הזה תלמדו איך ליצור Slack bot באמצעות ערכת הכלים Botkit ולהריץ אותו ב-Google Cloud. תהיה לך אפשרות לנהל אינטראקציה עם הבוט בערוץ Slack בשידור חי.

מה תלמדו

  • איך יוצרים שילוב מותאם אישית של בוט ב-Slack
  • איך מאבטחים את הסודות ב-Slack באמצעות Secret Manager
  • איך פורסים בוט של Slack ב-Cloud Run, פלטפורמת מחשוב מנוהלת שמותאמת באופן אוטומטי לקונטיינרים ללא שמירת מצב.

מה נדרש

  • פרויקט ב-Google Cloud
  • דפדפן כמו Chrome או Firefox

איך תשתמשו במדריך הזה?

לקריאה בלבד לקרוא אותו ולבצע את התרגילים

איזה דירוג מגיע לדעתך לחוויה שלך ב-Google Cloud?

מתחילים בינונית בקיאים

2. הגדרה ודרישות

הגדרת סביבה בקצב עצמאי

  1. נכנסים למסוף Google Cloud ויוצרים פרויקט חדש או עושים שימוש חוזר בפרויקט קיים. אם אין לכם עדיין חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון.

98e4187c97cf2e0e.png

37d264871000675d.png

c20a9642aaa18d11.png

  • Project name הוא השם המוצג של המשתתפים בפרויקט. זו מחרוזת תווים שלא משמשת את Google APIs. תמיד אפשר לעדכן.
  • Project ID הוא ייחודי בכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו (אי אפשר לשנות אותו אחרי שמגדירים אותו). מסוף Cloud יוצר מחרוזת ייחודית באופן אוטומטי; בדרך כלל לא מעניין אותך מה זה. ברוב ה-codelabs תצטרכו להפנות למזהה הפרויקט שלכם (בדרך כלל מזוהה כ-PROJECT_ID). אם המזהה שנוצר לא מוצא חן בעיניכם, אתם יכולים ליצור מזהה אקראי אחר. לחלופין, אפשר לנסות שם משלך ולראות אם הוא זמין. לא ניתן לשנות אותו אחרי השלב הזה, והוא נשאר למשך הפרויקט.
  • לידיעתך, יש ערך שלישי, Project Number, שבו משתמשים בחלק מממשקי ה-API. מידע נוסף על כל שלושת הערכים האלה זמין במסמכי התיעוד.
  1. בשלב הבא צריך להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים או בממשקי API של Cloud. מעבר ב-Codelab הזה לא יעלה הרבה כסף, אם בכלל. כדי להשבית משאבים ולא לצבור חיובים מעבר למדריך הזה, אתם יכולים למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים להשתתף בתוכנית תקופת ניסיון בחינם בשווי 1,200 ש"ח.

הפעלת Cloud Shell

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

הפעלת Cloud Shell

  1. במסוף Cloud, לוחצים על Activate Cloud Shell d1264ca30785e435.png.

84688aa223b1c3a2.png

אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים שמתוארת בו. אם הוצג לכם מסך ביניים, לוחצים על המשך.

d95252b003979716.png

ההקצאה וההתחברות ל-Cloud Shell נמשכת כמה דקות.

7833d5e1c5d18f54.png

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

אחרי ההתחברות ל-Cloud Shell, אתם אמורים לראות שהפרויקט מאומת ושהפרויקט מוגדר לפי מזהה הפרויקט שלכם.

  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהאימות בוצע:
gcloud auth list

פלט הפקודה

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהפקודה ב-gcloud יודעת על הפרויקט שלכם:
gcloud config list project

פלט הפקודה

[core]
project = <PROJECT_ID>

אם הוא לא משויך, תוכלו להגדיר אותו באמצעות הפקודה הבאה:

gcloud config set project <PROJECT_ID>

פלט הפקודה

Updated property [core/project].

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

מ-Cloud Shell, מפעילים את ממשקי ה-API של Artifact Registry, Cloud Build, Cloud Run ו-Secret Manager:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  run.googleapis.com \
  secretmanager.googleapis.com

בעקבות זאת תופיע הודעת הצלחה שדומה להודעה הבאה:

Operation "operations/..." finished successfully.

עכשיו אתם מוכנים להכין את האפליקציה ולפרוס אותה...

4. יצירת סביבת עבודה ב-Slack

אתם צריכים סביבת עבודה ב-Slack שבה תוכלו ליצור שילובים בהתאמה אישית. אם אין לכם עדיין סביבת עבודה שאתם רוצים להשתמש בה במדריך הזה, תוכלו ליצור סביבת עבודה בחינם.

aa1f0fda82263bf8.png

5. יצירת משתמש בבוט ב-Slack

משתמשים בבוט יכולים להאזין להודעות ב-Slack, לפרסם הודעות ולהעלות קבצים. ב-Codelab הזה תיצרו בוט כדי לפרסם הודעת ברכה פשוטה.

איך יוצרים אפליקציית Slack חדשה

  • עוברים אל דף ניהול האפליקציות ב-Slack.
  • לוחצים על הלחצן יצירת אפליקציה חדשה בפינה השמאלית העליונה.
  • נותנים לאפליקציה שם, למשל "Kittenbot".
  • בוחרים את הצוות של Slack שבו רוצים להתקין את האפליקציה.

איך יוצרים משתמשים בבוט

  • בחלונית שבצד ימין, עוברים אל דף הבית של האפליקציה בקטע תכונות

414213b184fcc992.png

  • כדי להקצות היקף לאסימון של הבוט, לוחצים על בדיקת היקפים להוספה.
  • גוללים למטה אל Bot Token Scopes ולוחצים על Add an OAuth Scope. בחירה באפשרות chat:write כדי לשלוח הודעות בשם Kittenbot

74a6fa87c64c2b23.png

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

הפעלת הודעות ופקודות

  • גוללים למטה לקטע הצגת כרטיסיות ומוודאים ששתי האפשרויות מופעלות:

5ca52f7abbdc15c.png

השגת סוד החתימה של הלקוח

  • עוברים אל מידע בסיסי בקטע הגדרות.
  • גוללים למטה אל סוד חתימה, לוחצים על הצגה ומעתיקים את הסוד ללוח:

74cfd6616fa71dc4.png

  • שומרים את הסוד במשתנה סביבה:
CLIENT_SIGNING_SECRET=PASTE_THE_SIGNING_SECRET

איך מקבלים את האסימון של הבוט

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

6f5a18069471101.png

  • שומרים את האסימון של הבוט במשתנה סביבה:
BOT_TOKEN=PASTE_THE_BOT_TOKEN

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

6. אבטחת הסודות שלכם

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

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

ליצירת הסודות שלכם

שומרים את סוד החתימה של הלקוח ואת האסימון של הבוט באמצעות הפקודות הבאות:

  • סוד חתימת הלקוח
echo -n $CLIENT_SIGNING_SECRET | gcloud secrets create client-signing-secret \
  --replication-policy automatic \
  --data-file -
  • אסימון הבוט
echo -n $BOT_TOKEN | gcloud secrets create bot-token \
  --replication-policy automatic \
  --data-file -

לגשת לסודות שלנו

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

echo $(gcloud secrets versions access 1 --secret client-signing-secret)
echo $(gcloud secrets versions access 1 --secret bot-token)

תוכלו גם לראות ולנהל את הסודות שלכם במסוף Google Cloud.

7. לקבלת הקוד לדוגמה

כדי לשכפל את מאגר ה-GitHub ב-Cloud Shell, מריצים את הפקודה הבאה:

git clone https://github.com/googlecodelabs/cloud-slack-bot.git

שינוי הספרייה ל-cloud-slack-bot/start.

cd cloud-slack-bot/start

הבנת הקוד

פותחים את הקובץ kittenbot.js באמצעות עורך שורת הפקודה המועדף עליכם (nano, vim, emacs...) או באמצעות הפקודה הבאה כדי לפתוח ישירות את התיקייה הנוכחית ב-Cloud Shell Editor:

cloudshell workspace .

לקוד החתלתול יש שני תפקידים עיקריים. אחת היא לאחזר את הסודות, והשנייה היא להריץ את הבוט.

קודם כול, אנחנו מייבאים את יחסי התלות:

kittenbot.js

const { Botkit } = require('botkit');
const {
  SlackAdapter,
  SlackEventMiddleware,
} = require('botbuilder-adapter-slack');
const { SecretManagerServiceClient } = require('@google-cloud/secret-manager');

SlackAdapter ו-SlackEventMiddleware הן חבילות שמרחיבות את Botkit ומאפשרות לבוט לתרגם הודעות בקלות ל-Slack API וממנו. הלקוח של Secret Manager יאפשר לגשת לסודות ששמרתם בשלב מוקדם יותר.

עכשיו פיתחנו את הפונקציה לאחזור הסודות:

/**
 * Returns the secret string from Google Cloud Secret Manager
 * @param {string} name The name of the secret.
 * @return {Promise<string>} The string value of the secret.
 */
async function accessSecretVersion(name) {
  const client = new SecretManagerServiceClient();
  const projectId = process.env.PROJECT_ID;
  const [version] = await client.accessSecretVersion({
    name: `projects/${projectId}/secrets/${name}/versions/1`,
  });

  // Extract the payload as a string.
  const payload = version.payload.data.toString('utf8');

  return payload;
}

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

הפונקציה הבאה מפעילה את הבוט:

/**
 * Function to initialize kittenbot.
 */
async function kittenbotInit() {
  const adapter = new SlackAdapter({
    clientSigningSecret: await accessSecretVersion('client-signing-secret'),
    botToken: await accessSecretVersion('bot-token'),
  });

  adapter.use(new SlackEventMiddleware());

  const controller = new Botkit({
    webhook_uri: '/api/messages',
    adapter: adapter,
  });

  controller.ready(() => {
    controller.hears(
      ['hello', 'hi', 'hey'],
      ['message', 'direct_message'],
      async (bot, message) => {
        await bot.reply(message, 'Meow. :smile_cat:');
      }
    );
  });
}

החלק הראשון של הפונקציה מגדיר את הסודות ב-SlackAdapter ולאחר מכן מציין את נקודת הקצה לקבלת הודעות. כשהשלט רחוק מופעל, הבוט ישיב לכל הודעה שכוללת את הביטויים 'hello', "hi" או "hey" עם "מיאו. 😺"

דוגמאות לחלקים הספציפיים הבאים בקובץ המניפסט של האפליקציה:

package.json

{
  // ...
  "scripts": {
    "start": "node kittenbot.js",
    // ...
  },
  "engines": {
    "node": "16"
  },
  // ...
}

אתם יכולים לפרוס אפליקציית Node.js ישירות מהמקור באמצעות Cloud Run. המערכת תציג את הדברים הבאים:

  • Cloud Run שולח קריאה ל-Cloud Build כדי ליצור קובץ אימג' של קונטיינר (מידע נוסף זמין במאמר פריסה מקוד מקור).
  • אם בספריית קוד המקור יש Dockerfile, Cloud Build ישתמש בו כדי ליצור קובץ אימג' בקונטיינר.
  • מכיוון שהמודל לא נמצא כרגע, Cloud Build שולח קריאה ל-Buildpacks כדי לנתח את המקור וליצור באופן אוטומטי קובץ אימג' שמוכן לייצור.
  • buildpacks מזהה את המניפסט package.json ויוצר קובץ אימג' של Node.js.
  • השדה scripts.start קובע את אופן ההפעלה של האפליקציה.
  • השדה engines.node קובע את גרסת Node.js של קובץ האימג' הבסיסי של הקונטיינר.
  • בזמן הפריסה, תיקוני אבטחה מוכרים מיושמים באופן אוטומטי.

האפליקציה מוכנה לפריסה!

8. פורסים את האפליקציה

ב-Slack Event API משתמשים בתגובה לפעולה מאתר אחר (webhook) כדי לשלוח הודעות יוצאות לגבי אירועים. כשמגדירים את אפליקציית Slack, צריך לספק כתובת URL נגישה לכולם כדי ש-Slack API יוכל לשלוח פינג.

Cloud Run הוא פתרון טוב לאירוח יעדים של תגובה לפעולה מאתר אחר (webhook). הוא מאפשר להשתמש בכל שפה או זמן ריצה שרוצים, ומספק בו-זמניות (concurrency), כלומר האפליקציה שלכם תוכל להתמודד עם נפח גבוה בהרבה.

אחזור של מזהה הפרויקט

מגדירים את משתנה הסביבה PROJECT_ID:

PROJECT_ID=$(gcloud config get-value core/project)

הגדרת האזור שלכם ב-Cloud Run

Cloud Run הוא אזור אזורי, כלומר התשתית שמפעילה את שירות Cloud Run ממוקמת באזור ספציפי ומנוהלת על ידי Google כך שהיא תהיה זמינה ביתית בכל התחומים (zones) באותו אזור. מגדירים את האזור שישמש לפריסה, לדוגמה:

REGION="us-central1"

עדכון ההרשאות

כדי לגשת לסודות מ-Secret Manager, צריך להקצות לחשבון השירות של Cloud Run את התפקיד roles/secretmanager.secretAccessor.

קודם כול, שומרים את חשבון השירות שמוגדר כברירת מחדל במשתנה סביבה:

SERVICE_ACCOUNT=$(gcloud iam service-accounts list \
  --format "value(email)" \
  --filter "displayName:Compute Engine default service account")

מאשרים שכתובת האימייל שמורה:

echo $SERVICE_ACCOUNT

חשבון השירות מופיע בפורמט הבא: PROJECT_NUMBER-compute@developer.gserviceaccount.com.

אחרי שמקבלים את כתובת האימייל, מפעילים את התפקיד עבור חשבון השירות:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT \
  --role roles/secretmanager.secretAccessor

פורסים את האפליקציה

שירות Cloud Run חושף נקודת קצה (endpoint) ייחודית ומדרג באופן אוטומטי את התשתית הבסיסית כדי לטפל בבקשות נכנסות.

פורסים את האפליקציה ב-Cloud Run:

gcloud run deploy kittenbot \
  --source . \
  --platform managed \
  --region $REGION \
  --set-env-vars PROJECT_ID=$PROJECT_ID \
  --allow-unauthenticated
  • הפעולה הזו יוצרת שירות בשם kittenbot.
  • האפשרות --source משתמשת בתיקייה הנוכחית כדי לפתח את האפליקציה ב-Cloud Build. Cloud Build מזהה באופן אוטומטי את הנוכחות של הקובץ package.json.
  • אפשר גם להגדיר אזור ברירת מחדל באמצעות הפקודה הבאה: gcloud config set run/region $REGION
  • אפשר גם להפוך את Cloud Run למנוהל כברירת מחדל באמצעות הפקודה הבאה: gcloud config set run/platform managed
  • האפשרות --set-env-vars מגדירה את המשתנים של סביבת השירות.
  • האפשרות --allow-unauthenticated הופכת את השירות לזמין לציבור.

בפעם הראשונה תופיע הנחיה ליצור מאגר של Artifact Registry. צריך להקיש על Enter כדי לאמת:

Deploying from source requires an Artifact Registry Docker repository to store
built containers. A repository named [cloud-run-source-deploy] in region [REGION]
will be created.

Do you want to continue (Y/n)?

הפעולה הזו מפעילה את ההעלאה של קוד המקור למאגר Artifact Registry ואת ה-build של קובץ האימג' בקונטיינר:

Building using Dockerfile and deploying container ...
* Building and deploying new service... Building Container.
  OK Creating Container Repository...
  OK Uploading sources...
  * Building Container... Logs are available at ...

לאחר מכן, המתינו רגע עד להשלמת ה-build והפריסה. לאחר הצלחה, שורת הפקודה תציג את כתובת ה-URL של השירות:

...
OK Building and deploying new service... Done.
  OK Creating Container Repository...
  OK Uploading sources...
  OK Building Container... Logs are available at ...
  OK Creating Revision... Creating Service.
  OK Routing traffic...
  OK Setting IAM Policy...
Done.
Service [SERVICE]... has been deployed and is serving 100 percent of traffic.
Service URL: https://SERVICE-PROJECTHASH-REGIONID.a.run.app

אפשר למצוא את כתובת ה-URL של השירות באמצעות הפקודה הבאה:

SERVICE_URL=$( \
  gcloud run services describe kittenbot \
  --platform managed \
  --region $REGION \
  --format "value(status.url)" \
)
echo $SERVICE_URL

כתובת ה-URL בפורמט הבא:

https://kittenbot-PROJECTHASH-REGIONID.a.run.app

כתובת ה-URL הזו תהיה הבסיס שישמש להפעלת ה-Slack Event API. אפשר להעתיק אותו ללוח כדי להשתמש בו בשלב הבא.

השירות שלך זמין עכשיו וזמין לציבור! מידע נוסף זמין במסוף Cloud Run. fee46ea7c8483d56.png

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

עכשיו נתחיל לשלוח הודעות מערוץ Slack!

9. הפעלת אירועי Slack

כפי שראינו קודם, הקוד ל-kittenbot מציין נקודת קצה (endpoint) יחסית ליעד ה-webhook שלנו.

kittenbot.js

 const controller = new Botkit({
    webhook_uri: '/api/messages',
    adapter: adapter,
  });

כלומר, כתובת ה-URL המלאה שלנו תהיה הבסיס משירות Cloud Run, וגם /api/messages.

הפעלת האירועים

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

PASTE_THE_SERVICE_URL/api/messages

5179a99339839999.png

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

הרשמה למינוי

הרשמה לכל האירועים של בוט ההודעות.

1e8f200390908a9b.png

לוחצים על שמירת השינויים בחלק התחתון של הדף. תתבקשו להתקין מחדש את האפליקציה. עוברים על ההנחיות ולוחצים על אישור.

בשלב הזה הבוט משולב בצורה מלאה. הודעות בסביבת העבודה יפעילו את Slack כדי לשלוח הודעות לשירות Cloud Run, ויגיע תגובה עם הודעת פתיחה פשוטה.

10. בדיקת הבוט

שליחת הודעה בצ'אט אישי ל-Kittenbot:

1f442dd7fd7b5773.png

כדי להוסיף את kittenbot לערוץ מזינים ' @kittenbot' ואז לוחצים על 'שליחת הזמנה':

9788d2167ce47167.png

עכשיו כל הצופים בערוץ שלך יכולים לתקשר עם Kittenbot!

9c0d1d7907a51767.png

כל הודעה ב-Slack מפעילה אירוע ושולחת הודעת HTTP POST לשירות Cloud Run. אם תעיינו ביומני השירות של Cloud Run, תראו שכל הודעה תואמת לרשומת POST ביומן.

1ff0c2347bf464e8.png

החתלתול מגיב לכל הודעה במילים 'כריח' 😺"

11. בונוס – עדכון הבוט

הקטע האופציונלי הזה נמשך כמה דקות. אפשר לדלג ישירות אל 'ניקוי'.

שרשורים בשיחה

אנחנו רוצים שהבוט יוכל לעשות יותר מאשר רק "מיאו". אבל איך פורסים גרסה חדשה של משהו שרץ ב-Cloud Run?

שינוי הספרייה ל-cloud-slack-bot/extra-credit:

cd ../extra-credit/

פותחים את התיקייה הנוכחית ב-Cloud Shell Editor:

cloudshell workspace .

Botkit מאפשר לטפל בשיחות. כך הבוט יכול לבקש מידע נוסף ולהגיב להודעות, מעבר למילה אחת של תשובה.

הגדרה של תיבת הדו-שיח

קודם כול, בודקים איך מוגדרות פונקציות שיחה בסוף הקובץ:

// ...
const maxCats = 20;
const catEmojis = [
  ':smile_cat:',
  ':smiley_cat:',
  ':joy_cat:',
  ':heart_eyes_cat:',
  ':smirk_cat:',
  ':kissing_cat:',
  ':scream_cat:',
  ':crying_cat_face:',
  ':pouting_cat:',
  ':cat:',
  ':cat2:',
  ':leopard:',
  ':lion_face:',
  ':tiger:',
  ':tiger2:',
];

/**
 * Function to concatenate cat emojis
 * @param {number} numCats Number of cat emojis.
 * @return {string} The string message of cat emojis.
 */
function makeCatMessage(numCats) {
  let catMessage = '';
  for (let i = 0; i < numCats; i++) {
    // Append a random cat from the list
    catMessage += catEmojis[Math.floor(Math.random() * catEmojis.length)];
  }
  return catMessage;
}

/**
 * Function to create the kitten conversation
 * @param {Object} controller The botkit controller.
 * @return {Object} The BotkitConversation object.
 */
function createKittenDialog(controller) {
  const convo = new BotkitConversation('kitten-delivery', controller);

  convo.ask('Does someone need a kitten delivery?', [
    {
      pattern: 'yes',
      handler: async (response, convo, bot) => {
        await convo.gotoThread('yes_kittens');
      },
    },
    {
      pattern: 'no',
      handler: async (response, convo, bot) => {
        await convo.gotoThread('no_kittens');
      },
    },
    {
      default: true,
      handler: async (response, convo, bot) => {
        await convo.gotoThread('default');
      },
    },
  ]);

  convo.addQuestion(
    'How many would you like?',
    [
      {
        pattern: '^[0-9]+?',
        handler: async (response, convo, bot, message) => {
          const numCats = parseInt(response);
          if (numCats > maxCats) {
            await convo.gotoThread('too_many');
          } else {
            convo.setVar('full_cat_message', makeCatMessage(numCats));
            await convo.gotoThread('cat_message');
          }
        },
      },
      {
        default: true,
        handler: async (response, convo, bot, message) => {
          if (response) {
            await convo.gotoThread('ask_again');
          } else {
            // The response '0' is interpreted as null
            await convo.gotoThread('zero_kittens');
          }
        },
      },
    ],
    'num_kittens',
    'yes_kittens'
  );

  // If numCats is too large, jump to start of the yes_kittens thread
  convo.addMessage(
    'Sorry, {{vars.num_kittens}} is too many cats. Pick a smaller number.',
    'too_many'
  );
  convo.addAction('yes_kittens', 'too_many');

  // If response is not a number, jump to start of the yes_kittens thread
  convo.addMessage("Sorry I didn't understand that", 'ask_again');
  convo.addAction('yes_kittens', 'ask_again');

  // If numCats is 0, send a dog instead
  convo.addMessage(
    {
      text:
        'Sorry to hear you want zero kittens. ' +
        'Here is a dog, instead. :dog:',
      attachments: [
        {
          fallback: 'Chihuahua Bubbles - https://youtu.be/s84dBopsIe4',
          text: '<https://youtu.be/s84dBopsIe4|' + 'Chihuahua Bubbles>!',
        },
      ],
    },
    'zero_kittens'
  );

  // Send cat message
  convo.addMessage('{{vars.full_cat_message}}', 'cat_message');

  convo.addMessage('Perhaps later.', 'no_kittens');

  return convo;
}

השיחה החדשה הזו מפנה את השרשור על סמך התשובות. לדוגמה, אם המשתמש משיב 'לא' לשאלה החתלתולים, הוא עובר להודעה בשם 'no_kittens', שהיא סוף השרשור בשיחה.

הוספת תיבת הדו-שיח לשלט רחוק

עכשיו, אחרי שהשיחה מוגדרת, אפשר להוסיף אותה לבקר:

async function kittenbotInit() {
  // ...
  const controller = new Botkit({
    webhook_uri: '/api/messages',
    adapter: adapter,
  });

  // Add Kitten Dialog
  const convo = createKittenDialog(controller);
  controller.addDialog(convo);

  // Controller is ready
  controller.ready(() => {
    // ...
  });
}

טריגרים של תיבת הדו-שיח

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

  // ...

  controller.ready(() => {
    controller.hears(
      ['hello', 'hi', 'hey'],
      ['message', 'direct_message'],
      async (bot, message) => {
        await bot.reply(message, 'Meow. :smile_cat:');
        return;
      }
    );

    // START: listen for cat emoji delivery
    controller.hears(
      ['cat', 'cats', 'kitten', 'kittens'],
      ['message', 'direct_message'],
      async (bot, message) => {
        // Don't respond to self
        if (message.bot_id !== message.user) {
          await bot.startConversationInChannel(message.channel, message.user);
          await bot.beginDialog('kitten-delivery');
          return;
        }
      }
    );
    // END: listen for cat emoji delivery

    // ...
  });

  // ...

עדכון האפליקציה

פורסים מחדש את האפליקציה ב-Cloud Run:

gcloud run deploy kittenbot \
  --source . \
  --platform managed \
  --region $REGION \
  --set-env-vars PROJECT_ID=$PROJECT_ID \
  --allow-unauthenticated

רוצים לנסות?

eca12b3463850d52.png

מעולה! שיניתם עכשיו בוט של Slack, שפועל ב-Cloud Run, לגרסה חדשה.

פקודות Salash

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

אפשר להשתמש ב-Slack הזה באמצעות פקודות Slash, שמאפשרות למשתמשים להפעיל את האפליקציה באמצעות הזנת הפקודה בתיבת ההודעה.

הפעלת הפקודות של Slack Slash

  • עוברים לקטע Slash Commands בקטע Features (תכונות) בדף 'ניהול אפליקציות'.
  • לוחצים על Create New Command.
  • מגדירים פקודת /cats עם כתובת ה-URL של שירות ה-kittenbot. חשוב לזכור להשתמש באותה נקודת הקצה שבה השתמשתם כדי להפעיל את ה-Event API. זו כתובת ה-URL שלך, בתוספת '/api/messages'.

e34d393c14308f28.png

  • פועלים לפי ההנחיות כדי לעדכן את האפליקציה ואת ההרשאות.

הוספת פקודות Lash לשלט רחוק

כך נוסף handler של פקודות לוכסן בתוך הפונקציהcontrol.Ready:

  // ...

  // Controller is ready
  controller.ready(() => {
    // ...

    // START: slash commands
    controller.on('slash_command', async (bot, message) => {
      const numCats = parseInt(message.text);
      const response = makeCatMessage(numCats);
      bot.httpBody({ text: response });
    });
    // END: slash commands
  });

  // ...

רוצים לנסות?

כדי לשלוח את הפקודה של הלוכסן, מזינים /cats ועוד מספר. לדוגמה: /cats 8

c67f6fe1ffcafec8.png

הבוט יחזיר 8 חתולים עם 8 חתולים, אבל רק לכם:

9c1b256987fd379a.png

12. הסרת המשאבים

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

מחיקת הפרויקט

אפשר למחוק את הפרויקט כולו ישירות מ-Cloud Shell:

gcloud projects delete $PROJECT_ID

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

מחיקת הפריסה

gcloud run services delete kittenbot --region $REGION

הפלט של הפקודה

Service [kittenbot] will be deleted.
Do you want to continue (Y/n)?  y
Deleted service [kittenbot].

מחיקת סוד החתימה של הלקוח

gcloud secrets delete client-signing-secret

הפלט של הפקודה

You are about to destroy the secret [client-signing-secret] and its
[1] version(s). This action cannot be reversed.
Do you want to continue (Y/n)?  y
Deleted secret [client-signing-secret].

איך מוחקים את הסוד של האסימון של הבוט

gcloud secrets delete bot-token

הפלט של הפקודה

You are about to destroy the secret [bot-token] and its [1]
version(s). This action cannot be reversed.
Do you want to continue (Y/n)?  y
Deleted secret [bot-token].

מחיקת קטגוריות האחסון

קודם כול, מציגים את רשימת הקטגוריות של Google Cloud Storage כדי לקבל את הנתיב של הקטגוריה:

gsutil ls

הפלט של הפקודה

gs://[REGION.]artifacts.<PROJECT_ID>.appspot.com/
gs://<PROJECT_ID>_cloudbuild/

בשלב הזה מוחקים את קטגוריית פריטי המידע שנוצרו בתהליך הפיתוח (Artifact):

gsutil rm -r gs://[REGION.]artifacts.${PROJECT_ID}.appspot.com/

הפלט של הפקודה

Removing gs://[REGION.]artifacts.<PROJECT_ID>.appspot.com/...

לבסוף, מוחקים את הקטגוריה של Cloudbuild:

gsutil rm -r gs://${PROJECT_ID}_cloudbuild/

הפלט של הפקודה

Removing gs://<PROJECT_ID>_cloudbuild/...

13. מעולה!

528302981979de90.png

עכשיו אתם יודעים איך להריץ בוט של Slack ב-Cloud Run!

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

אילו נושאים דיברנו?

  • יצירת שילוב בהתאמה אישית של בוט ב-Slack
  • אבטחת הסודות ב-Slack באמצעות Secret Manager
  • פריסת הבוט של Slack ב-Cloud Run

השלבים הבאים

מידע נוסף