Dialogflow图书馆订房意图:基于Node.js Webhook调用API校验时间并重提示
Dialogflow 会议室预订意图:Node.js Webhook 调用API校验可用时间实现方案
针对你的需求,以下是基于Node.js Webhook的具体实现步骤,核心是通过上下文存储可用时间,在参数收集过程中调用API并校验时间有效性:
1. Dialogflow 意图与参数配置
- 创建「会议室预订」意图,添加训练短语(例:“我要预订会议室”“预订3号房间明天下午的会议”)
- 添加必填参数:
roomNumber:绑定@sys.number或自定义房间号实体,标记为必填bookingTime:绑定@sys.time,标记为必填bookingDate:绑定@sys.date,标记为必填userEmail:绑定@sys.email,标记为必填
- 开启意图的Webhook调用:在「Fulfillment」标签下,勾选「Enable webhook call for this intent」和「Enable webhook call for slot filling」,确保参数收集过程中触发Webhook。
2. Node.js Webhook 代码实现
先安装依赖:
npm install dialogflow-fulfillment express axios
编写Webhook服务代码,实现API调用、时间校验和参数重新收集逻辑:
const express = require('express'); const { WebhookClient } = require('dialogflow-fulfillment'); const axios = require('axios'); const app = express(); app.use(express.json()); // 替换为你的可用时间查询API地址 async function fetchAvailableTimes(roomNumber) { try { const res = await axios.get(`https://your-api-domain.com/rooms/${roomNumber}/available`); // 假设API返回格式:{ availableTimes: ["14:00", "15:00", "16:00"] } return res.data.availableTimes; } catch (err) { console.error('查询可用时间失败:', err); return []; } } app.post('/webhook', (req, res) => { const agent = new WebhookClient({ request: req, response: res }); // 处理房间号收集完成后的API调用 async function processRoomSelection(agent) { const roomNum = agent.parameters.roomNumber; const availableTimes = await fetchAvailableTimes(roomNum); if (availableTimes.length === 0) { agent.add(`抱歉,${roomNum}号房间目前无可用时段,请更换房间或稍后尝试。`); agent.parameters.roomNumber = ''; return; } // 将可用时间存入上下文,用于后续校验 agent.setContext({ name: 'room_availability', lifespan: 5, parameters: { times: availableTimes.join(', ') } }); agent.add(`已确认${roomNum}号房间的可用时段:${availableTimes.join('、')}。请告知预订时间。`); } // 校验用户输入的时间是否可用 async function validateTimeSlot(agent) { const selectedTime = agent.parameters.bookingTime; const availabilityCtx = agent.getContext('room_availability'); if (!availabilityCtx) { agent.add('请先告知要预订的房间号。'); agent.parameters.bookingTime = ''; return; } const availableTimes = availabilityCtx.parameters.times.split(', '); // 统一时间格式:提取Dialog返回时间的HH:mm部分 const formattedTime = selectedTime.slice(0, 5); if (!availableTimes.includes(formattedTime)) { agent.add(`抱歉,${formattedTime}时段已被预订。当前可用时段为:${availableTimes.join('、')},请重新选择。`); agent.parameters.bookingTime = ''; // 维持上下文,保留房间号信息 agent.setContext({ name: 'room_availability', lifespan: 5 }); // 指定重新收集bookingTime参数 agent.setAction('input.bookingTime'); return; } agent.add(`已确认${formattedTime}时段可用,请告知你的邮箱用于发送确认信息。`); } // 意图处理逻辑分发 const intentMap = new Map(); intentMap.set('会议室预订', async (agent) => { const { roomNumber, bookingTime, userEmail } = agent.parameters; const hasAvailabilityCtx = !!agent.getContext('room_availability'); if (roomNumber && !hasAvailabilityCtx) { // 刚收集到房间号,调用API获取可用时间 await processRoomSelection(agent); } else if (bookingTime) { // 已收集到时间,校验有效性 await validateTimeSlot(agent); } else if (userEmail) { // 所有参数收集完成,执行最终预订逻辑 const bookingDate = agent.parameters.bookingDate; // 此处调用预订API完成操作 agent.add(`已成功为你预订${roomNumber}号房间${bookingDate} ${bookingTime.slice(0,5)}的会议,确认邮件已发送至${userEmail}。`); } else { // 引导用户补全缺失参数 if (!roomNumber) agent.add('请问你要预订哪个房间?'); else if (!agent.parameters.bookingDate) agent.add('请问要预订哪一天的会议?'); } }); agent.handleRequest(intentMap); }); app.listen(3000, () => console.log('Webhook服务已启动,监听端口3000'));
3. 关键细节说明
- 上下文作用:通过
room_availability上下文存储房间可用时间,避免重复调用API,同时在时间校验时快速获取参考数据 - 时间格式统一:Dialogflow的
@sys.time返回ISO格式字符串,需与API返回的时间格式对齐(例:均转为HH:mm) - 参数重新收集:当时间不可用时,清空
bookingTime参数并设置action: 'input.bookingTime',触发Dialogflow重新询问时间 - 错误处理:API调用失败时,返回友好提示并重置房间号参数,引导用户重新选择
内容的提问来源于stack exchange,提问作者aayog koirala
相关产品推荐
相关产品推荐

