I've got a chatbot which is plugged to backend and DialogFlow/ApiAI.
I'm trying to set up a skill in Alexa so that I can catch everything that is said to my skill and then forward it to my backend so that i can use my existing infrastructure and convo design.
I've been struggling with Alexa to set up an intent that catch everything and just forward it.
From what I understand, you are supposed to use AMAZON.SearchQuery, but I'm getting the following error when i try to set the intent up:
Build Failed
Sample utterance "CATCH_ALL {any}" in intent "CATCH_ALL" must include a carrier phrase. Sample intent utterances with phrase types cannot consist of only slots. Error code: MissingCarrierPhraseWithPhraseSlot -
Does anyone know how to do so ? I tried to use AMAZON.Literal as well, but it seems to be deprecated and I cannot build the skill when i use it.
I'm kinda stuck. It would be great if someone had a solution...
Thanks.
You can replace the AMAZON.SearchQuery with AMAZON.Person. Usually AMAZON.SearchQuery require a phrase along with the slot.Using AMAZON.Person there is no need of phrase along with the slot. It would accept any values that you pass to the Intent.
{
"name": "CATCH_ALL",
"slots": [
{
"name": "any",
"type": "AMAZON.Person"
}
],
"samples": [
"{any}"
]
}
I finally managed to do so by doing something like this:
{
"interactionModel": {
"languageModel": {
"invocationName": "test",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "CATCHALL",
"slots": [
{
"name": "any",
"type": "AMAZON.LITERAL"
}
],
"samples": [
"{hey|any}",
"{hey hey|any}",
"{hey hey hey|any}",
"{hey hey hey hey|any}",
"{hey hey hey hey hey|any}"
]
}
],
"types": []
}
}
}
the samples for the intent CATCHALL indicates the number of word you want to catch. So lige this, i will catch any sentence between one and this 5 words.
I'm not sure if this is going to be a problem when I'll submit the app, though.
Note that AMAZON.LITERAL is not supported for any language other than English (US), so this is not a solution for me as it's a french and english chatbot. So i'm back again at the beginning...
edit: Here is the solution without LITERAL:
{
"interactionModel": {
"languageModel": {
"invocationName": "mon invocation",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": [
"que puis-je faire"
]
},
{
"name": "AMAZON.StopIntent",
"samples": [
"je veux quitter"
]
},
{
"name": "CATCH_ALL",
"slots": [
{
"name": "any",
"type": "ANYTHING"
}
],
"samples": [
"{any}"
]
}
],
"types": [
{
"name": "ANYTHING",
"values": [
{
"name": {
"value": "hey"
}
},
{
"name": {
"value": "hey hey"
}
},
{
"name": {
"value": "hey hey hey"
}
},
{
"name": {
"value": "hey hey hey hey"
}
},
{
"name": {
"value": "hey hey hey hey hey"
}
},
{
"name": {
"value": "hey hey hey hey hey hey"
}
},
{
"name": {
"value": "hey hey hey hey hey hey hey"
}
},
{
"name": {
"value": "hey hey hey hey hey hey hey hey"
}
},
{
"name": {
"value": "hey hey hey hey hey hey hey hey hey"
}
},
{
"name": {
"value": "hey hey hey hey hey hey hey hey hey hey"
}
},
{
"name": {
"value": "hey hey hey hey hey hey hey hey hey hey hey"
}
},
{
"name": {
"value": "hey hey hey hey hey hey hey hey hey hey hey hey"
}
}
]
}
]
}
}
}
Unfortunately, there is no solution at this time. Alexa doesn't support a way to get all the text the way you're looking to do.
You can create a custom slot with some random words.
{
"interactionModel": {
"languageModel": {
"invocationName": "demo",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "EveryThingIntent",
"slots": [
{
"name": "EveryThingSlot",
"type": "BAG_OF_WORDS"
}
],
"samples": [
"{EveryThingSlot} "
]
}
],
"types": [
{
"name": "BAG_OF_WORDS",
"values": [
{
"name": {
"value": "Hello World"
}
}
]
}
]
}
}
}
Related
I have an interaction model with a GetMenuIntent which I can invoke with "what's for {meal}". meal is a MealType custom slot with allowed values of "breakfast" and "lunch". I added validation on the meal slot in my GetMenuIntent to only allow those values defined in the slot type and it works great for those configured values.
However, after saving and building my model, when I put "what's for dinner" into the Utterance Profiler or the interactive tester, It ended up calling my FallbackIntent instead of reprompting for a correct value.
I feel like what I'm trying to do isn't really much different than Amazon's own example here.
Here's "whats for lunch" working correctly:
And here's "whats for dinner" ignoring my GetMenuIntent and calling FallbackIntent instead:
Here's my interaction model:
{
"interactionModel": {
"languageModel": {
"invocationName": "school menus",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "GetMenuIntent",
"slots": [
{
"name": "meal",
"type": "Meal"
},
{
"name": "date",
"type": "AMAZON.DATE"
}
],
"samples": [
"whats for {meal} {date}",
"what will you have for {meal} {date}",
"what is on the menu for {meal} {date}",
"what are we having for {meal} {date}",
"what we're having for {meal} {date}"
]
},
{
"name": "AMAZON.FallbackIntent",
"samples": []
}
],
"types": [
{
"values": [
{
"name": {
"value": "lunch"
}
},
{
"name": {
"value": "breakfast"
}
}
],
"name": "Meal"
}
]
},
"dialog": {
"intents": [
{
"name": "GetMenuIntent",
"confirmationRequired": false,
"prompts": {},
"slots": [
{
"name": "meal",
"type": "Meal",
"elicitationRequired": false,
"confirmationRequired": false,
"prompts": {},
"validations": [
{
"type": "hasEntityResolutionMatch",
"prompt": "Slot.Validation.806855880612.19281662909.602239253259"
}
]
},
{
"name": "date",
"type": "AMAZON.DATE",
"elicitationRequired": false,
"confirmationRequired": false,
"prompts": {}
}
]
}
],
"delegationStrategy": "ALWAYS"
},
"prompts": [
{
"id": "Slot.Validation.806855880612.19281662909.602239253259",
"variations": [
{
"type": "PlainText",
"value": "Hmm, I don't know about that menu type. Please try again."
}
]
}
]
},
"version": "48"
}
Since this is 6 months old I assume you figured out by now that your interaction model only includes Lunch and Breakfast.
During Alexa discovery process, we need to send device details and their capabilities. I am sending light and fan details. Light gets showed up in Alexa App but not the fan. Can you please help me to find what I am doing wrong with the following response.
I used this Alexa documentation for creating response. https://developer.amazon.com/docs/smarthome/connect-a-tower-fan-to-alexa.html
{
"event": {
"header": {
"namespace": "Alexa.Discovery",
"name": "Discover.Response",
"payloadVersion": "3",
"messageId": "somd-id"
},
"payload": {
"endpoints": [
{
"endpointId": "fan-i",
"friendlyName": "Fan",
"description": "Fan",
"manufacturerName": "Fan",
"displayCategories": [
"OTHER"
],
"cookie": {},
"capabilities": [
{
"type": "AlexaInterface",
"interface": "Alexa.PowerController",
"version": "3",
"properties": {
"supported": [
{
"name": "powerState"
}
],
"proactivelyReported": true,
"retrievable": true
}
},
{
"type": "AlexaInterface",
"interface": "Alexa.RangeController",
"version": "3",
"instance": "speed",
"capabilityResources": {
"friendlyNames": [
{
"#type": "asset",
"value": {
"assetId": "Alexa.Setting.FanSpeed"
}
}
]
},
"properties": {
"supported": [
{
"name": "rangeValue"
}
],
"proactivelyReported": true,
"retrievable": true
},
"configuration": {
"supportedRange": {
"minimumValue": 1,
"maximumValue": 5,
"precision": 1
},
"presets": [
{
"rangeValue": 1,
"presetResources": {
"friendlyNames": [
{
"#type": "asset",
"value": {
"assetId": "Alexa.Value.Minimum"
}
},
{
"#type": "asset",
"value": {
"assetId": "Alexa.Value.Low"
}
}
]
}
},
{
"rangeValue": 5,
"presetResources": {
"friendlyNames": [
{
"#type": "asset",
"value": {
"assetId": "Alexa.Value.Maximum"
}
},
{
"#type": "asset",
"value": {
"assetId": "Alexa.Value.High"
}
}
]
}
},
{
"rangeValue": 3,
"presetResources": {
"friendlyNames": [
{
"#type": "asset",
"value": {
"assetId": "Alexa.Value.Medium"
}
}
]
}
}
]
}
},
{
"type": "AlexaInterface",
"interface": "Alexa",
"version": "3"
}
]
},
]
}
}
}
Note: I am just repeating above question below because StackOverflow doesn't allow so much code to be pasted with less description.
During Alexa discovery process, we need to send device details and their capabilities. I am sending light and fan details. Light gets showed up in Alexa App but not the fan. Can you please help me to find what I am doing wrong with the following response.
I think Alexa.RangeController is currently restricted to US region. So if you are trying to discover devices registered to account outside US, then it looks like that Alexa simply ignores the discovery response with RangeController interface. The way I got around this problem is by switching the user account to US and the device appeared immediately. Give it a try and if you a better solution then please do share.
Alexa is saying minute wrong, how can I make her say minute as in 60 seconds when replying to my Skill ?
At the moment she says "as of 5 minutes ago" 5 very small objects haha
This is my skill
{
"interactionModel": {
"languageModel": {
"invocationName": "jarvis",
"intents": [
{
"name": "NSStatus",
"slots": [],
"samples": [
"How am I doing"
]
},
{
"name": "UploaderBattery",
"slots": [],
"samples": [
"How is my uploader battery"
]
},
{
"name": "PumpBattery",
"slots": [],
"samples": [
"How is my pump battery"
]
},
{
"name": "LastLoop",
"slots": [],
"samples": [
"When was my last loop"
]
},
{
"name": "MetricNow",
"slots": [
{
"name": "metric",
"type": "LIST_OF_METRICS"
},
{
"name": "pwd",
"type": "AMAZON.US_FIRST_NAME"
}
],
"samples": [
"What is my {metric}",
"What my {metric} is",
"What is {pwd} {metric}"
]
},
{
"name": "InsulinRemaining",
"slots": [
{
"name": "pwd",
"type": "AMAZON.US_FIRST_NAME"
}
],
"samples": [
"How much insulin do I have left",
"How much insulin do I have remaining",
"How much insulin does {pwd} have left",
"How much insulin does {pwd} have remaining"
]
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
}
],
"types": [
{
"name": "LIST_OF_METRICS",
"values": [
{
"name": {
"value": "bg"
}
},
{
"name": {
"value": "blood glucose"
}
},
{
"name": {
"value": "number"
}
},
{
"name": {
"value": "iob"
}
},
{
"name": {
"value": "insulin on board"
}
},
{
"name": {
"value": "current basal"
}
},
{
"name": {
"value": "basal"
}
},
{
"name": {
"value": "cob"
}
},
{
"name": {
"value": "carbs on board"
}
},
{
"name": {
"value": "carbohydrates on board"
}
},
{
"name": {
"value": "loop forecast"
}
},
{
"name": {
"value": "ar2 forecast"
}
},
{
"name": {
"value": "forecast"
}
},
{
"name": {
"value": "raw bg"
}
},
{
"name": {
"value": "raw blood glucose"
}
}
]
}
]
}
}
}
Obviously this can't be launched until this is resolved as it just sounds ridiculous hahah
I tried to do some googling and searching on here but its really hard when 2 words are spelt the same to distinguish between minute and minute - see !
Thanks :D
Use SSML speech tag for the response texts.
<speak>
<say-as interpret-as="time" > 5' </say-as>
</speak>
will be pronounced as 5 minutes.
<speak>
<say-as interpret-as="time" > 5'10" </say-as>
</speak>
will be pronounced as 5 minutes and ten seconds.
The say-as tag of SSML will help you to interpret your response in the desired way. You can use interpret-as="time" to make Alexa interpret it as time.
<speak>
<say-as interpret-as="time" > 5'10" </say-as> ago.
</speak>
Beware that if you want just "minute" and not seconds, use it like 5'0". If you only include 5' it will read as "five apostrophe".
<say-as interpret-as="time" > 5'0" </say-as> ago.
In the same way for seconds alone use it like 0'10". This will read as "ten seconds".
<say-as interpret-as="time" > 0'10" </say-as>
More on say-as tag here.
phoneme
If you have some complex pronunciations or the same text has different pronunciations, then use phoneme tag to provide its exact phonetic pronunciation.
For example, The "minute" (time) and "minute" (size) can be pounced differently by giving its exact phonetic pronunciation symbols.
<speak>
<phoneme alphabet="ipa" ph="/mʌɪˈnjuːt/">minute</phoneme>particles.
One <phoneme alphabet="ipa" ph="/ˈmɪnɪt/">minute</phoneme>.
</speak>
This will be spoken as
"minute particles" and "One minute ago".
More on phoneme tag here.
so I have written a handler for an intent where the user asks Alexa to recommend a service i.e. "Alexa could you recommend a plumber". The problem is that Alexa comes in an triggers its default recommendation action.
The conversation is as follows:
User: Alexa open Bucharest insight
Alexa: Hi, welcome to Bucharest Insight, how are you? you can ask me questions about the local news or ask me for a recommendation.
User: I need a plumber
Alexa: Here are a few top-rated ones
I was expecting my getRecommendationIntentHandler to be triggered as I have setup the intent correctly ( See the below JSON) - "I need a {serviceName}",
The result from Alexa seems like a build in response instead of my custom intent handler below:
const getRecommendationIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'getRecommendationIntent';
},
handle(handlerInput) {
console.log('Called getRecommendationIntentHandler');
const responseBuilder = handlerInput.responseBuilder;
const filledSlots = handlerInput.requestEnvelope.request.intent.slots;
// Get the filled slots inputted by the user
const slotValues = getSlotValues(filledSlots);
console.log(JSON.stringify(slotValues));
const speechText = 'getRecommendationIntentHandler called';
return responseBuilder
.speak(speechText)
.getResponse();
},
};
I have attached my JSON from Alexa Skills Kit below)
{
"interactionModel": {
"languageModel": {
"invocationName": "bucharest insight",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "NewsIntent",
"slots": [],
"samples": [
"What's the latest news",
"Tell me the news",
"Can you tell me the news please",
"I want the news",
"Play the news"
]
},
{
"name": "getRecommendationIntent",
"slots": [
{
"name": "serviceName",
"type": "AMAZON.ProfessionalType",
"samples": [
"Do you have {serviceName}",
"I would like to get a {serviceName}",
"An {serviceName}",
"A {serviceName}",
"{serviceName}",
"I would like a {serviceName}"
]
}
],
"samples": [
"Have you got any plumbers",
"Do you know a good {serviceName}",
"Do you know of a good {serviceName}",
"Can you recommend me a {serviceName} please",
"I want a {serviceName} do you know anyone",
"Have you got any good {serviceName}",
"Can you find me a {serviceName}",
"I need a {serviceName}",
"Can you find me a good {serviceName}",
"Do you know of any good {serviceName}",
"Can you recommend me a {serviceName}"
]
},
{
"name": "AMAZON.PauseIntent",
"samples": []
},
{
"name": "AMAZON.ResumeIntent",
"samples": []
}
],
"types": [
{
"name": "AMAZON.ProfessionalType",
"values": [
{
"name": {
"value": "fashion designer",
"synonyms": [
"Fashion",
"clothes designer"
]
}
},
{
"name": {
"value": "Interior designer",
"synonyms": [
"Home designer"
]
}
},
{
"name": {
"value": "Painter",
"synonyms": [
"Painting"
]
}
},
{
"name": {
"value": "Electrician",
"synonyms": [
"Electric man"
]
}
},
{
"name": {
"value": "Plumber",
"synonyms": [
"plumber",
"Water man"
]
}
}
]
}
]
},
"dialog": {
"intents": [
{
"name": "getRecommendationIntent",
"confirmationRequired": true,
"prompts": {
"confirmation": "Confirm.Intent.508140955512"
},
"slots": [
{
"name": "serviceName",
"type": "AMAZON.ProfessionalType",
"confirmationRequired": true,
"elicitationRequired": true,
"prompts": {
"confirmation": "Confirm.Slot.508140955512.325067758753",
"elicitation": "Elicit.Slot.508140955512.325067758753"
}
}
]
}
]
},
"prompts": [
{
"id": "Elicit.Slot.508140955512.325067758753",
"variations": [
{
"type": "PlainText",
"value": "What service do you want?"
},
{
"type": "PlainText",
"value": "Can you tell me what you're looking for ?"
},
{
"type": "PlainText",
"value": "What's the serivice you are looking for?"
}
]
},
{
"id": "Confirm.Slot.508140955512.325067758753",
"variations": [
{
"type": "PlainText",
"value": "So you want to find a {serviceName} , correct?"
}
]
},
{
"id": "Confirm.Intent.508140955512",
"variations": [
{
"type": "PlainText",
"value": "So you want me to find a {serviceName} , is that correct?"
},
{
"type": "PlainText",
"value": "So you want me to recommend you a {serviceName} , am I right ?"
}
]
}
]
}
}
Any help would be much appreciated and I am open to further questions about this.
-- New comment 06/09/2018 - This is the JSON created by Alexa:
JSON Input:
{
"version": "1.0",
"session": {
"new": true,
"sessionId": "amzn1.echo-api.session.5688bb9b-0f5c-4616-9c8d-46d2218a167b",
"application": {
"applicationId": "amzn1.ask.skill.180e6d66-06c5-412c-8fe0-90f2fcc31a3a"
},
"user": {
"userId": "amzn1.ask.account.AEHB6UB7SDQU6TCKZOEADQ2ICGLSXETSXC6LOJSRXWAPGWLBBXQIKKH2GTFRLO6NIKLCXIRJBQLXAT45OCKP4UHMPSCM33M5ZE4M4EE5MARUBLF7BNTL6WWAIWKOL3WMYCWT7SCOKQHROFD3VEJTPN3JFCLWQ46ZRY6UGSENVLPFIHPQGQZNV3T6UQ4TEXGFNMHX6PCLTHZUS5I"
}
},
"context": {
"AudioPlayer": {
"playerActivity": "IDLE"
},
"System": {
"application": {
"applicationId": "amzn1.ask.skill.180e6d66-06c5-412c-8fe0-90f2fcc31a3a"
},
"user": {
"userId": "amzn1.ask.account.AEHB6UB7SDQU6TCKZOEADQ2ICGLSXETSXC6LOJSRXWAPGWLBBXQIKKH2GTFRLO6NIKLCXIRJBQLXAT45OCKP4UHMPSCM33M5ZE4M4EE5MARUBLF7BNTL6WWAIWKOL3WMYCWT7SCOKQHROFD3VEJTPN3JFCLWQ46ZRY6UGSENVLPFIHPQGQZNV3T6UQ4TEXGFNMHX6PCLTHZUS5I"
},
"device": {
"deviceId": "amzn1.ask.device.AFYZEJWCDICBPMGAGXM2TNFW4MMZCWWGVFATSXL6ARKMXBENBTS5U2M2PAQJRTBQB2OR2X5HHCM4A7CWIWNOCFIP4LF2LXH6F5OND5425SXYUONA6NTJ67LM2Z27OOAAJ4WXW4COPWZXNP7KMK2YIHDOMUSQ",
"supportedInterfaces": {
"AudioPlayer": {}
}
},
"apiEndpoint": "https://api.eu.amazonalexa.com",
"apiAccessToken": "Redacted by me"
}
},
"request": {
"type": "LaunchRequest",
"requestId": "amzn1.echo-api.request.c17bb90f-8c8d-4b4c-ab1f-0462ab5f2c05",
"timestamp": "2018-09-06T06:29:14Z",
"locale": "en-US",
"shouldLinkResultBeReturned": false
}
}
JSON Output
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Hi, welcome to Bucharest Insight, how are you ? you can ask me questions about the local news or ask me for a recommendation</speak>"
}
},
"sessionAttributes": {},
"userAgent": "ask-node/2.0.5 Node/v8.10.0"
}
}
Event.TextMessage
{
"event": {
"header": {
"namespace": "Text",
"name": "TextMessage",
"messageId": "messageId",
"dialogRequestId": "6ecb05d5-905f-4c9f-aae0-bbeb028062db"
},
"payload": {
"textMessage": "i need a plumber"
}
},
"context": [
{
"header": {
"namespace": "SpeechSynthesizer",
"name": "SpeechState"
},
"payload": {
"token": "amzn1.as-ct.v1.ThirdPartySdkSpeechlet#ACRI#ValidatedSpeakDirective_amzn1.ask.skill.180e6d66-06c5-412c-8fe0-90f2fcc31a3a_0b040a2a-a5bc-4d43-9452-95c49c3cca1c",
"offsetInMilliseconds": 1000,
"playerActivity": "FINISHED"
}
},
{
"header": {
"namespace": "AudioPlayer",
"name": "PlaybackState"
},
"payload": {
"token": "",
"offsetInMilliseconds": 0,
"playerActivity": "IDLE"
}
},
{
"header": {
"namespace": "Alerts",
"name": "AlertsState"
},
"payload": {
"activeAlerts": [],
"allAlerts": []
}
},
{
"header": {
"namespace": "VisualFocusManager",
"name": "VisualFocusState"
},
"payload": {
"inFocus": {
"component": "ListRenderer",
"idleTimeInMilliseconds": 0
}
}
},
{
"header": {
"namespace": "AudioFocusManager",
"name": "AudioFocusState"
},
"payload": {
"alert": {
"component": null,
"idleTimeInMilliseconds": 0
},
"dialog": {
"component": "SpeechSynthesizer",
"idleTimeInMilliseconds": 1000
},
"content": {
"component": null,
"idleTimeInMilliseconds": 0
}
}
},
{
"header": {
"namespace": "ListRenderer",
"name": "RenderedListState"
},
"payload": {
"listToken": "amzn1.as-lt.v1.ThirdPartySdkSpeechlet#LRID#amzn1.ask.skill.180e6d66-06c5-412c-8fe0-90f2fcc31a3a::Latuc",
"itemsVisibleOnScreen": [],
"selectedItems": [],
"focusedItem": {},
"renderedItemDetail": {
"listItemIdentifier": "amzn1.as-lt.v1.ThirdPartySdkSpeechlet#LRID#amzn1.ask.skill.180e6d66-06c5-412c-8fe0-90f2fcc31a3a::Latuc",
"ordinalNumber": 1
},
"highestOrdinalSeen": 1,
"lastItemOrdinal": 1
}
}
]
}
Directive: SpeechSynthesizer.Speak
{
"header": {
"namespace": "SpeechSynthesizer",
"name": "Speak",
"messageId": "aa79a5f3-9293-4f49-9fda-22abeaedbe03",
"dialogRequestId": "6ecb05d5-905f-4c9f-aae0-bbeb028062db"
},
"payload": {
"caption": "Here are a few top-rated ones",
"url": "https://kopytko-eu-west-1.amazon.com/3/72c80478-b19e-11e8-aeb5-15393a31d62e-9eedcf/5/1536301872334/10f6885702786ce70473a6560e8b09fdc9a5d548d7c5f6072eaf3a18c498fce1/resource.mp3",
"format": "AUDIO_MPEG",
"token": "amzn1.as-ct.v1.DOMAIN:POI#ACRI#DeeAppPOISpeechlet",
"ssml": "<speak><prosody volume=\"x-loud\">Here are a few top-rated ones</prosody><metadata><promptMetadata><promptId>POICategory#Knight#MultipleResults</promptId><namespace>POI</namespace><locale>en_US</locale><overrideId>default</overrideId><variant>1</variant><condition/><weight>1</weight><stageVersion>Adm-20180810_234837-1</stageVersion></promptMetadata></metadata></speak>"
}
}
Directive.ListRenderer.RenderList
{
"header": {
"namespace": "ListRenderer",
"name": "RenderList",
"messageId": "d79a03bb-b1cf-4722-a24a-a982f2b89da7",
"dialogRequestId": "6ecb05d5-905f-4c9f-aae0-bbeb028062db"
},
"payload": {
"name": "renderList",
"namespace": "ListRenderer",
"listToken": "amzn1.as-lt.v1.DOMAIN:POI#LRID#a1be83a5-35d9-41c9-94c1-066e7152fc45",
"totalNumberOfItems": 4,
"listPage": {
"listItems": [
..... (Too long to display here)
Directive: ListRenderer.ReadListItems
{
"header": {
"namespace": "ListRenderer",
"name": "ReadListItems",
"messageId": "57b1df77-1175-42bd-99a1-86ded50e7525",
"dialogRequestId": "6ecb05d5-905f-4c9f-aae0-bbeb028062db"
},
"payload": {
"listToken": "amzn1.as-lt.v1.DOMAIN:POI#LRID#a1be83a5-35d9-41c9-94c1-066e7152fc45",
"beginOrdinal": 1,
"count": 4
}
}
Directive: SpeechRecognizer.RequestProcessingCompleted
{
"header": {
"namespace": "SpeechRecognizer",
"name": "RequestProcessingCompleted",
"messageId": "59a2194d-f04f-43f4-9269-8bbe0c3c3809",
"dialogRequestId": "6ecb05d5-905f-4c9f-aae0-bbeb028062db"
},
"payload": {}
}
Your first response does not have shouldEndSession parameter. If not provided, defaults to true. What that means is that, once your response is read, Alexa will end the session and closes the skill. You are no longer inside the skill. Whenever you want Alexa to wait for user response, keep the session alive by setting shouldEndSession parameter set to false.
Your first response should be like this:
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Hi, welcome to Bucharest Insight, how are you ? you can ask me questions about the local news or ask me for a recommendation</speak>"
},
"shouldEndSession": false
},
"sessionAttributes": {},
"userAgent": "ask-node/2.0.5 Node/v8.10.0"
}
}
The good thing is that, you don't have to set this parameter manually and the SDK will take care of it. For that use a reprompt. Including a reprompt in your response is a good design.
return responseBuilder
.speak(speechText)
.reprompt(repromptSpeechOutput)
.getResponse();
If you don't want to use a reprompt you can use withShouldEndSession(false).
Read this answer for more.
I'm trying to develop an Alexa skill, and I need to get the relative time, eg: "5 minutes ago".
I have defined a time slot for my skill which accepts time like 5 minutes, 6.30 am or 4 in the morning. But I'm not able to accept a time like 5 minutes ago. I new to Alexa and can some one help me out with this
{
"slots": [
{
"name": "time",
"type": "AMAZON.TIME"
}
],
"intent": "ReportTime"
}
You could add a {modifier} slot that can take several keywords like "ago" and "from now". The intent could then have something like the following utterances:
{
"name": "TimeTest",
"samples": [
"what happened {time} {modifier}",
"what will happen {time} {modifier}"
],
"slots": [
{
"name": "time",
"type": "AMAZON.TIME",
"samples": []
},
{
"name": "modifier",
"type": "custom_time_modifier",
"samples": []
}
]
}
with the following custom modifier type:
"types": [
{
"name": "custom_time_modifier",
"values": [
{
"id": null,
"name": {
"value": "ago",
"synonyms": [
"in the past"
]
}
},
{
"id": null,
"name": {
"value": "from now",
"synonyms": [
"in the future"
]
}
}
]
}