Search code examples
javascriptalexa-skills-kit

How would I ask the user for a list of names?


I'm creating a custom Alexa skill and it need to collect a unknown number of names that the user says.

I have tried to store the names in a slot. I was able to get one name to work this way but not multiple. Right now, I am trying to ask the user for a number of people and then ask the user the names. But, I can not figure out how to get that solution to work. Also, I am trying to store the names in the session attributes.

Here is a what I have so far

    // Api call wrapped into a promise. Returns the person's email.
    return findEmployee(sessionAttributes.client, givenName)
        .then(attendee => {
            let prompt = ''
            if (attendee.value.length === 1) {
            sessionAttributes.attendees = [...sessionAttributes.attendees, attendee.value[0]]
            prompt = `${attendee.value.displayName} added to the meeting.`
            return handlerInput.responseBuilder
                .speak(prompt)
                .reprompt(prompt)
                .getResponse()
            }
         })
         .catch(err => console.log(err))

This snippet works fine with one person but how would I refactor it so Alexa will ask until a end condition is reached.


Solution

  • After doing some research I figured out that the answer is actually simple. To collect my names I need to loop a intent until a certain condition is meet. I can do this by checking the state of my skill in the "canHandle" function and using an if statement in my response.

    Lets say that I have a slot called number that is set to a random number.

    const AddNameHandler = {
      canHandle (handlerInput) {
        const request = handlerInput.requestEnvelope.request
        const attributesManager = handlerInput.attributesManager
        const sessionAttributes = attributesManager.getSessionAttributes()
        const slots = request.intent.slots
    
        return handlerInput.requestEnvelope.request.type === 'IntentRequest' &&
          (sessionAttributes.names < slots.number)
    
      },
      handle (handlerInput) {
        const request = handlerInput.requestEnvelope.request
        const attributesManager = handlerInput.attributesManager
        const sessionAttributes = attributesManager.getSessionAttributes()
        const slots = request.intent.slots
        // Collect the name
        sessionAttributes.names += 1
        if (sessionAttributes.names !== slots.number) {
          handlerInput.responseBuilder
            .speak('Say another name.')
            .reprompt('Say another name')
            .getResponse()
        } else {
          handlerInput.responseBuilder
            .speak('Got the names.')
            .getResponse()
        }
      }
    }
    

    This example will collect a list of name and if I want to fire another handler upon reaching the limit of names, I would just need to create another handler with a new condition.