如何根据用户选择的内容建立建议的订单?

时间:2019-02-03 22:46:07

标签: node.js dialogflow actions-on-google

我正在构建一个将执行基本交易功能的AOG(Google行动)项目。由于我对AOG还是有点陌生​​,所以我完全停留在如何接受用户选择的内容(无论是轮播还是基本的卡片等)上,并将他们选择的参数值/密钥传递到建议中订单或订单预览完成交易之前。

基本上是我尝试过的(这不是实际的代码,因为它很长,但是仍然可以理解)

    app.intent('delivery_address_complete', (conv) => {
       const arg = conv.arguments.get('DELIVERY_ADDRESS_VALUE');
       if (arg.userDecision ==='ACCEPTED') {
           conv.ask('Ok, what would you like to order?');
           conv.ask(new Suggestions(intentSuggestions));
           conv.ask(new Carousel({
               items: {
              // Add the first item to the carousel
                  SELECTION_KEY_COFFEE: {
                      synonyms: [
                          'Coffee'
                      ],
                      title: 'Coffee',
                      description: 'Sweet cream and sugar coffee.',
                      image: new Image({
                          url: IMG_URL_COFFEE,
                          alt: 'Image alternate text',
                      }),
              },
         }));

     }
    });


    const yesOrno = [
    'Yes',
    'No'
    ];

    app.intent('actions.intent.OPTION', (conv ) => {
        conv.ask('Okay, are you ready to proceed?');
        conv.ask(new Suggestions(yesOrno));
      });


    app.intent('transaction_decision_action', (conv) => {
      const order = {
       id: UNIQUE_ORDER_ID,
       cart: {
          merchant: {
             id: 'coffee',
        name: 'Coffee Store',
         },
           lineItems: [
           {
              name: 'My Memoirs',
              id: 'coffee_1',
          price: {
            amount: {
                 currencyCode: 'USD',
                 nanos: 990000000,
                 units: 3,
            },
            type: 'ACTUAL',
          },
          quantity: 1,
          subLines: [
            {
              note: 'coffee',
            },
          ],
          type: 'REGULAR',
        },

       otherItems: [
      {
        name: 'Subtotal',
        id: 'subtotal',
        price: {
          amount: {
            currencyCode: 'USD',
            nanos: 220000000,
            units: 32,
          },
          type: 'ESTIMATE',
        },
        type: 'SUBTOTAL',
      },
      {
        name: 'Tax',
        id: 'tax',
        price: {
          amount: {
            currencyCode: 'USD',
            nanos: 780000000,
            units: 2,
          },
          type: 'ESTIMATE',
        },
        type: 'TAX',
      },
    ],
    totalPrice: {
      amount: {
        currencyCode: 'USD',
        nanos: 0,
        units: 35,
      },
      type: 'ESTIMATE',
    },
  };

请注意:这主要是伪代码,因此,如果发生诸如收费过高或价格不合理的事情,这不是我要解决的问题。

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

更具体地说:

  • 我可以创建所需的order对象,并且我知道如何将其作为ProposedOrder对象的一部分发送给Google(然后发送给用户),该对象成为{{ 1}}对象。 (上面的代码中的“ transaction_decision_action” Intent处理程序。)
  • 我不了解如何根据用户说的话或通过选择轮播或列出我已显示的项目来构建TransactionDecision。 (例如,我在上面的“ actions.intent.OPTION” Intent处理程序中做什么?)

编辑:这也可以消除任何混乱。这是我想要做的事情的视频表示(在下面的评论中提到):

  • youtube.com/watch?v=LlgMcJBnNN8从1:02到1:29我知道该怎么做,我很困惑(在视频示例中)他们如何能够添加“火鸡肉三明治”和“绿色奶昔”到轮播选择中的1:35 ish的订单预览

1 个答案:

答案 0 :(得分:1)

您想要做的就是Google所说的building the order。正如它在该链接上指出的那样

  

获得所需的用户信息后,您将建立一个“购物车”   组装”的经验,指导用户建立订单。每   动作可能与购物车的组装流程略有不同,因为   适合您的产品或服务。

     

您可以构建推车组装体验,使用户能够   通过简单的是或否问题重新订购他们最近的购买。   您还可以向用户展示顶部的轮播或列表卡   “精选”或“推荐”项目。我们建议使用rich responses   直观地展示用户的选项,同时设计   对话,以便用户可以仅使用他们的   声音。

     

有关如何构建高质量推车组件的更多信息   体验,请参阅Transactions Design Guidelines

因此,没有一种方法可以解决您的问题。但是,有一些技巧可以帮助您构建proposed order

管理订单

您需要做的最重要的事情是跟踪用户在订购过程中订购的所有商品。您可以通过多种方式存储此信息:

  • 在Dialogflow上下文中
  • 在用户会话存储区
  • 在会话的数据库或数据存储中

简而言之,您必须存储会话信息的任何当前方式。以下所有信息均假定您已选择执行此操作的方法。

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

在此示例中,我们将采用后一种方案(因为它更易于显示),并使用Google动作库将其存储在会话存储对象中。

因此对于初学者来说,当我们开始执行Action或知道要接受订单时,我们需要使用类似的东西初始化要订购的商品列表

conv.user.data.items = [];

现在我们有了初始项目列表,我们可以探索添加到此列表的不同方法。

添加项目:“我的常规”

对于某些类型的订单,用户可以说“我会照常”。在这种情况下,我们需要一个Intent来处理该短语(或处理对我们提示的“是”响应),以及一个Intent Handler来查找用户的常规订单并将其添加到商品中。也许是这样的:

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?" );
    });
});

从列表中添加项目

如果您已经向用户展示了可能的商品的轮播或列表,那么您的生活会更轻松一些(尽管您可能暂时不这样认为)。您确实需要设置一个处理actions_intent_OPTION事件的Dialogflow Intent(在这种情况下,我将其称为order.option)。

order.option Intent

在此处理程序中,我们假设您用于该选项的键也恰好是商品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

item Entity Type

然后是一个Intent,它捕获表示用户要求添加它们的短语(我将称其为order.name,并且用户必须包含一个itemName参数)。

[Intent[8]

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

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?" );
    });
});

完成订单构建

一旦您收集完他们想要的所有东西,您的Intent Handler就应该把订单放在一起,从我们一直放在的lineItems数组中组装conv.user.data.items的完整列表,计算税金,总计以及order的所有其他部分。

然后,我们需要通过发送包含proposedOrder参数中的订单的TransactionDecision对象来propose the order。聪明,不是吗?可能是这样的:

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,
  }));
});

我将大多数内容分解为一个函数,因为除了订单的格式(在示例中已说明)以外,没有其他具体说明。您可以按照自己的方式构建它。

结论

您需要做的许多事情实际上可以归结为

  • 收集用户想要订购的信息,主要存储这些商品的ID
  • 将此项目列表转换为完整的订单对象
  • 发送此订单以供用户查看