Node.js 如何使用用户选择的内容建立建议订单?

Node.js 如何使用用户选择的内容建立建议订单?,node.js,dialogflow-es,actions-on-google,Node.js,Dialogflow Es,Actions On Google,我正在构建一个AOG(谷歌操作)项目,它将实现基本的事务功能。因为我对AOG还是有点陌生,所以我完全无法理解如何在用户完成交易之前,将用户选择的内容(无论是转盘、基本卡等)传递到提议的订单或订单预览中 这是我基本上已经尝试过的(这不是实际的代码,因为它相当长,但它仍然能让人理解) 请注意:这大部分都是伪代码,所以如果发生了诸如过度收费或价格不合理之类的事情,这不是我试图解决的问题 如何获取用户从任何方法中选择的内容,并将其显示在订单预览或建议订单上?我不需要任何关于制作旋转木马或基本卡片等的帮助

我正在构建一个AOG(谷歌操作)项目,它将实现基本的事务功能。因为我对AOG还是有点陌生,所以我完全无法理解如何在用户完成交易之前,将用户选择的内容(无论是转盘、基本卡等)传递到提议的订单或订单预览中

这是我基本上已经尝试过的(这不是实际的代码,因为它相当长,但它仍然能让人理解)

请注意:这大部分都是伪代码,所以如果发生了诸如过度收费或价格不合理之类的事情,这不是我试图解决的问题

如何获取用户从任何方法中选择的内容,并将其显示在订单预览或建议订单上?我不需要任何关于制作旋转木马或基本卡片等的帮助。如何将所选信息发送到订单预览。

更具体地说:

  • 我可以创建一个所需的
    order
    对象,并且我知道如何将其发送给Google(然后发送给用户),作为
    ProposedOrder
    对象的一部分,该对象将成为
    TransactionDecision
    对象的一部分。(上面代码中的“事务\决策\操作”意图处理程序。)
  • 我不明白的是,如何根据用户所说的话,或者通过在旋转木马上选择或列出我显示给他们的项目来构建
    订单
    。(例如,在上面的“actions.intent.OPTION”意图处理程序中我该怎么做?)
编辑:这也可以消除任何混淆。这是我试图做的事情的视频演示(在下面的评论中提到):

  • 从1:02到1:29我知道该怎么做,我很困惑(在视频示例中)他们是如何在1:35从旋转木马选择中将“火鸡三明治”和“绿色冰沙”添加到订单预览的

    • 你想做的就是谷歌所说的。正如它在链接中所指出的那样

      一旦您获得了所需的用户信息,您将构建一个“购物车” 引导用户建立订单的“组装”体验。每一个 操作可能会有稍微不同的购物车装配流程,如下所示: 适合您的产品或服务

      您可以构建购物车组装体验,使用户能够 通过简单的“是”或“否”问题重新订购他们最近购买的产品。 您还可以向用户提供一个旋转木马或顶部列表卡 “特色”或“推荐”项目。我们建议使用 以直观的方式呈现用户的选项,同时设计 对话,以便用户仅使用自己的 声音

      有关如何构建高质量购物车部件的详细信息,请参见 经验,请参阅

      所以没有一种方法可以满足你的要求。然而,这里有一些技巧是你可以而且应该做的事情来构建这个系统

      管理订单

      你需要做的一件大事是在整个过程中跟踪用户订购的所有东西。您可以通过多种方式存储此信息:

      • 在对话流上下文中
      • 在用户会话存储中
      • 在会话的数据库或数据存储中
      简言之,任何当前存储会话信息的方法。下面的所有信息都假设您已经选择了某种方法来实现这一点

      由于所有内容都将成为
      行项目之一
      ,因此一个简单的解决方案是在进行过程中构建此数组,然后直接将数组复制到order对象中。另一种方法是只存储项目ID列表,然后在构建订单时填充其余信息

      对于本例,我们将使用后一种方案(因为它更容易显示),并使用google library上的操作将其存储在会话存储对象中

      因此,对于初学者来说,当我们开始操作时,或者当我们知道我们将接受订单时,我们需要使用以下内容初始化我们正在订购的项目列表

      conv.user.data.items = [];
      
      现在我们有了初始项目列表,我们可以探索添加到此列表的不同方式

      添加项目:“我的常规”

      对于某些类型的订单,用户可以说“我要我通常的”。在这种情况下,我们需要一个处理这个短语的意图(或者处理对提示的“是”响应),以及一个查找用户常规订单并将其添加到项目中的意图处理程序。也许是这样的:

      app.intent('order.usual', conv => {
        // Get their user profile from our database
        // The "loadUser" function is up to you, and has little to do with AoG
        return loadUser( conv )
          .then( user => {
            // Add each item in their usual order to the current items
            let usualOrder = user.usualOrder;
            usualOrder.forEach( item => conv.user.data.items.push( item ) );
      
            // Send a message back to the user
            conv.add( "You got it! Do you want anything else?" );
          });
      });
      
      app.intent('review', conv => {
        // Get the items the user has saved
        let items = conv.user.data.items;
      
        // Turn these into more complete lineItems
        // You will need to provide the "itemToLineItem" function
        let lineItems = items.map( itemToLineItem );
      
        // Get some other objects we need
        // You'll need to define these functions, too
        let orderId = generateOrderId();
        let subtotal = computeSubtotal( lineItems );
        let tax = computeTax( lineItems );
        let total = computerTotal( subtotal, tax );
      
        // Build the order object
        let order = buildOrder( lineItems, subtotal, tax, total );
      
        conv.ask(new TransactionDecision({
          orderOptions: {
            requestDeliveryAddress: false,
          },
          paymentOptions: {
            googleProvidedOptions: {
              prepaidCardDisallowed: false,
              supportedCardNetworks: ['VISA', 'AMEX'],
              // These will be provided by payment processor,
              // like Stripe, Braintree, or Vantiv.
              tokenizationParameters: {
                tokenizationType: 'PAYMENT_GATEWAY',
                parameters: {
                  'gateway': 'stripe',
                  'stripe:publishableKey': (conv.sandbox ? 'pk_test_key' : 'pk_live_key'),
                  'stripe:version': '2017-04-06'
                },
              },
            },
          },
          proposedOrder: order,
        }));
      });
      
      从列表中添加项目

      如果你已经向用户展示了一个旋转木马或一个可能物品的列表,那么你的生活就会轻松一点(尽管你现在可能并不这么认为)。您确实需要设置一个Dialogflow Intent来处理
      actions\u Intent\u选项
      事件(在本例中,我将调用
      order.OPTION

      在这个处理程序中,我们假设用于选项的键恰好也是项ID,因此您可以将其添加到列表中

      app.intent('order.option', (conv, params, option) => {
        // The item is the option sent
        let item = option;
      
        // Add the item to the list of items
        conv.user.data.items.push( item );
      
        // Send a message back to the user
        conv.add( "I've put that in your cart. Anything else?" );
      });
      
      按名称添加项目

      但是请记住,用户可以在任何时间向任何方向进行对话。因此,他们可能会要求您提供您当前未在传送带中显示的项目。处理此问题的最佳方法是在Dialogflow中创建一个实体类型(例如,我将其称为
      item

      然后是一个意图,它捕获了一些表达用户请求添加它们的短语(我称之为
      order.name
      ,它有一个用户必须包含的
      itemName
      参数)

      [

      在处理程序中,您需要获取他们所说的名称,查找项目是什么,并将其添加到他们已订购的项目列表中

      app.intent('order.name', (conv, params) => {
        // Get the name
        let itemName = params['itemName'];
      
        // Look it up to find out what they ordered
        // You need to implement the itemFromName function
        return itemFromName( itemName )
          .then( item => {
            // Add the item
            conv.user.data.items.push( item );
      
            // And reply
            conv.add( "You got it! Anything else?" );
          });
      });
      
      完成订单的构建

      app.intent('review', conv => { // Get the items the user has saved let items = conv.user.data.items; // Turn these into more complete lineItems // You will need to provide the "itemToLineItem" function let lineItems = items.map( itemToLineItem ); // Get some other objects we need // You'll need to define these functions, too let orderId = generateOrderId(); let subtotal = computeSubtotal( lineItems ); let tax = computeTax( lineItems ); let total = computerTotal( subtotal, tax ); // Build the order object let order = buildOrder( lineItems, subtotal, tax, total ); conv.ask(new TransactionDecision({ orderOptions: { requestDeliveryAddress: false, }, paymentOptions: { googleProvidedOptions: { prepaidCardDisallowed: false, supportedCardNetworks: ['VISA', 'AMEX'], // These will be provided by payment processor, // like Stripe, Braintree, or Vantiv. tokenizationParameters: { tokenizationType: 'PAYMENT_GATEWAY', parameters: { 'gateway': 'stripe', 'stripe:publishableKey': (conv.sandbox ? 'pk_test_key' : 'pk_live_key'), 'stripe:version': '2017-04-06' }, }, }, }, proposedOrder: order, })); });