Alexa is picking only US cities for city intent - alexa

I am developing an app for the weather where the user has to respond with the city name when alexa ask for. My city intent read like this
{
"slots": [
{
"name": "cityName",
"type": "AMAZON.US_CITY"
}
],
"intent": "cityIntent"
}
When user says only city name like San Francisco, Chicago or New York, it processed but if user is giving another city name like Mumbai, London, Manchester, it won't pick it up and directly go for stop intent. But if I am saying Change My City To Mumbai, then it is processing the city.
And Changed the AMAZON.US_CITY to AMAZON.GB_CITY too but it didn't work for me.

Related

InvalidSlotTypeLiteral: Slot type "AMAZON.LITERAL" for slot "Text" in intent "RawText" is not valid

AMAZON.LITERAL is deprecated as of October 22, 2018. Older skills built with AMAZON.LITERAL.
What is the alternative to AMAZON.LITERAL, I want each and every word spoken by user from Alexa device in my endpoint API.
I have created custom slots, but my endpoint is not called everytime.
Anyone have solution to this?
You will not get the entire user input through any inbuilt slots or intents. The closest one to your requirement that I can think of is AMAZON.SearchQuery.
AMAZON.SearchQuery
AMAZON.SearchQuery is a phrase-type slot that lets you capture less-predictable input that makes up the search query. You can use phrase slots when you cannot predict all possible values the user might say, or when there may not be an identifiable pattern that can be captured by a custom slot. The intended use of this slot is to capture short messages, comments, search queries, and other short free-form text, not the entire user spoken utterance.
Ex:
{
"intents": [
{
"name": "SearchIntent",
"slots": [
{
"name": "Query",
"type": "AMAZON.SearchQuery"
},
{
"name": "CityList",
"type": "AMAZON.US_CITY"
}
],
"samples": [
"search for {Query} near me",
"find out {Query}",
"search for {Query}",
"give me details about {CityList}"
]
}
]
}
You cannot add sample intent utterances consisting of only phrase type slots.
That means, you cannot give something like this:
{
"name": "QueryIntent",
"slots": [
{
"name": "query",
"type": "AMAZON.SearchQuery"
}
],
"samples": [
"{query}" // utterance with only phrase-type slot
]
}
More on AMAZON.SearchQuery here
Alexa will always will fire a POST request to your skill's endpoint with a payload whenever there is a user interaction.

How to add validation on a slot value in alexa skill

I have a single intent in my skill NoteMyDetail which has three required slots: name, age, gender.
I have various utterances like "note my details", "note my name as {name}" etc.
So if I say "note my details" it one by one asks for all the values and if I say "note my name as Joe" it asks for only the age and the gender.
Now the issue I am facing is how to add validations for these slots because when Alexa asks: "what is your age" and I reply my name is Joe or any gibberish it sends a "?" in the slot value.
How do I make sure that the value is a number only for age?
EDIT: So I used the code of the link: https://gist.github.com/stormbytes/7ee3a05aa03c0ada0621dde746f2a6f9#file-index-js-L31
I have the slots as required, so it asks for all the values and then checks for the value which disrupts the flow, so I made the slot values as not mandatory and checked if the value if defined/undefined. I am getting the following response in the simulator but it says "There was a problem with the requested skill's response"
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak> Sorry I did not get the age, please say it again </speak>"
},
"directives": [
{
"type": "Dialog.ElicitSlot",
"slotToElicit": "ageValue"
}
],
"reprompt": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak> Please tell me your age </speak>"
}
},
"shouldEndSession": false
},
"sessionAttributes": {},
"userAgent": "ask-nodejs/1.0.25 Node/v6.10.3"
}
}
This is a typical case where you can use a recently released feature called Slot Validation. All you have to do is go to the page where you defined your slot as required and click on the Validations tab:
and add a validation rule. In your case where you're dealing with age, most probably and AMAZON.Number, you can set up two rules, one for the lower limit of the age (e.g. 0) and another one for the top limit (e.g. 100). Take a look at my example using a numeric slot called ownedMiles:
Once you do that anything that is not a number within the range defined by the validation rules will cause the provided prompt in the validation to be spoken and Alexa will try to collect the value again.

Alexa sometimes not understanding city name

In my app, user has to tell the current city. My intent request is
{
"slots": [
{
"name": "cityName",
"type": "AMAZON.US_CITY"
}
],
"intent": "cityIntent"
}
And my utterances are
cityIntent my city is {cityName}
cityIntent my favorite city is {cityName}
cityIntent {cityName}
cityIntent change city to {cityName}
now when I am saying Alexa change city to Mumbai or My city is Miami, it is working fine but when alexa ask for the city name and I am replying with only city name like Mumbai Or Miami, it won't work. It calls for stopIntent
Amazon recently created a new slot type AMAZON.SearchQuery which would perfectly suit your problem.

How do i extract the original date value passed from the user input

Context:
The Watson Conversation bot has a node that gets triggered by three input entities from the user, this works fine, but i want the reply from the bot to be
"Checking if you have a lecture tomorrow. Give me a moment"
then there's a query in the background building up the answer that gets replied later to the user.
the strong word tomorrow is an #sys-date entity, but i want it to reply to the user what he/she said instead of the date, because the bot can check no both weeks months ect, all valid date formats, and the reply would look much better if i could use the original text from the user.
This kind of origin retrieval will be used for other entities aswell when i get it working.
You can use the context variable in the case, and if you want to get specific data, you can use regex to extract the user input:
Example all user input
"date": "<? input.text?>"
or for exactly what the user input, ex: "this week"
"date": "<?#sys-date.literal?>"
Etc..
Use the variable with the .literal, see my complete example:
{
"context": {
"date": "<?#sys-date.literal?>"
},
"output": {
"text": {
"values": [
"Checking if you have a lecture $date. Give me a moment."
],
"selection_policy": "sequential"
}
}
}
Documentation examples
:

Firebase database structure

I'm just starting to experiment with Firebase. It's a real head bender when you're used to relational databases!
I'm trying to design an app that will allow users to search for meals by barcode or name and retrieve the number of calories. Additionally, I need to be able to store the meals eaten by a user, and finally retrieve the food eaten by a user each day, week or month.
I was thinking each meal would have a unique ID (e.g. M1234 for Pizza), then I'd have 2 lookup sections - one by barcode and one by name, so that should hopefully cover the search functionality.
Each user would have the meals eaten stored in the eaten 'table' (what is the correct term for 'table' in a Firebase database?) by date, just referencing the meal by ID.
This is how I've designed the database.
{
// Here are the users.
"users": {
"mchen": {
"name": "Mary Chen",
"email": "mary#chen.com",
}
},
...
},
// Here are the meals eaten by date.
"eaten": {
"mchen": {
// index Mary's meals in her profile /eaten/mchen/meals/20161217 should return 'M1234' (pizza) and 'M8765' (chips)
"meals": {
"20161217": {
"M1234": true,
"M8765": true
},
"20161218": {
"M2222": true,
"M8765": true
}
},
...
},
// Here are the meals with calorie information.
"meals": {
"M1234": {
"name": "Pizza"
"calories": 400
},
"M2222": {
"name": "Curry"
"calories": 250
},
"M8765": {
"name": "Chips"
"calories": 100
},
},
// Here is the barcode lookup
"barcode-lookup": {
"12345678": {
"id": "M1234"
},
"87654321": {
"id": "M2222"
},
"11223344": {
"id": "M8765"
}
},
// Here is the name lookup
"name-lookup": {
"Chips": {
"id": "M8765"
},
"Pizza": {
"id": "M1234"
},
"Curry": {
"id": "M2222"
}
}
}
Does it seem reasonable or are there any obvious flaws?
You will want to leverage .childByAutoId() and let Firebase create the parent key names. It's best practice to disassociate your child data from the parent node and allowing Firebase to create 'random' key's for the parents will make that work.
Along with that, it's customary to create a /users node and the parent nodes for each user would be the uid which was created by Firebase when the user was first created.
In your original structure, there's a barcode and name lookup which I have integrated into the following structure to reduce complexity.
users
uid_0
name: "Mary Chen",
email: "mary#chen.com"
uid_1
name: "Larry David"
email: "ldavid#david.com"
and then the dining
dining
-Yuiia09skjspo
dining_timestamp: "20161207113010"
Y79joa90ksss: true
Yjs9990kokod: true
user: uid_0
uid_timestamp: "uid_0_ 20161207113010"
-Yi9sjmsospkos
dining_timestamp: "20161207173000"
Y79joa90ksss: true
Yjs9990kokod: true
user: uid_1
uid_timestamp: "uid_1_ 20161207173000"
and the meals the user can choose from
meal
-Y79joa90ksss
name: "Pizza"
calories: "400"
barcode: "008481816164"
-Yjs9990kokod
name: "Burger"
calories: "520"
barcode: "991994411815"
As you can see, the dining node contains a dining event for each user (so all of the dining events are in one node)
This enables you to query for all kinds of things:
All dining for all users by date or range of dates.
All dining that contain a certain meal
All meals by a user
->The cool one<- all dining for a specific user within a date range.
The one omission is a search for dining that contains two meals, however, the solution to that is also in this answer.
All in all, your structure is sound - just needs a little tweaking.
The structure looks fine (though I would let firebase generate the ids). The only thing that won't work like what you're expecting is searching. Based on your data if I searched for pizza you couldn't write a query that would return the Pizza entry. My suggestion would be to either use Algolia (or something similar) for searching or to roll another key with your name lowerCased to make it possible for a query to work. The only issue with running your own is you won't be able to search for things like izz and have Pizza turn up. See my answer Firebase - How can I filter similarly to equalTo() but instead check if it contains the value? for how to do a search.

Resources