Search code examples
node.jsdialogflow-esactions-on-google

How to get data from other intent? (pass data for intents to other intents)


I'm making a actions on google project that will use basic functionality of remembering what the user says and using it for another intent.

So for example, this is what the conversation might look like:

1     User: Hello
2     Bot: Hey! What's your name?
3     User: Joel
4     Bot: Your name is Joel, is that correct?
5     User: Yes that is correct
6     Bot: Awesome, it's great to meet you Joel.

I know how to get the information initially, but I am having trouble with getting the information (the name 'Joel') passed to another intent that is used purely for confirmation.

Here is what I have:

app.intent('greeting', (conv, params) => {
  const context = conv.contexts.set('context');      // working good
  conv.ask(`I got ${params.name}, is that right?`);
});

app.intent('greeting_1', (conv,params) => {
  const context1 = conv.contexts.get('context');  //not working
  conv.ask(`Awesome, it's great to meet yoy ${params.name}`);
 });

If this helps, specifically the error I'm getting reads:

TypeError: Cannot read property 'userDecision' of undefined

How do I get this to work? I have a feeling I have to save the data in userStorage but I've only really had to do that is very basic cases so I'm not to familiar with that.

Thanks for the help!


Solution

  • First of all, hi!

    Your initial thought of storing the data in UserStorage might be correct depending on your use case. Let me elaborate:

    Two Ways of Saving Data with Actions On Google Node.JS Client Library

    Storing Data In A Conversation

    You can use conv.data.name = 'Joel' to save the data between the turns of a conversation. But this data won't be available the next time user comes back.

    Storing Data Permanently (As Long As The User Allows It)

    This is where userStorage comes into play. You can use conv.user.storage.name = 'Joel' to remember the user's name every time they come back. Keep in mind that this type of permanent storage may require consent from the user depending on where they live.

    Legal note: Obtaining consent prior to accessing userStorage. Some countries have regulations that require developers to obtain consent from the user before they can access, or save certain information (e.g. personal information) in the userStorage. If you operate in one of these countries and you want to access, or save such information in userStorage, you must use the Confirmation helper to ask consent to the user and obtain the consent before you can start storing such information in userStorage.

    You also need to explain the data you're saving in your Privacy Policy.

    As for you specific use case, storing data that won't change (i.e. name) in userStorage is a much better method. Since if you only save it for one conversation, you'll need to ask for permission again the next time.

    These should cover your basic needs of saving data on the platform. However, if you do need a more complex state management solution, you may want to check Dialogflow Contexts.


    EDIT: I overlooked that you were already using contexts. But the answer still stands, you don't need to use contexts if all you want to do is to save data during a conversation.

    But I think the reason you're having a problem is that you're not setting or getting the context parameters correctly. Take a look at the examples here and here:

    The context.set() method gets three parameters; name, lifespan and parameters. You're only passing the name of the context in your code.

    And, using only contexts.get() method isn't enough to read parameters of a context. You need to read them like this:

    app.intent('Tell Greeting', conv => {
      const context1 = conv.contexts.get('context1')
      const { color, num } = context1.parameters
    })
    

    But, I repeat my original point. You shouldn't make things so complicated for yourself if you don't really need to. Try using conv.data and conv.user.storage if possible.