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

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

5f529fb87abc11c9.png

ב-Codelab הזה תלמדו איך ליצור בוט ל-Slack באמצעות ערכת הכלים 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

  • שם הפרויקט הוא השם המוצג של הפרויקט הזה למשתתפים. זו מחרוזת תווים שלא נמצאת בשימוש ב-Google APIs. תמיד אפשר לעדכן את המיקום.
  • מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud, והוא קבוע (אי אפשר לשנות אותו אחרי שהוא מוגדר). מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית, ובדרך כלל לא צריך לדעת מה היא. ברוב ה-Codelabs, תצטרכו להפנות למזהה הפרויקט (בדרך כלל מסומן כ-PROJECT_ID). אם אתם לא אוהבים את המזהה שנוצר, אתם יכולים ליצור מזהה אקראי אחר. אפשר גם לנסות שם משתמש משלכם ולבדוק אם הוא זמין. אי אפשר לשנות את ההגדרה הזו אחרי השלב הזה, והיא תישאר לאורך הפרויקט.
  • לידיעתכם, יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. במאמרי העזרה מפורט מידע נוסף על שלושת הערכים האלה.
  1. בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API של Cloud. השלמת ה-codelab הזה לא תעלה לכם הרבה, אם בכלל. כדי להשבית את המשאבים ולמנוע חיובים נוספים אחרי שתסיימו את המדריך הזה, תוכלו למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.

מפעילים את Cloud Shell

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

הפעלת Cloud Shell

  1. ב-Cloud Console, לוחצים על 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.
  • לוחצים על הלחצן Create new app (יצירת אפליקציה חדשה) בפינה השמאלית העליונה.
  • נותנים לאפליקציה שם, למשל Kittenbot.
  • בוחרים את הצוות ב-Slack שבו רוצים להתקין את האפליקציה.

יצירת משתמש בוט

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

414213b184fcc992.png

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

74a6fa87c64c2b23.png

  • גוללים למעלה ולוחצים על הלחצן Install App to your Workspace (התקנת האפליקציה בסביבת העבודה).
  • הפעולה הזו תתקין את האפליקציה בצוות שלכם, תוסיף את משתמש הבוט שיצרתם ותיצור טוקן בוט.
  • כשמופיעה בקשה, לוחצים על אישור כדי לתת לבוט הרשאה לשוחח בסביבת העבודה.

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

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

5ca52f7abbdc15c.png

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

  • עוברים אל הגדרות ואז אל מידע בסיסי.
  • גוללים למטה אל Signing Secret (סוד החתימה), לוחצים על Show (הצגה) ומעתיקים את הסוד ללוח:

74cfd6616fa71dc4.png

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

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

  • עוברים אל OAuth & Permissions (הרשאות ו-OAuth) בקטע Features (תכונות).
  • לוחצים על הלחצן העתקה כדי להעתיק את הטקסט טוקן הגישה ל-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. קבלת קוד לדוגמה

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

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 יש שתי פונקציות עיקריות. אחת מהן היא לאחזור הסודות, והשנייה היא להפעלת הבוט.

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

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" בתשובה "Meow. 😺".

כדאי לעיין בחלקים הספציפיים האלה בקובץ המניפסט של האפליקציה:

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

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

פורסים את האפליקציה ב-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 ואת יצירת קובץ אימג' של קונטיינר:

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 Events API. מעתיקים אותו ללוח כדי להשתמש בו בשלב הבא.

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

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

עכשיו אפשר להתחיל לשלוח הודעות מערוץ Slack שלנו.

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

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

kittenbot.js

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

כלומר, כתובת ה-URL המלאה תהיה החלק הבסיסי משירות Cloud Run, בתוספת /api/messages.

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

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

PASTE_THE_SERVICE_URL/api/messages

5179a99339839999.png

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

הרשמה למינוי

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

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(() => {
    // ...
  });
}

הפעלת תיבת הדו-שיח

עכשיו תיבת הדו-שיח זמינה לבקר. אפשר לראות איך השיחה מתחילה כשהצ'אטבוט שומע את המילים kitten,‏ kittens,‏ cat או cats:

  // ...

  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 לגרסה חדשה.

פקודות דרך שורת הפקודות

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

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

הפעלת פקודות דרך שורת הפקודות ב-Slack

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

e34d393c14308f28.png

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

הוספת פקודות סלאש לבקר

כך מוסיפים handler לפקודות דרך שורת הפקודות בתוך הפונקציה controller.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 חתולים, שרק אתם יכולים לראות:

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

השלבים הבאים

  • השלמת מדריכים נוספים בנושא Cloud Run

מידע נוסף