將後端模組整合至系統

後端模組提供基礎架構,可處理大量與功能相關的訊息,並與服務專員桌面 UI 互動。本教學課程會逐步引導您將後端模組與代理程式系統整合。

如要進一步瞭解背景模組概念和結構,請參閱「後端模組基礎知識」說明文件。

必要條件

  1. 如果尚未設定,請安裝 Google Cloud CLI
  2. 為您需要 Dialogflow 提供的每種事件通知,建立 Cloud Pub/Sub 主題。請記下主題 ID 和主題名稱,以便稍後部署後端。
  3. 使用 Agent Assist 控制台和 Pub/Sub 主題設定對話設定檔

部署作業自動化

您可以使用 Google Cloud 自動化指令碼或 Terraform,自動部署。

自動化指令碼

詳情請參閱 ./deploy.sh

套用 Terraform 變更

您可以使用 gcloud CLI 自動化指令碼或 Terraform,自動部署。套用 Terraform 變更前,請先完成下列步驟。

  1. 將下列 IAM 角色授予您的帳戶:
    • Project IAM Admin (roles/resourcemanager.projectIamAdmin)
    • Service Usage Admin (roles/serviceusage.serviceUsageAdmin)
    • Service Account Admin (roles/iam.serviceAccountAdmin)
    • Service Account User (roles/iam.serviceAccountUser)
    • Pub/Sub Admin (roles/pubsub.admin)
    • Secret Manager Admin (roles/secretmanager.admin)
    • Cloud Build Editor (roles/cloudbuild.builds.editor)
    • Artifact Registry Administrator (roles/artifactregistry.admin)
    • Storage Admin (roles/storage.admin)
    • Cloud Run Admin (roles/run.admin)
    • Cloud Memorystore Redis Admin (roles/redis.admin)
    • Serverless VPC Access Admin (roles/vpcaccess.admin)
  2. 為 UI 連接器和 Cloud Pub/Sub 攔截器建構映像檔,並記下映像檔名稱。
    • 如要使用 UI 連接器,請在 ./ui-connector 資料夾下執行下列指令。
      $ gcloud builds submit --tag gcr.io/$GCP_PROJECT_ID/aa-integration-backend/ui-connector
    • 如為 Cloud Pub/Sub Interceptor,請在 ./cloud-pubsub-interceptor 資料夾下執行下列指令。
      $ gcloud builds submit --tag gcr.io/$GCP_PROJECT_ID/aa-integration-backend/cloud-pubsub-interceptor
  3. 建立 Cloud Storage bucket 來儲存 Terraform 狀態,並使用下列指令更新 /terraform/backend.tf 的後端 bucket 值。
    GCP_PROJECT_ID=$(gcloud config get-value project)
    # Create the Cloud storage bucket
    gcloud storage buckets create gs://${GCP_PROJECT_ID}-tfstate
    # Enable Object Versioning to keep the history of your deployments
    gcloud storage buckets update gs://${GCP_PROJECT_ID}-tfstate --versioning
  4. 匯出必要 Terraform 變數 gcp_project_idui_connector_docker_imagecloud_pubsub_interceptor_docker_image 的值。例如:export TF_VAR_gcp_project_id='you-gcp-project-id'。你也可以直接在 /terraform/variables.tf 中填入值。
  5. 如要自訂驗證方法,請在 /ui-connector/auth.py 修改 auth.check_auth() 方法。

如要使用 Cloud Build 自動執行這些步驟,請按照這項指示操作,並使用建構設定檔 ./terraform_cloudbuild.yaml。如要允許 Cloud Build 部署服務,您必須將步驟 1 列出的 IAM 角色授予 Cloud Build 服務帳戶。

手動部署

下列步驟說明如何手動部署後端模組。

設定環境變數

為簡化部署指令,建議您在殼層中設定下列實用的環境變數。您可以使用下列範例指令設定變數:

$ export GCP_PROJECT_ID='aa-integration-service'

設定下列環境變數:

  • GCP_PROJECT_ID:Cloud Platform 專案的專案 ID,用於存放相關資源。範例:my-project
  • SERVICE_REGION:服務和相關 Google Cloud 資源的位置或區域。 平台資源。範例:us-central1

設定管理員帳戶

建議您使用不同的 Google Cloud 帳戶進行服務管理和執行階段身分識別。服務管理作業主要由具有 Google 帳戶的人員執行,而執行階段身分則使用服務帳戶授予 Cloud Run 服務權限,以便存取必要資源。

準備人員管理帳戶

如果您打算使用專案中已具備「編輯者」或「擁有者」權限的帳戶,可以跳至下一節

如要管理後端基礎架構,請建立管理員帳戶,並授予下列 Identity and Access Management (IAM) 角色。編輯者和擁有者基本角色都具備這些權限。

  • roles/secretmanager.admin (Secret Manager 管理員):管理儲存在 Secret Manager 中的密鑰,用於產生和驗證 JWT。
  • roles/run.admin (Cloud Run 管理員):部署及管理 Cloud Run 服務。
  • roles/iam.serviceAccountUser (服務帳戶使用者):授予 Cloud Run 執行階段服務帳戶 iam.serviceAccounts.actAs 權限。
  • roles/cloudbuild.builds.editor (Cloud Build 編輯者):使用 Cloud Build 建構整合服務的 Docker 映像檔。
  • Artifact Registry 管理員:儲存及管理整合服務的建構 Docker 映像檔。
  • roles/pubsub.editor (Cloud Pub/Sub 編輯者):建立及管理 Cloud Pub/Sub 主題和訂閱項目。
  • roles/redis.admin (Redis 管理員):建立及管理 Memorystore for Redis 資源。

如要將 IAM 角色授予人員帳戶,請使用 add-iam-policy-binding Google Cloud CLI 指令。指令範例如下:

$ gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
 --member='user:test-user@gmail.com' \
 --role='roles/pubsub.editor'

在 gcloud 中設定人員管理帳戶

在下列範例中,將 $ADMIN_ACCOUNT 替換為您要使用的管理員帳戶 (例如:myaccount@gmail.com):

$ gcloud config set account $ADMIN_ACCOUNT

設定服務帳戶

根據預設,Cloud Run 服務或作業會以 Compute Engine 預設服務帳戶執行。建議您不要使用預設身分,而是為每個 Cloud Run 服務指派由使用者管理的服務帳戶,並授予最低必要權限,藉此為服務提供專屬身分。如要保留預設服務帳戶,請直接跳到設定環境變數

為每個 Cloud Run 執行階段建立兩個服務帳戶

  1. 如要建立服務帳戶,請視需要替換 $CONNECTOR_SERVICE_ACCOUNT_ID$INTERCEPTOR_SERVICE_ACCOUNT_ID 的值,然後執行下列指令:

    $ export CONNECTOR_SERVICE_ACCOUNT_ID='aa-ui-connector' && gcloud iam service-accounts create $CONNECTOR_SERVICE_ACCOUNT_ID \
    --description='Agent Assist integration - UI connector service account' \
    --display-name='Agent Assist integration - UI connector'
    $ export INTERCEPTOR_SERVICE_ACCOUNT_ID='aa-pubsub-interceptor' && gcloud iam service-accounts create $INTERCEPTOR_SERVICE_ACCOUNT_ID \
    --description='Agent Assist integration - Pubsub interceptor service account' \
    --display-name='Agent Assist integration - Pubsub interceptor'
  2. 使用下列範例指令,將下列角色指派給 UI 連接器和 Cloud Pub/Sub 連接器服務帳戶:

    $ gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
    --member='serviceAccount:$CONNECTOR_SERVICE_ACCOUNT_ID@$GCP_PROJECT_ID.iam.gserviceaccount.com' \
    --role='roles/pubsub.editor'

將下列 IAM 角色授予 UI 連接器服務帳戶:

  • roles/redis.editor
  • roles/vpcaccess.user
  • roles/compute.viewer
  • roles/secretmanager.secretAccessor
  • roles/dialogflow.agentAssistClient

將下列角色授予 Cloud Pub/Sub 連接器服務帳戶:

  • roles/redis.editor
  • roles/vpcaccess.user
  • roles/compute.viewer

設定環境變數

將下列環境變數的值設為您剛建立的服務帳戶,或是專案中的預設 Compute Engine 服務帳戶

  1. CONNECTOR_SERVICE_ACCOUNT:UI 連接器執行階段的服務帳戶。範例:aa-ui-connector@my-project-id.iam.gserviceaccount.com
  2. INTERCEPTOR_SERVICE_ACCOUNT:Cloud Pub/Sub Interceptor 執行階段的服務帳戶。範例:aa-pubsub-interceptor@my-project-id.iam.gserviceaccount.com

自訂使用者驗證方法

程式碼存放區支援後端使用者,以及 Genesys Cloud 和 Twilio 的前端模組使用者。

  1. 在程式碼存放區中,開啟 ui_connector/auth.py 檔案。
  2. 設定環境變數 AUTH_OPTION 來指定支援的識別資訊提供者,或使用 auth.check_auth 實作驗證方法。

    根據預設,AUTH_OPTION 為空白,且不允許任何使用者透過 UI 連接器服務註冊 JWT。 支援的值:

    • Salesforce:使用 Salesforce OpenID Connect 驗證授權權杖。必要環境變數:SALESFORCE_ORGANIZATION_ID。
    • SalesforceLWC:使用 oauth2/userinfo REST 端點驗證 Salesforce OAuth 用戶端憑證授權權杖。必要環境變數:SALESFORCE_ORGANIZATION_ID、SALESFORCE_DOMAIN。
    • GenesysCloud:使用 Genesys SDK UsersAPI 驗證授權權杖。
    • Twilio:驗證 Twilio 的驗證權杖。必要環境變數:TWILIO_FLEX_ENVIRONMENT。
    • Skip:略過驗證授權權杖。不應在正式環境中使用。

    範例:

    $ export AUTH_OPTION='Salesforce'

    每種權杖類型的驗證方式可能不同。權杖的驗證方式由您決定。如果沒有任何變更,auth.check_auth 會為每個要求傳回 false

如要限制可存取服務的來源,請變更 config.CORS_ALLOWED_ORIGINS 變數的值。預設值 * 可讓任何來源造訪您的服務。

產生及儲存 JWT 密鑰

為確保 UI 連接器服務能將安全驗證權杖傳回給用戶端,必須使用 JWT 私密金鑰加密權杖。金鑰值可以是任意字串,但應不得重複且難以猜測。

這組私密金鑰會儲存在 Secret Manager

設定環境變數

  • JWT_SECRET_NAME:Secret Manager 中的密鑰名稱。可以是任意名稱。建議值:aa-integration-jwt-secret

產生金鑰

建議您產生隨機雜湊做為 JWT 密鑰,以免攻擊者猜到密鑰。如要這麼做,可以使用 python secrets 為其產生安全的隨機數字。

# generate_secret_key.py
import secrets
jwt_secret_key = secrets.token_bytes(16)
print(jwt_secret_key) # Output example: b'L\x9b\xd6i4\xc3\x1d\x95\xe3\xf78z\xdda\x97\xec'

將金鑰儲存在 Secret Manager

在下列範例指令中,將 my_key 替換為您打算使用的密鑰。

$ python generate_secret_key.py | gcloud secrets create $JWT_SECRET_NAME --data-file=- \
--replication-policy=user-managed --locations=$SERVICE_REGION

設定 Memorystore for Redis

如要設定 Redis,您需要下列環境變數:

  • VPC_CONNECTOR_NAME無伺服器虛擬私有雲存取連接器的名稱,用於將 Cloud Run 服務連線至 Memorystore for Redis。建議值:aa-integration-vpc
  • VPC_NETWORK:要附加無伺服器虛擬私有雲存取連接器的虛擬私有雲網路。如果沒有為 Google Cloud 專案設定 VPC,值應為 default
  • VPC_SUBNET:Redis 執行個體所連結的授權 VPC 網路名稱。如果尚未自訂虛擬私有雲網路設定,值應為 default
  • REDIS_IP_RANGE:無伺服器虛擬私有雲存取連接器的未保留內部 IP 網路。必須有 /28 的未分配空間。建議值: 10.8.0.0/28 (這個值應適用於大多數新專案)。
  • REDIS_INSTANCE_ID:Redis 執行個體的名稱。建議值: aa-integration-redis

在 Cloud Run 服務的所在區域中建立 Redis 執行個體

執行下列指令:

$ gcloud redis instances create $REDIS_INSTANCE_ID --size=5 --region=$SERVICE_REGION

您可以透過直接輸出或無伺服器虛擬私有雲存取,從 Cloud Run 連線至 Redis 執行個體。

建立無伺服器虛擬私有雲存取連接器 {:#create-svpca-connector} (選用)

如果客戶選擇直接輸出,這項設定現在為選用項目。如果選擇無伺服器虛擬私有雲存取,您需要建立無伺服器虛擬私有雲存取連接器。如要進一步瞭解這個步驟,請參閱 Cloud Run 教學課程

確認專案已啟用 Serverless VPC Access API:

$ gcloud services enable vpcaccess.googleapis.com

使用自訂 IP 範圍建立無伺服器虛擬私有雲存取連接器:

$ gcloud compute networks vpc-access connectors create $VPC_CONNECTOR_NAME \
  --network $VPC_NETWORK \
  --region $SERVICE_REGION \
  --range $REDIS_IP_RANGE

將 Redis 主機和 Redis 連接埠儲存為環境變數

  • 將 Redis 執行個體的 IP 位址設為環境變數 REDIS_HOST
  • 將 Redis 執行個體的通訊埠號碼設為環境變數 REDIS_PORT

部署 UI 連接器服務

UI 連接器服務需要下列環境變數:

  • CONNECTOR_SERVICE_NAME:UI 連接器的 Cloud Run 服務名稱。 建議值:ui-connector
  • CONNECTOR_IMAGE_NAME:UI 連接器服務的映像檔名稱。可以與 CONNECTOR_SERVICE_NAME 相同。建議值:ui-connector

建構 Docker 映像檔

/ui-connector 資料夾下執行下列指令:

$ gcloud builds submit --tag gcr.io/$GCP_PROJECT_ID/$CONNECTOR_IMAGE_NAME

將 UI 連接器部署至 Cloud Run

/ui-connector 資料夾中,執行下列指令:

  • 如果使用直接輸出連線來連線至 Redis。
$ gcloud run deploy $CONNECTOR_IMAGE_NAME \
--image gcr.io/$GCP_PROJECT_ID/$CONNECTOR_IMAGE_NAME \
--platform managed \
--service-account=$CONNECTOR_SERVICE_ACCOUNT_NAME \
--allow-unauthenticated \
--timeout 3600 \
--region $SERVICE_REGION \
--network $VPC_NETWORK \
--subnet $VPC_SUBNET \
--clear-vpc-connector \
--min-instances=1 \
--set-env-vars REDISHOST=$REDIS_HOST,REDISPORT=$REDIS_PORT,GCP_PROJECT_ID=$GCP_PROJECT_ID,AUTH_OPTION=$AUTH_OPTION \
--update-secrets=/secret/jwt_secret_key=${JWT_SECRET_NAME}:latest
  • 如果使用已建立的 Serverless VPC Access 連接器進行 Redis 連線。
$ gcloud run deploy $CONNECTOR_IMAGE_NAME \
--image gcr.io/$GCP_PROJECT_ID/$CONNECTOR_IMAGE_NAME \
--platform managed \
--service-account=$CONNECTOR_SERVICE_ACCOUNT_NAME \
--allow-unauthenticated \
--timeout 3600 \
--region $SERVICE_REGION \
--vpc-connector $VPC_CONNECTOR_NAME \
--clear-network \
--min-instances=1 \
--no-cpu-throttling \
--set-env-vars REDISHOST=$REDIS_HOST,REDISPORT=$REDIS_PORT,GCP_PROJECT_ID=$GCP_PROJECT_ID,AUTH_OPTION=$AUTH_OPTION \
--update-secrets=/secret/jwt_secret_key=${JWT_SECRET_NAME}:latest

記下已部署 UI 連接器的服務網址,用戶端 (服務專員桌面) 會使用這個網址。

部署 Cloud Pub/Sub 攔截器服務

Pub/Sub 攔截器服務需要下列環境變數:

  • INTERCEPTOR_SERVICE_NAME:Cloud Pub/Sub 攔截器的 Cloud Run 服務名稱。建議值:cloud-pubsub-interceptor
  • INTERCEPTOR_IMAGE_NAME:Cloud Pub/Sub 攔截器服務的映像檔名稱。可以與 INTERCEPTOR_SERVICE_NAME 相同。建議值:cloud-pubsub-interceptor
  • INTERCEPTOR_SERVICE_ACCOUNT_NAME:Cloud Pub/Sub 攔截器執行階段的服務帳戶。

建構 Docker 映像檔

/cloud-pubsub-interceptor 資料夾下執行下列指令:

$ gcloud builds submit --tag gcr.io/$GCP_PROJECT_ID/$INTERCEPTOR_IMAGE_NAME

將 Pub/Sub 攔截器部署至 Cloud Run

/cloud-pubsub-interceptor 資料夾下執行下列指令:

  • 如果使用直接輸出連線來連線至 Redis。
$ gcloud run deploy $INTERCEPTOR_SERVICE_NAME \
--image gcr.io/$GCP_PROJECT_ID/$INTERCEPTOR_IMAGE_NAME \
--platform managed \
--service-account=$INTERCEPTOR_SERVICE_ACCOUNT_NAME \
--region $SERVICE_REGION \
--network $VPC_NETWORK \
--subnet $VPC_SUBNET \
--clear-vpc-connector \
--ingress=internal \
--min-instances=1 \
--no-cpu-throttling \
# You can also add LOGGING_FILE here to specify the logging file path on Cloud Run.
--set-env-vars REDISHOST=$REDIS_HOST,REDISPORT=$REDIS_PORT
  • 如果使用已建立的 Serverless VPC Access 連接器進行 Redis 連線。
$ gcloud run deploy $INTERCEPTOR_SERVICE_NAME \
--image gcr.io/$GCP_PROJECT_ID/$INTERCEPTOR_IMAGE_NAME \
--platform managed \
--service-account=$INTERCEPTOR_SERVICE_ACCOUNT_NAME \
--region $SERVICE_REGION \
--vpc-connector $VPC_CONNECTOR_NAME \
--clear-network \
--ingress=internal \
--min-instances=1 \
# You can also add LOGGING_FILE here to specify the logging file path on Cloud Run.
--set-env-vars REDISHOST=$REDIS_HOST,REDISPORT=$REDIS_PORT

儲存已部署的網址

將已部署的網址設為 INTERCEPTOR_SERVICE_URL 環境變數。

設定 Cloud Pub/Sub 訂閱項目

Cloud Pub/Sub 訂閱項目會使用下列項目:

  • 主題
  • 對話設定檔
  • 服務帳戶
  • 攔截器服務的服務帳戶權限

建立 Cloud Pub/Sub 主題

針對您需要 Dialogflow 提供的每種事件通知,建立 Cloud Pub/Sub 主題。可用的事件通知類型如下:

  • 新建議事件:有新的 Agent Assist 建議時傳送的事件 (例如,回應顧客話語的新智慧回覆建議)。
  • 新訊息事件:每當系統辨識出服務專員或顧客的新語音內容時,就會傳送事件 (例如顧客說「Hi」)。
  • 新的對話生命週期事件:針對特定對話生命週期變更傳送的事件 (例如對話開始或結束時)。
  • 新的辨識結果通知事件:當系統從服務專員或顧客辨識出中間轉錄稿時,就會傳送事件 (例如,顧客說「Hi, how can I help you?」,系統會在顧客說話時轉錄出「Hi how can」)。

記下主題 ID 和主題名稱,以供後續部署後端時使用。

設定對話設定檔

設定對話設定檔,並使用上一個步驟中建立的 Cloud Pub/Sub 主題。

  • 建立新的對話設定檔時,請選取「Pub/Sub notifications」(Pub/Sub 通知),然後選取「Enable Pub/Sub notifications」(啟用 Pub/Sub 通知)。啟用後,您可以勾選要啟用的通知類型旁邊的方塊,並輸入通知相關聯的 Cloud Pub/Sub 主題 ID。
  • 為每個主題選取 JSON 做為訊息格式。

為 Pub/Sub 訂閱身分建立服務帳戶

使用下列指令建立服務帳戶,代表 Pub/Sub 訂閱身分:

$ gcloud iam service-accounts create cloud-run-pubsub-invoker \
     --display-name "Cloud Run Pub/Sub Invoker"

授予服務帳戶叫用攔截器服務的權限

執行下列指令:

$ gcloud run services add-iam-policy-binding $INTERCEPTOR_SERVICE_NAME \ 
  --member=serviceAccount:cloud-run-pubsub-invoker@$GCP_PROJECT_ID.iam.gserviceaccount.com \
   --role=roles/run.invoker

為主題建立 Cloud Pub/Sub 訂閱項目

您必須為建立的每個主題建立對應的 Cloud Pub/Sub 訂閱項目。

新的建議事件

your-new-suggestion-topic-id 替換為您為新建議設定的 Cloud Pub/Sub 主題:

$ export TOPIC_ID='your-new-suggestion-topic-id' && gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_ID \
   --push-endpoint=$INTERCEPTOR_SERVICE_URL/human-agent-assistant-event \
   --push-auth-service-account=cloud-run-pubsub-invoker@$GCP_PROJECT_ID.iam.gserviceaccount.com
新訊息事件

your-new-message-event-topic-id 換成您為新訊息事件設定的 Cloud Pub/Sub 主題:

$ export TOPIC_ID='your-new-message-event-topic-id' && gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_ID \
   --push-endpoint=$INTERCEPTOR_SERVICE_URL/new-message-event \
   --push-auth-service-account=cloud-run-pubsub-invoker@$GCP_PROJECT_ID.iam.gserviceaccount.com
對話生命週期事件

your-conversation-lifecycle-event-topic 替換為您為新對話生命週期事件設定的 Cloud Pub/Sub 主題:

$ export TOPIC_ID='your-conversation-lifecycle-event-topic' && gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_ID \
   --push-endpoint=$INTERCEPTOR_SERVICE_URL/conversation-lifecycle-event \
   --push-auth-service-account=cloud-run-pubsub-invoker@$GCP_PROJECT_ID.iam.gserviceaccount.com
新的辨識結果通知事件
$ export TOPIC_ID='your-new-recognition-result-notification-event-topic' && gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_ID \
   --push-endpoint=$INTERCEPTOR_SERVICE_URL/new-recognition-result-notification-event \
   --push-auth-service-account=cloud-run-pubsub-invoker@$GCP_PROJECT_ID.iam.gserviceaccount.com