You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于NodeJS实现Actions on Google的数据库与用户实体(会话)方案咨询

实现方案:存储用户设备数据并返回给Actions on Google

我来帮你一步步搞定这个需求,结合你现有的Dialogflow代码,咱们分核心模块来落地:

1. 先搞定数据库设计(适配你的Firebase环境)

因为你用了firebase-functions,直接用Firebase Firestore最顺手。咱们给每个用户单独存设备列表,用AoG提供的用户唯一ID做标识:

// Firestore文档结构示例
users/{userId} = {
  devices: [
    { name: "客厅吸顶灯", type: "light" },
    { name: "主卧空调", type: "aircon" }
  ]
}

2. 把数据库集成到现有代码里

首先在代码顶部引入并初始化Firebase Admin SDK(因为是firebase函数,默认已经集成,直接用就行):

const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();

3. 获取用户设备并传给AoG让NLB识别

这里分两种核心场景:一是给用户展示设备建议,二是让Dialogflow自动识别用户说的设备名,咱们都给你安排上:

场景一:获取设备并给用户展示建议

新增或者修改一个Intent(比如欢迎Intent),用来拉取用户设备并返回:

// 新增欢迎Intent的处理逻辑(替换你现有类似逻辑也可以)
app.intent('Default Welcome Intent', async (conv) => {
  // 获取AoG提供的用户唯一标识
  const userId = conv.user.id;
  
  // 从Firestore拉取用户设备数据
  const userDoc = await db.collection('users').doc(userId).get();
  let devices = [];
  if (userDoc.exists) {
    devices = userDoc.data().devices || [];
  } else {
    // 新用户初始化空设备列表
    await db.collection('users').doc(userId).set({ devices: [] });
  }

  const deviceNames = devices.map(device => device.name);
  
  if (deviceNames.length === 0) {
    conv.ask('还没找到你的设备哦,你可以先添加设备~');
    return;
  }

  // 把设备列表存入上下文,方便后续Intent调用
  conv.contexts.set('user_devices', Lifespans.DEFAULT, { deviceNames });

  // 回复用户同时给出设备建议
  conv.ask(`我找到你的设备有:${deviceNames.join('、')},你想控制哪个呢?`);
  conv.ask(new Suggestions(deviceNames));
});

场景二:让NLB自动识别设备名(动态实体)

如果要让Dialogflow的NLB引擎直接识别用户说的设备(比如用户说“打开客厅灯”,自动把“客厅灯”识别成设备参数),可以用动态实体功能:

app.intent('Default Welcome Intent', async (conv) => {
  const userId = conv.user.id;
  const userDoc = await db.collection('users').doc(userId).get();
  const devices = userDoc.exists ? userDoc.data().devices || [] : [];
  const deviceNames = devices.map(device => device.name);

  // 设置动态实体,让Dialogflow能识别这些设备名
  if (deviceNames.length > 0) {
    conv.intentManager.setEntities({
      'device_name': deviceNames.map(name => ({
        value: name,
        synonyms: [name] // 有设备别名的话可以加在这里,比如"客厅灯"的别名"厅灯"
      }))
    });
  }

  // 后续回复逻辑和上面一样
  conv.ask(`我找到你的设备有:${deviceNames.join('、')},你想控制哪个呢?`);
  conv.ask(new Suggestions(deviceNames));
});

⚠️ 注意:要先在Dialogflow控制台创建一个名为device_name的动态实体,这样代码才能动态更新它的内容。

4. 可选:添加设备的逻辑

如果要支持用户新增设备,加个Intent处理就行:

app.intent('add_device', async (conv, { device_name, device_type }) => {
  const userId = conv.user.id;
  const userDoc = db.collection('users').doc(userId);
  
  // 把新设备追加到用户的设备列表里
  await userDoc.update({
    devices: admin.firestore.FieldValue.arrayUnion({
      name: device_name,
      type: device_type || 'unknown'
    })
  });

  conv.ask(`已添加设备${device_name},现在你可以直接控制它啦~`);
});

关键注意点

  • 配置Firestore安全规则,确保用户只能访问自己的设备数据:
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth.uid == userId;
    }
  }
}
  • 如果用conv.user.id,需要在Dialogflow控制台的「集成→Actions on Google」里开启用户身份验证;如果不需要登录,也可以用conv.user.storage存储匿名用户的设备数据。

内容的提问来源于stack exchange,提问作者aarontzk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:51:36