alexa-js / alexa-app

A framework for Alexa (Amazon Echo) apps using Node.js
https://www.youtube.com/watch?v=pzM4jv7k7Rg
MIT License
1.03k stars 212 forks source link

Calling another intent #335

Closed ololoepepe closed 6 years ago

ololoepepe commented 6 years ago

Is there a way to call another intent? Something like this.emit('OtherIntent'); in https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs.

I have to ask users to input data several times, and the number of slots may vary, so I can not just hardcode N slots in one intent. The data which users input is in free form, so it can not be hardcoded (e.g. as utterances for different intents) as well.

Example:

Iteration 1: Alexa: What food would you like to order? User: pizza Sets some internal state for the session, which indicates we are now on iteration 2. Launches the same intent again. Iteration 2: Alexa: What kind? User: pepperoni the options vary for different types of food Sets some internal state for the session, which indicates we are now on iteration 3. Launches the same intent again. Iteration 3: Alexa: What size? User: Big options here also vary ... And so on up to N iterations.

Chaining intents this way seems the only solution.

lazerwalker commented 6 years ago

app.intents is an object mapping from intent names to intent objects. So app.intents["someIntent"].handler(request, response) should be equivalent to having called someIntent directly (other than making sure request is in the correct state).

Alternatively, before registering your intents, you can store your handler functions in your own data structure and access them that way.

kobim commented 6 years ago

@ololoepepe it sounds like you should use dialogs for this use case (collecting user information).

As your first answer affects the rest of the flow, I'm guessing you should also take a look on how to update slot values during the dialog.

ololoepepe commented 6 years ago

@kobim It seems that one can only manage a fixed number of slots declared for the dialog. In my case, the number of slots may vary, so I'll have to define a dialog with a number of slots big enough to satisfy every possible case. And I'll have to mark extra slots as optional dynamically, if not needed. That does not look like an elegant solution.

ololoepepe commented 6 years ago

@lazerwalker So, if I understand you correctly, you suggest something like:

function handler(req, res) {
  // Do something
  handler(req, res); // Calling the same handler
  // Do something else
}

app.intent('SomeIntent', {
  utterances: [/*...*/],
  slots: {/**/}
}, handler);

Am I right? Will this work? How will I receive new data from Alexa this way?

ololoepepe commented 6 years ago

That is not the answer for this question, but for my case the solution was lying in a different plane: one can just add an intent with some custom (or built-in) slot (e.g. AMAZON.Food), make it the only utterance ({slotName}), and all user queries that do not match any other intent, will go to this one, while this intent is the last intent that was added to the skill.

lazerwalker commented 6 years ago

Sounds like you got this sorted out, so I'm going to close this for now. Feel free to re-open, or open a new issue if something else comes up!