Search code examples
alexa-skills-kit

How to set Slot values dynamically in Alexa Skills?


I'm trying to make my own Alexa Skill, and i have an Intent which need two slots filled to return the response, the first slot is a DATE so with it i doesn't have any problem, the second it's a Name from a list, that name list is different for each user which will use my Skill so in my own server i have an API that for Authenticated user will return a list of "names" for now it's default for all for testing and the return value is a JSON formatted as per docs for entity with ID and values like this:

(This is live JSON returned from my API)

[
    {
        "type": "Dialog.UpdateDynamicEntities",
        "updateBehavior": "REPLACE",
        "types": [
            {
                "name": "PuntoVenditaType",
                "values": [
                    {
                        "id": "0",
                        "name": {
                            "value": "PC-STEVE"
                        }
                    },
                    {
                        "id": "1",
                        "name": {
                            "value": "GINESI - NUOVO"
                        }
                    },
                    {
                        "id": "4",
                        "name": {
                            "value": "IGOR"
                        }
                    },
                    {
                        "id": "10",
                        "name": {
                            "value": "TELEX - SELF"
                        }
                    }
                ]
            }
        ]
    }
]

Then here is my Intent which i delegate from the LaunchRequest:

const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
    },
    handle(handlerInput) {
        const speakOutput = 'XXX.';

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .addDelegateDirective({
                name: 'IncassoIntent',
                confirmationStatus: 'NONE',
                slots: {}
            })
            .getResponse();
    }
};

const IncassoIntent = {
  canHandle(handlerInput) {
    return (
      Alexa.getRequestType(handlerInput.requestEnvelope) === "IntentRequest"
      && Alexa.getIntentName(handlerInput.requestEnvelope) === "IncassoIntent"
    );
  },
  async handle(handlerInput) {
    const {requestEnvelope, responseBuilder} = handlerInput;
    const {intent} = requestEnvelope.request;
    console.log(intent)
    
    let speech = "XXX"
    
    const replaceEntityDirective = await getPuntiVendita();
    console.log(replaceEntityDirective)

    if (intent.confirmationStatus === 'CONFIRMED') {
        const date = Alexa.getSlotValue(requestEnvelope, 'date');
        const puntoVendita = Alexa.getSlotValue(requestEnvelope, 'puntoVendita');
        speech = handlerInput.t('XXX {{date}} XXX {{puntoVendita}} XXX', {date, puntoVendita})
    }else {
        const repeat = handlerInput.t('XXX?')
        responseBuilder.reprompt(repeat)
    }

    return handlerInput.responseBuilder
      .speak(speech)
      .addDirective(replaceEntityDirective)
      .getResponse();
  },
};

    function getPuntiVendita() {
      return new Promise(((resolve, reject) => {
        var options = {
            host: 'www.example.cloud',
            port: 443,
            path: '/api/alexa/negozi',
            method: 'GET',
        };
        const request = https.request(options, (response) => {
          let returnData = '';
          response.on('data', (chunk) => {
            returnData += chunk;
          });
    
          response.on('end', () => {
            resolve(JSON.parse(returnData));
          });
    
          response.on('error', (error) => {
              console.log(error)
              reject(error);
          });
        });
        request.end();
      }));
    }

So the tipoNegozio should accept ONLY the data returned from my API when asked to the user, but instead it accept any value...


Solution

  • You are looking for Dynamic Entities which are described here: https://developer.amazon.com/en-US/docs/alexa/custom-skills/use-dynamic-entities-for-customized-interactions.html

    If you are not using the Node or Java libs, you must specify the directive they discuss in the response model sent from some previous call. That is described here: https://developer.amazon.com/en-US/docs/alexa/custom-skills/request-and-response-json-reference.html