1. 總覽
在本程式碼研究室中,您將瞭解如何使用 Botkit 工具包建構 Slack 機器人,並在 Google Cloud 上執行。您將在即時的 Slack 頻道中與機器人互動。
課程內容
- 如何在 Slack 中建立機器人自訂整合項目
- 如何使用 Secret Manager 保護 Slack 密鑰
- 瞭解如何在 Cloud Run 部署 Slack 機器人。Cloud Run 是一個全代管運算平台,可自動調整無狀態容器的資源配置
軟硬體需求
您會如何使用這個教學課程?
針對 Google Cloud 使用體驗,您會給予什麼評價?
2. 設定和需求
自修環境設定
- 登入 Google Cloud 控制台,建立新專案或重複使用現有專案。如果您還沒有 Gmail 或 Google Workspace 帳戶,請先建立帳戶。
- 「專案名稱」是這項專案參與者的顯示名稱。這是 Google API 未使用的字元字串。您可以隨時更新付款方式。
- 所有 Google Cloud 專案的專案 ID 均不得重複,而且設定後即無法變更。Cloud 控制台會自動產生一個不重複的字串。但通常是在乎它何在在大部分的程式碼研究室中,您必須參照專案 ID (通常為
PROJECT_ID
)。如果您對產生的 ID 不滿意,可以隨機產生一個 ID。或者,您也可以自行嘗試,看看是否支援。在這個步驟後,這個名稱即無法變更,而且在專案期間內仍會保持有效。 - 資訊中的第三個值是專案編號,部分 API 會使用這個編號。如要進一步瞭解這三個值,請參閱說明文件。
- 接下來,您需要在 Cloud 控制台中啟用計費功能,才能使用 Cloud 資源/API。執行本程式碼研究室不會產生任何費用 (如果有的話)。如要關閉資源,以免產生本教學課程結束後產生的費用,您可以刪除自己建立的資源或刪除專案。新使用者符合 $300 美元免費試用計畫的資格。
啟動 Cloud Shell
雖然 Google Cloud 可以從筆記型電腦遠端操作,但在本教學課程中,您將使用 Cloud Shell,這是在 Cloud 中執行的指令列環境。
啟用 Cloud Shell
- 在 Cloud 控制台中,按一下「啟用 Cloud Shell」圖示 。
如果您是第一次啟動 Cloud Shell,系統會顯示中繼畫面,說明這項服務的內容。如果系統顯示中繼畫面,請按一下「繼續」。
佈建並連線至 Cloud Shell 只需幾分鐘的時間。
這個虛擬機器已載入所有必要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。在本程式碼研究室中,您的大部分作業都可透過瀏覽器完成。
連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。
- 在 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`
- 在 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 中啟用 Artifact Registry、Cloud Build、Cloud Run 和 Secret Manager API:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ run.googleapis.com \ secretmanager.googleapis.com
這會輸出與以下內容類似的成功訊息:
Operation "operations/..." finished successfully.
您現在可以準備及部署應用程式...
4. 建立 Slack 工作區
您必須擁有 Slack 工作區,才能建立自訂整合項目。如果您還沒有要用於本教學課程的工作區,可以免費建立工作區。
5. 建立 Slack 機器人使用者
機器人使用者可以監聽 Slack 的訊息、發布訊息及上傳檔案。在本程式碼研究室中,您將建立機器人來張貼簡單的問候訊息。
建立新的 Slack 應用程式
- 前往 Slack 應用程式管理頁面。
- 按一下右上角的「Create new app」按鈕。
- 為應用程式命名,例如「Kittenbot」。
- 選擇要安裝哪個 Slack 團隊。
建立機器人使用者
- 在左側面板的「功能」下方,前往「應用程式首頁」
- 按一下「查看要新增的範圍」,為機器人權杖指派範圍
- 向下捲動至「Bot Token Scopes」(機器人權杖範圍),然後按一下「Add an OAuth Scope」(新增 OAuth 範圍)。選取
chat:write
即可「以 Kittenbot 的身分傳送訊息」
- 向上捲動,然後按一下「Install App to your Workspace」按鈕。
- 這個應用程式會安裝到您的團隊、新增您剛建立的機器人使用者,並產生機器人權杖。
- 出現提示訊息時,請按一下 [允許],即可授權機器人在您的工作區中進行即時通訊。
啟用訊息和指令
- 向下捲動至「顯示分頁」,並確認這兩個選項均已啟用:
取得用戶端簽署密鑰
- 前往「設定」中的「基本資訊」。
- 向下捲動至「簽署密鑰」,按一下「顯示」,然後將密鑰複製到剪貼簿:
- 將密鑰儲存在環境變數中:
CLIENT_SIGNING_SECRET=PASTE_THE_SIGNING_SECRET
取得機器人權杖
- 前往 OAuth 與功能下的權限。
- 按一下「Copy」按鈕,將「Bot User OAuth Access Token」文字複製到剪貼簿。
- 將機器人權杖儲存在環境變數中:
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
瞭解程式碼
使用您偏好的指令列編輯器 (nano、vim、emacs...) 開啟 kittenbot.js
檔案,或使用以下指令在 Cloud Shell 編輯器中直接開啟目前的資料夾:
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」的訊息並會說話。😺?」。
請查看應用程式資訊清單中的下列特定部分:
package.json
{
// ...
"scripts": {
"start": "node kittenbot.js",
// ...
},
"engines": {
"node": "16"
},
// ...
}
您可以直接使用 Cloud Run,從原始碼部署 Node.js 應用程式。系統實際上會發生以下情形:
- 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 會使用 Webhook 傳送與事件相關的外送訊息。設定 Slack 應用程式時,您必須提供可公開存取的網址,讓 Slack API 進行連線偵測 (ping)。
Cloud Run 是託管 Webhook 目標的理想解決方案。它可讓您使用任何偏好的語言或執行階段,而且提供並行,意即您的應用程式能夠處理更多的磁碟區。
擷取專案 ID
定義 PROJECT_ID 環境變數:
PROJECT_ID=$(gcloud config get-value core/project)
定義 Cloud Run 區域
Cloud Run 具有「區域性」,這表示執行 Cloud Run 服務的基礎架構位於特定區域,並由 Google 代管,可為該區域內的所有可用區提供備援功能。定義部署項目所使用的區域,例如:
REGION="us-central1"
更新權限
如要存取 Secret Manager 的密鑰,必須將 roles/secretmanager.secretAccessor
角色授予 Cloud Run 服務帳戶。
首先,將預設服務帳戶儲存在環境變數中:
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 存放區時,系統會提示您建立 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 ...
接著,請等待建構及部署完成。部署成功之後,指令列會顯示服務網址:
... 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
您可以使用下列指令取得服務網址:
SERVICE_URL=$( \ gcloud run services describe kittenbot \ --platform managed \ --region $REGION \ --format "value(status.url)" \ ) echo $SERVICE_URL
網址格式如下:
https://kittenbot-PROJECTHASH-REGIONID.a.run.app
這個網址將成為啟用 Slack 活動 API 的基礎。請將網址複製到剪貼簿,以在下一個步驟中使用。
你的服務現已發布並公開發布!請前往 Cloud Run 控制台瞭解詳情。
您可以查看上次修訂版本的建立時間、接收的流量,以及記錄檔。點選記錄後,就能看到 Botkit 控制器已開啟,可以開始接收訊息。
現在讓我們開始從 Slack 頻道傳送訊息!
9. 啟用 Slack 事件
如先前所述,貓咪機器人程式碼會為 Webhook 目標指定相對端點。
kittenbot.js
const controller = new Botkit({
webhook_uri: '/api/messages',
adapter: adapter,
});
這表示完整網址將是 Cloud Run 服務的基本部分,再加上 /api/messages
。
啟用事件
在應用程式管理頁面中,前往側欄的「事件訂閱」部分,然後將「啟用事件」切換為開啟。輸入服務網址:
PASTE_THE_SERVICE_URL/api/messages
系統可能會在你完成網址前嘗試驗證,實際速度取決於輸入網址的速度。如果失敗,請按一下「重試」。
訂閱
訂閱所有訊息機器人事件。
按一下頁面底部的「儲存變更」。系統會提示您重新安裝應用程式。按照提示操作,然後按一下「允許」。
到目前為止,您的機器人已完全整合!工作區中的訊息會觸發 Slack 將訊息傳送至 Cloud Run 服務,接著再以簡單的問候語回應。
10. 測試機器人
傳送即時訊息給 Kittenbot:
輸入「@kittenbot」即可將貓咪機器人加入頻道然後按一下 [邀請對方],即可邀請對方。
現在你頻道中的所有使用者都能與 Kittenbot 互動!
Slack 中的每則訊息都會觸發事件,並傳送 HTTP POST 訊息至 Cloud Run 服務。如果您查看 Cloud Run 服務記錄檔,就會看到每個訊息都對應至記錄檔中的 POST 項目。
小貓會以「喵」😺?」。
11. 獎勵 - 更新機器人
這個選用章節大約需要幾分鐘的時間。您可以直接跳到「清理」。
對話討論串
我們希望機器人能做的,不再只是「甲」而已。但要如何在 Cloud Run 部署新版本的運作?
將目錄變更為 cloud-slack-bot/extra-credit
:
cd ../extra-credit/
在 Cloud Shell 編輯器中開啟目前的資料夾:
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
馬上試試
恭喜!您已將在 Cloud Run 上執行的 Slack 機器人更新為新版本。
斜線指令
如果您不想和該使用者對話,該怎麼做?如果只想透過一個簡單的指令觸發動作,該怎麼做?
Slack 透過 Slash 指令提供這項功能,讓使用者在訊息方塊中輸入指令就能叫用您的應用程式。
啟用 Slack Slash 指令
- 前往應用程式管理頁面上「功能」下方的「Slash Commands」部分。
- 按一下「Create New Command」。
- 使用您的 Kittenbot 服務網址設定
/cats
指令。請務必使用先前啟用 Event API 的端點!這是您的網址,再加上'/api/messages'
。
- 按照提示更新應用程式和權限。
將 Slash 指令新增至控制器
看看如何在 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
機器人會回應 8 隻貓,但只有你看得到:
12. 清除
恭喜,您在 Cloud Run 中已有一個執行中的 Slack 機器人。是花時間清理所用資源 (節省成本並成為良好的雲端公民)。
刪除專案
您可以直接透過 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/
現在,請刪除構件值區:
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. 恭喜!
您已瞭解如何在 Cloud Run 中執行 Slack 機器人!
這項技術才剛起步,建議您深入瞭解自己的 Cloud Run 部署項目。
涵蓋內容
- 在 Slack 中建立機器人自訂整合
- 運用 Secret Manager 保護 Slack 密鑰
- 在 Cloud Run 中部署 Slack 機器人
後續步驟
- 完成更多 Cloud Run 教學課程
瞭解詳情
- 查看 GitHub 上的其他 Google Cloud Slack 整合範例。
- 自行試用其他 Google Cloud 功能。歡迎參考我們的教學課程。