Dialogflow Fulfillment 與 API 整合完整教學

Dialogflow Fulfillment 與 API 整合完整教學
靜態回覆只能做簡單的 FAQ 機器人。要讓機器人真正有用,必須連接後端系統:查訂單、查庫存、處理預約。
Dialogflow 透過 Fulfillment(Webhook)讓你的機器人能呼叫外部 API,實現動態回覆。這篇文章從零開始,教你開發 Webhook、部署到 Cloud Functions、整合第三方 API。
如果你還不熟悉 Dialogflow 基礎,建議先閱讀 Dialogflow 完整指南 和 Intent 與 Context 教學。
Fulfillment 基礎概念
什麼時候需要 Fulfillment
不需要 Fulfillment 的場景:
- 回答固定問題(營業時間、地址)
- 純粹的閒聊對話
- 提供靜態資訊
需要 Fulfillment 的場景:
- 查詢即時資訊(訂單狀態、庫存數量)
- 執行動作(建立訂單、預約)
- 根據條件動態回覆
- 連接外部系統(CRM、ERP)
Webhook 運作原理
使用者 → Dialogflow → Webhook → 你的後端 → Webhook → Dialogflow → 使用者
│ │ │ │ │ │ │
「查訂單」 意圖理解 呼叫API 查資料庫 回傳結果 組合回覆 「您的訂單...」
流程說明:
- Dialogflow 偵測到需要 Fulfillment 的 Intent
- 發送 HTTP POST 請求到你設定的 Webhook URL
- 你的 Webhook 處理請求,呼叫資料庫或 API
- 回傳結構化的 JSON 給 Dialogflow
- Dialogflow 把內容發送給使用者
ES vs CX Fulfillment 差異
| 差異 | ES | CX |
|---|---|---|
| Request 格式 | v2 API 格式 | v3 API 格式 |
| Response 格式 | fulfillmentText / messages | fulfillmentResponse |
| Context 處理 | outputContexts | sessionInfo.parameters |
| 觸發方式 | Intent 級別啟用 | Page/Route 級別啟用 |
| 官方 SDK | dialogflow-fulfillment | 無官方 SDK |
本文主要以 ES 為例,CX 的 Webhook 開發請參考 Dialogflow CX 教學。
插圖:Fulfillment 架構圖
場景描述: 一張架構圖展示 Fulfillment 的資料流。左側是使用者和 Dialogflow,中間是 Webhook 服務(Cloud Functions),右側是後端系統(資料庫、第三方 API)。箭頭標示 Request 和 Response 的方向和內容。
視覺重點:
- 主要內容清晰呈現
必須出現的元素:
- 依據描述中的關鍵元素
需要顯示的中文字: 無
顏色調性: 專業、清晰
避免元素: 抽象圖形、齒輪、發光特效
Slug:
dialogflow-fulfillment-architecture
建立 Webhook 服務
使用 Cloud Functions(推薦)
Google Cloud Functions 是最簡單的 Webhook 部署方式,免管伺服器、自動擴展。
Step 1:建立 Cloud Function
- 前往 Google Cloud Console
- 選擇你的專案(與 Dialogflow Agent 相同)
- 搜尋「Cloud Functions」並進入
- 點擊「Create Function」
基本設定:
- Function name:dialogflow-webhook
- Region:asia-east1(台灣)
- Trigger type:HTTPS
- Authentication:Allow unauthenticated invocations
Step 2:撰寫程式碼
選擇 Runtime:Node.js 20
package.json:
{
"name": "dialogflow-webhook",
"version": "1.0.0",
"dependencies": {
"dialogflow-fulfillment": "^0.6.1"
}
}
index.js:
const { WebhookClient } = require('dialogflow-fulfillment');
exports.dialogflowWebhook = (request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Intent: ' + agent.intent);
console.log('Parameters: ' + JSON.stringify(agent.parameters));
function welcome(agent) {
agent.add('歡迎使用我們的服務!請問有什麼可以幫您?');
}
function fallback(agent) {
agent.add('抱歉,我不太理解您的意思。');
}
function checkOrder(agent) {
const orderId = agent.parameters.order_id;
// 這裡呼叫你的訂單系統
agent.add(`訂單 ${orderId} 的狀態是:處理中,預計明天出貨。`);
}
const intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('check_order', checkOrder);
agent.handleRequest(intentMap);
};
Step 3:部署
- 點擊「Deploy」
- 等待部署完成(約 1-2 分鐘)
- 複製觸發 URL
Step 4:在 Dialogflow 設定
- 進入 Dialogflow Console
- 點擊左側「Fulfillment」
- 啟用「Webhook」
- 貼上 Cloud Functions 的 URL
- 點擊「Save」
Step 5:啟用 Intent 的 Fulfillment
- 進入需要 Fulfillment 的 Intent
- 滾動到最下方
- 展開「Fulfillment」區塊
- 勾選「Enable webhook call for this intent」
- 儲存
使用 Node.js + Express
如果你想在自己的伺服器部署:
const express = require('express');
const { WebhookClient } = require('dialogflow-fulfillment');
const app = express();
app.use(express.json());
app.post('/webhook', (req, res) => {
const agent = new WebhookClient({ request: req, response: res });
function handleIntent(agent) {
agent.add('這是自訂伺服器的回覆');
}
const intentMap = new Map();
intentMap.set('my_intent', handleIntent);
agent.handleRequest(intentMap);
});
app.listen(3000, () => {
console.log('Webhook server running on port 3000');
});
注意:自建伺服器需要:
- HTTPS(可用 ngrok 測試)
- 公開可存取的 URL
- 處理擴展性問題
使用 Python Flask
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
req = request.get_json()
intent_name = req['queryResult']['intent']['displayName']
parameters = req['queryResult']['parameters']
if intent_name == 'check_order':
order_id = parameters.get('order_id')
response_text = f'訂單 {order_id} 的狀態是:處理中'
else:
response_text = '收到您的訊息'
return jsonify({
'fulfillmentText': response_text
})
if __name__ == '__main__':
app.run(port=5000)
部署與 HTTPS 設定
本地測試用 ngrok:
# 安裝 ngrok
npm install -g ngrok
# 啟動本地伺服器
node server.js
# 另一個終端機
ngrok http 3000
# 複製 ngrok 給的 HTTPS URL,貼到 Dialogflow
正式部署選項:
- Google Cloud Functions(推薦)
- Google Cloud Run
- AWS Lambda
- Heroku
- 自建伺服器 + SSL 憑證
Dialogflow API 呼叫
除了被動接收 Webhook,你也可以主動呼叫 Dialogflow API。
DetectIntent API
DetectIntent API 讓你從自己的應用程式發送訊息給 Dialogflow。
使用場景:
- 自建聊天介面
- 整合到現有 App
- 批次測試對話
服務帳戶與驗證設定
Step 1:建立服務帳戶
- 前往 Google Cloud Console > IAM & Admin > Service Accounts
- 點擊「Create Service Account」
- 輸入名稱(如:dialogflow-client)
- 授予角色:「Dialogflow API Client」
- 建立金鑰(JSON 格式)
- 下載並安全保存金鑰檔案
Step 2:設定環境變數
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account-key.json"
範例程式碼
Node.js:
const dialogflow = require('@google-cloud/dialogflow');
const uuid = require('uuid');
async function detectIntent(projectId, text) {
const sessionId = uuid.v4();
const sessionClient = new dialogflow.SessionsClient();
const sessionPath = sessionClient.projectAgentSessionPath(projectId, sessionId);
const request = {
session: sessionPath,
queryInput: {
text: {
text: text,
languageCode: 'zh-TW',
},
},
};
const [response] = await sessionClient.detectIntent(request);
const result = response.queryResult;
console.log('Intent:', result.intent.displayName);
console.log('Response:', result.fulfillmentText);
return result;
}
// 使用範例
detectIntent('your-project-id', '我要訂位');
Python:
from google.cloud import dialogflow_v2 as dialogflow
import uuid
def detect_intent(project_id, text):
session_client = dialogflow.SessionsClient()
session_id = str(uuid.uuid4())
session = session_client.session_path(project_id, session_id)
text_input = dialogflow.TextInput(text=text, language_code='zh-TW')
query_input = dialogflow.QueryInput(text=text_input)
response = session_client.detect_intent(
request={'session': session, 'query_input': query_input}
)
result = response.query_result
print(f'Intent: {result.intent.display_name}')
print(f'Response: {result.fulfillment_text}')
return result
# 使用範例
detect_intent('your-project-id', '我要訂位')
插圖:DetectIntent API 流程圖
場景描述: 一張流程圖展示 DetectIntent API 的呼叫過程。從左到右:你的應用程式 → API Request(含 projectId、sessionId、text)→ Dialogflow → API Response(含 intent、fulfillmentText)→ 你的應用程式。
視覺重點:
- 主要內容清晰呈現
必須出現的元素:
- 依據描述中的關鍵元素
需要顯示的中文字: 無
顏色調性: 專業、清晰
避免元素: 抽象圖形、齒輪、發光特效
Slug:
dialogflow-detect-intent-api-flow
GitHub 範例專案
官方範例庫介紹
Google 提供官方範例程式碼:
Dialogflow ES:
Dialogflow CX:
社群推薦專案
| 專案 | 語言 | 功能 |
|---|---|---|
| dialogflow-fulfillment-nodejs | Node.js | 官方 Fulfillment 函式庫 |
| flask-dialogflow-webhook | Python | Flask Webhook 模板 |
| dialogflow-angular | TypeScript | Angular 整合範例 |
快速部署模板
一鍵部署到 Cloud Functions:
# 克隆範例專案
git clone https://github.com/your-repo/dialogflow-webhook-template.git
cd dialogflow-webhook-template
# 部署
gcloud functions deploy dialogflow-webhook \
--runtime nodejs20 \
--trigger-http \
--allow-unauthenticated \
--region asia-east1
進階整合
連接資料庫(Firestore / MySQL)
Firestore 範例:
const { Firestore } = require('@google-cloud/firestore');
const firestore = new Firestore();
async function checkOrder(agent) {
const orderId = agent.parameters.order_id;
const doc = await firestore.collection('orders').doc(orderId).get();
if (!doc.exists) {
agent.add('找不到這筆訂單,請確認訂單編號是否正確。');
return;
}
const order = doc.data();
agent.add(`訂單 ${orderId} 的狀態是:${order.status},預計 ${order.delivery_date} 送達。`);
}
MySQL 範例:
const mysql = require('mysql2/promise');
async function checkInventory(agent) {
const productName = agent.parameters.product;
const connection = await mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
const [rows] = await connection.execute(
'SELECT stock FROM products WHERE name = ?',
[productName]
);
if (rows.length > 0) {
agent.add(`${productName} 目前庫存 ${rows[0].stock} 件。`);
} else {
agent.add('找不到這個商品。');
}
await connection.end();
}
呼叫第三方 API
天氣 API 範例:
const axios = require('axios');
async function getWeather(agent) {
const city = agent.parameters['geo-city'];
try {
const response = await axios.get(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${process.env.WEATHER_API_KEY}&units=metric&lang=zh_tw`
);
const weather = response.data;
agent.add(`${city} 目前天氣:${weather.weather[0].description},氣溫 ${weather.main.temp}°C。`);
} catch (error) {
agent.add('抱歉,無法取得天氣資訊,請稍後再試。');
}
}
非同步處理與長時間任務
Dialogflow Webhook 有 5 秒的 timeout 限制。如果任務需要更久:
方法 1:快速回覆 + 後續通知
async function processLongTask(agent) {
const taskId = generateTaskId();
// 立即回覆
agent.add(`收到您的請求,處理中...我們會在完成後通知您(任務編號:${taskId})`);
// 非同步處理(不等待)
processTaskInBackground(taskId);
}
async function processTaskInBackground(taskId) {
// 執行長時間任務
const result = await someHeavyOperation();
// 完成後發送通知(透過 LINE Push、Email 等)
await sendNotification(taskId, result);
}
方法 2:使用 Cloud Tasks
把任務放入佇列,另一個服務處理:
const { CloudTasksClient } = require('@google-cloud/tasks');
async function queueTask(agent) {
const client = new CloudTasksClient();
const task = {
httpRequest: {
httpMethod: 'POST',
url: 'https://your-worker-service.com/process',
body: Buffer.from(JSON.stringify({ data: agent.parameters })).toString('base64'),
},
};
await client.createTask({ parent: queuePath, task });
agent.add('您的請求已加入處理佇列,稍後會通知您結果。');
}
錯誤處理與重試機制
async function robustApiCall(agent) {
const maxRetries = 3;
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
const result = await callExternalApi();
agent.add(`查詢結果:${result}`);
return;
} catch (error) {
lastError = error;
console.error(`Attempt ${i + 1} failed:`, error.message);
if (i < maxRetries - 1) {
await sleep(1000 * (i + 1)); // 指數退避
}
}
}
// 所有重試都失敗
console.error('All retries failed:', lastError);
agent.add('系統暫時忙碌,請稍後再試。如急需協助,請撥打客服專線。');
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
插圖:進階整合架構圖
場景描述: 一張複雜的架構圖展示進階整合。中央是 Cloud Functions,連接到:左邊的 Dialogflow、右上的資料庫(Firestore、MySQL)、右中的第三方 API(天氣、金流)、右下的訊息服務(LINE Push、Email)。每個連接標示資料流向。
視覺重點:
- 主要內容清晰呈現
必須出現的元素:
- 依據描述中的關鍵元素
需要顯示的中文字: 無
顏色調性: 專業、清晰
避免元素: 抽象圖形、齒輪、發光特效
Slug:
dialogflow-advanced-integration-architecture
整合做不出來?後端整合是技術門檻最高的部分,牽涉到資安、效能、錯誤處理。預約技術諮詢,讓有經驗的人幫你解決整合難題。
部署與維運
監控與日誌
Cloud Functions 日誌:
- 前往 Google Cloud Console > Cloud Functions
- 選擇你的 Function
- 點擊「Logs」分頁
設定告警:
- 前往 Cloud Monitoring
- 建立告警政策
- 設定條件:錯誤率 > 5%、延遲 > 2 秒
- 設定通知管道(Email、Slack)
效能優化
1. 減少冷啟動
// 在 Function 外初始化連線,避免每次都重新連
const firestore = new Firestore();
exports.webhook = async (req, res) => {
// 使用已建立的連線
const doc = await firestore.collection('orders').doc('123').get();
// ...
};
2. 使用快取
const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 300 }); // 5 分鐘快取
async function getData(key) {
let data = cache.get(key);
if (!data) {
data = await fetchFromDatabase(key);
cache.set(key, data);
}
return data;
}
3. 設定 minimum instances
避免冷啟動延遲:
gcloud functions deploy webhook \
--min-instances 1 \
--max-instances 10
安全性考量
1. 驗證請求來源
確認請求真的來自 Dialogflow:
// 檢查 User-Agent
if (!req.headers['user-agent'].includes('Google-Dialogflow')) {
return res.status(403).send('Forbidden');
}
2. 環境變數管理
敏感資訊不要寫在程式碼中:
// ❌ 不好
const apiKey = 'sk-xxxxx';
// ✓ 好
const apiKey = process.env.API_KEY;
3. 限制存取範圍
服務帳戶只給需要的權限,不要用 Owner 權限。
如果需要整合到行動 App,請參考 Dialogflow 行動開發整合教學。LINE Bot 整合請參考 Dialogflow LINE Bot 串接教學。
下一步
掌握 Fulfillment 開發後,你可以:
- 優化對話設計:Dialogflow Intent 與 Context 完整教學
- 學習 CX 版本:Dialogflow CX 教學:從入門到進階
- 整合 LINE Bot:Dialogflow LINE Bot 串接教學
- 行動 App 整合:Dialogflow 行動開發整合教學
後端整合需要協助?
好的後端架構能讓系統穩定、安全、易於擴展。不好的架構會在流量增加時出問題,或成為資安漏洞。
如果你需要:
- 設計可擴展的 Webhook 架構
- 整合複雜的企業系統
- 處理高流量場景
- 確保資安合規
預約架構諮詢,讓有經驗的工程師幫你設計穩健的後端架構。
諮詢完全免費,我們會在 24 小時內回覆。
相關文章
Dialogflow CX vs ES 完整比較:2026 版本選擇指南
Dialogflow CX 和 ES 到底差在哪?本文詳細比較功能、費用、適用場景,附決策流程圖,幫你選對版本不踩雷、不花冤枉錢。
DialogflowDialogflow 完整指南 2026:從入門到實戰的 AI 對話機器人開發
完整解析 Google Dialogflow CX 與 ES 版本差異、Generative AI Agents、Vertex AI 整合、費用計算、LINE Bot 整合教學。從零開始打造企業級 AI 客服機器人,含 2026 最新生成式 AI 功能與實戰範例。
DialogflowDialogflow Intent 與 Context 完整教學:打造聰明的多輪對話
深入解析 Dialogflow Intent 意圖設計、Context 上下文管理、Entity 實體擷取。學會設計多輪對話、條件式回應,打造真正聰明的 AI 機器人。