Search code examples
node.jsalexa-skills-kit

Alexa, taking notes and send them via mail


I'd like to learn to write Alexa Skills, so I thought a Skill, that records the users speech and writes it down, to send it to him via mail later, would be pretty cool.

I managed to let the user Start the Skill but I have no idea how to save the "notes" of the user. I havent found anything on google, so I tried to ask here.


Solution

  • I managed to realize my problem. Here is my solution: Intent (Utterances are in German, but the Slot {NoteInput} is important)

    {
    "interactionModel": {
        "languageModel": {
            "invocationName": "mail notes",
            "intents": [
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                },
                {
                    "name": "noteIntent",
                    "slots": [
                        {
                            "name": "NoteInput",
                            "type": "AMAZON.SearchQuery",
                            "samples": [
                                "notiere {NoteInput}",
                                "{NoteInput}"
                            ]
                        }
                    ],
                    "samples": [
                        "und schreibe auf {NoteInput}",
                        "und notiere {NoteInput}",
                        "notiere {NoteInput}",
                        "sende mir folgendes",
                        "und schreib auf",
                        "und notiere",
                        "notiere",
                        "und schreib mit",
                        "schreib mit",
                        "schreib auf"
                    ]
                }
            ]
        },
        "dialog": {
            "intents": [
                {
                    "name": "noteIntent",
                    "confirmationRequired": false,
                    "prompts": {},
                    "slots": [
                        {
                            "name": "NoteInput",
                            "type": "AMAZON.SearchQuery",
                            "confirmationRequired": false,
                            "elicitationRequired": true,
                            "prompts": {
                                "elicitation": "Elicit.Slot.61384016725.485372519591"
                            }
                        }
                    ]
                }
            ]
        },
        "prompts": [
            {
                "id": "Elicit.Slot.61384016725.485372519591",
                "variations": [
                    {
                        "type": "PlainText",
                        "value": "Sehr wohl, ich trage zu protokoll"
                    },
                    {
                        "type": "PlainText",
                        "value": "Gerne, ich notiere"
                    },
                    {
                        "type": "PlainText",
                        "value": "Sehr wohl, ich notiere"
                    },
                    {
                        "type": "PlainText",
                        "value": "Gerne, ich schreibe mit"
                    }
                ]
            }
    }
    

    }

    As you can see the Slot {NoteInput} got AMAZON.SearchQuery as Slottype. This will cause Alexa to simply transfer Speech-to-Text.

    The Handler in the Lambda-Function looks like this:

     const inProgressNoteIntentHandler = {
       canHandle(handlerInput) {
         const request = handlerInput.requestEnvelope.request;
        return request.type === 'IntentRequest'
          && request.intent.name === 'noteIntent'
          && request.dialogState !== 'COMPLETED' ;
      },handle(handlerInput) {
         const currentIntent = handlerInput.requestEnvelope.request.intent;
         return handlerInput.responseBuilder
          .addDelegateDirective(currentIntent)
          .getResponse();
    
      }
    };
    
    const completeNoteIntentHandler = {
      canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'IntentRequest'
          && handlerInput.requestEnvelope.request.intent.name === 'noteIntent';
      },handle(handlerInput) {
        const filledSlots = handlerInput.requestEnvelope.request.intent.slots;
        const slotValues = getSlotValues(filledSlots);
        console.log("Folgende Slots im noteIntent " + slotValues.NoteInput.synonym);
    
    
          noteArr.push(slotValues.NoteInput.synonym);
          console.log(noteArr.toString());
    
    
    
          return handlerInput.responseBuilder
          .speak("Ok, ich habe " +slotValues.NoteInput.synonym+ " notiert.")
          .getResponse();
    
      },
    
    
    };
    

    You'll need this function to get the Value of the Slot:

    function getSlotValue(slot){
        let value = slot.value;
        let resolution = (slot.resolutions && slot.resolutions.resolutionsPerAuthority && slot.resolutions.resolutionsPerAuthority.length > 0) ? slot.resolutions.resolutionsPerAuthority[0] : null;
        if(resolution && resolution.status.code == 'ER_SUCCESS_MATCH'){
            let resolutionValue = resolution.values[0].value;
            value = resolutionValue.name;
        }
        return value;
    }