How can I get Amazon echo to respond to "preheat the car" or "what's the car battery status"? (they get hijacked) - alexa-skills-kit

I'm trying to create some skills for my Echo (for my own use, I'm not concerned about the invocation names not getting through review). I've set my invocation name as "the car" (I also tried "car"). I wanted to be able to ask what my battery status is and order Alexa to pre-heat the car (a Renault ZOE).
It seems no matter what I put in for my utterances, I always get the same responses:
Anything with "battery" in gets "I don't have a battery"
Anything with "heat" in gets "You have no smarthome devices, blah blah"
It seems like the words "battery" and "heat" result in things never matching my skill (even when I said the invocation name).
Is there anything I can do so that it will route actions along the lines of the above to my skill?
Edit: Today I get different results trying "preheat the car".. I just get a weird tone. It never calls my skill, nor shows anything in the Home section of the app. What does this tone mean?
Video here: https://twitter.com/DanTup/status/804615557605654528

With help from Reddit I managed to get this working reasonably well. the car was a bad invocation name and I wasn't following the documented way for invoking skills (joining words etc. are fairly restrictive).
I'm now using my car as the invocation name and can do the following:
Alexa tell my car to preheat
Alexa ask my car for battery

As of Dec 2017, it's still not possible to have completely custom phrases with Alexa. Google Assistant/Home does support this however, via shortcuts.

Related

Reason for an unexpcted match to an intent in Watson Assistant

I have defined an intent in Watson Assistant using the following training examples:
adieu
au revoir
bye
bye now
ciao
cu
cya
exit
farewell
good bye
have a nice day
I'm leaving
later
quit
see you
so long
stop
we are done
A user inputs the word "again". Watson returns a match to this intent with a confidence level of about .9
The word "again" does appear in a training example for a completely different intent, namely "I'm looking forward to working with you again! :)". It does not appear in any other training example.
What is the reasoning used by Watson Assistant to arrive at this match and with such a high level of confidence?
There is a whole load of factors that determine why an intent is picked over the other.
Intents do not work properly if you have <= 2 intents.
Any entities you have created that are referenced in the example questions can also impact what is picked.
Contextual entities will also add weight to the POS of those entities.
Number of intents and how frequently the word is used across those intents can also impact the scoring.
Watson Assistant always tries to get meaning from the term where it can.
When trying to determine why it picked one intent over another, you need to look at both. The intent you mention may not even be the second one picked.
With just one intent shown above it's hard to say the 'Why', so this is just an educated guess as to what may be happening.
"again" is a single word and by itself has no context to determine an intent. The closest in the list would be "later".
It couldn't find any meaning whatsoever in a single word, so looked at the intent with the most single word examples, as possible reason to pick it.
That aside, you should try not to answer real 1-2 keyword based questions. There is almost never any context that a person could answer, so it's unlikely WA will be able to either.

Single term answer to Alexa Skill

Background
I'm writing an Alexa Skill and looking to get pieces of information from the user.
The following conversation for example:
Alexa: What month were you born at?
User: April
Alexa: Good. And what was your favorite movie?
User: April
The problem
Given the following utterances:
GetMonthIntent {month}
GetMovieIntent {movie}
Once a user answers April for the second time, the GetMonthIntent might be triggered.
What I have tried
Asking the user to specify which piece of information is giving by using the following utterances:
GetMonthIntent Month {month}
GetMovieIntent Movie {movie}
The question
What is the right way to make Alexa wait for a single term answer based on the current context?
In the same vein as the other answers here, you should take a look at the newest Node.JS library here, which handles state out of the box:
https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs#making-skill-state-management-simpler
You could define:
State_Launch
State_Month
State_Movie
And then return the proper error response if anything other than the GetMovieIntent or GetMonthIntent (etc.) intents are called in the wrong state.
You would have to do data validation on the server side to make sure the "month" is a valid one, and movies are even harder to validate unless you have a list of expected values. That is, if you care to parse them for use beyond repeating back.
Unfortunately, there is no solution. There is no way to specify the 'context' in which a user reply should be interpreted, so you have to tell the user "what was your favorite movie? Please say 'my favorite movie is' and then the name of the movie".
Here are two ASK feature requests that I think would address your issue:
https://forums.developer.amazon.com/content/idea/41062/creating-something-to-help-with-more-structured-qu.html
https://forums.developer.amazon.com/content/idea/55525/allow-a-response-to-specify-a-set-of-expected-inte.html
Personally I think this is fairly important so I voted for those, but they are not near the top.
I ran into this same problem when I created the "Who's on First? Baseball Skit" skill. I handled this by:
Create a sequence number for each response given by Alexa
Write this number to the "session" in the response.
The session is then passed back to your skill by Alexa in the next request.
Read the sequence number from the request to know what the previous question was.
If a given intent could be the answer to multiple questions (eg. month and movie in your case) then use the sequence number to determine which it is.
This should give you ideas on how to deal with repeated answers. The session is quite easy to use. Other options include writing the userId and status to a database like DynamoDB, but I find that the session works in most cases.

Alexa Skills Kit (ASK) and Utterances

I am developing a simple, custom skill for Alexa. I have it up and running, and hosting the handler on AWS Lambda. It's working fine except...
In the test UI, if I enter a valid utterance, e.g., help, cancel, swim, run (two custom utterances), everything works well; however, if I enter a nonsense utterance, e.g., dsfhfdsjhf, the Alexa service always maps the nonsense to the first valid intent in the intents schema.
In my lambda code, I have a handler for handling unknown intents; however, the intent is never unknown. Is this an artifact of the test interface? Something else happening?
Thanks,
John
Based on the inclusion of an unhandled intent in your approach, it sounds like you are using the Alexa Skills Kit SDK for Node.js. Your issue is not an artifact of the test interface. Yes, something else is happening.
While not yet acknowledged by amazon, this is a recognized issue in the SDK by a number of folks. See this open issue. Speaking from personal experience to the suggestion above, it doesn't matter if you use real words or gibberish, the unhandled intent is never called. Until this is fixed, my suggestion would be to build a handler that is a high level prompt for your skill, and reiterates for the user the valid options they have. Position it to be the catch-all. Hopefully we will see better maintenance of this SDK moving forward.
Instead of typing dsfhfdsjhf (which is not pronounceable in any language Alexa knows), what happens if your utterance is boogie or shake?
In a real-world scenario, I don't think Alexa would ever pass dsfhfdsjhf, so it may be difficult to plan exactly what the behavior would be.
So you'd like to pipe all garbage inputs to a single intent. You're in luck. Here's a few things you should know before proceeding.
In Node.js the unhandled handler is fired within a MODE if the intent returned by the Alexa voice service is not available within the given MODE.
An example MODE would be confirmation mode. Of the many intents that are available yes and no are the only intents that are accepted.
var ConfirmationHandlers = Alexa.CreateStateHandler(states.CONFIRMATIONMODE, {
'YesIntent': function () {
this.handler.state = states.CLOSINGCOSTSMODE;
message = ` So you will be buying this house. Great! `;
reprompt = `Please carry on with the other intents found in the house buyer skill. `;
this.emit(':ask', message, reprompt);
},
'NoIntent': function () {
this.handler.state = states.GENERALSEARCHMODE;
message = ` So you won't be buying this house. That's Ok, Continue searching for your dream house in the House buyer skill. !`;
reprompt = `Continue searching for your dream house in the House buyer skill.`;
this.emit(':ask', message, reprompt);
},
'Unhandled': function() {
console.log("UNHANDLED");
var reprompt = ` All other intents are disabled at this moment. Would you like to buy this house Yes or No? `;
this.emit(':ask', reprompt, reprompt);
}
});
However, before reaching the lambda function the Alexa Voice Service must interpret your utterance and map it to one of the available intents. If your utterance is garbage and does not map to any specific intent it is currently being mapped to the first intent.
Solution: If you would like to add a garbage intent this is something that should be handled by the intent schema not by the unhandled intent. To add a garbage intent you can follow the instructions in this amazon article.
https://developer.amazon.com/blogs/post/Tx3IHSFQSUF3RQP/Why-a-Custom-Slot-is-the-Literal-Solution
Scenario 3: I just want everything. Using custom slot types for
grammar as described above typically fulfills this desire and enables
you to improve accuracy through NLP training. If you still just want
everything, you can create a custom slot called something like
“CatchAll” and a corresponding intent and utterance: CatchAllIntent
{CatchAll}. If you use the same training data that you would have used
for LITERAL, you’ll get the same results. People typically find that
adding a little more scenario specific training data improves
accuracy.
If you’re still not getting the results, trying setting the CatchAll
values to around twenty 2 to 8 word random phrases (from a random word
generator – be really random). When the user says something that
matches your other utterances, those intents will still be sent. When
it doesn’t match any of those, it will fall to the CatchAll slot. If
you go this route, you’re going to lose accuracy because you’re not
taking full advantage of Alexa’s NLP so you’ll need to test heavily.
Any input that is not mapped to one of your more specific intents, like YES or NO, will very likely map to this CatchAll intent.

Custom Slot with Numeric Data for Alexa Skills Kit

I'm writing an alexa skill for my local public transit directions. I'm defining the Train Stations with a custom slot like this -
LIST_OF_STOPS - 14th Street | 23rd Street | 33rd Street | Christopher Street | Exchange Place
I have a strong suspicion that Alexa is going to have a hard time understanding the ones like 14th Street, is there documentation or guidelines around how these should be defined?
There is not any documentation. Most people do it by trial and error. The only obscurely documented quirk is that "a.", "b.", etc can be used for the letters.
That being said, I think that those values look to be pretty OK. The one thing you need to be aware of is that Alexa takes the list of custom values "under advisement". It is not a definitive list. Alexa will happily return values other than what is on the list. So you are going to need a fuzzy matcher anyway so you can handle '23 street', and things like that.
I would try the simple list you have, and see if you are happy with the results. If not, you might make one intent that is {slot} street, another for {slot} place, etc. That might improve things. But it might not. You need to iterate and try a bunch of things and see.

Best Strategies for preventing addresses with PO Boxes?

I have a client which is shipping via UPS, and therefore cannot deliver to Post Office boxes. I would like to be able to validate customer address fields in order to prevent them from entering addresses which include a PO box. It would be best if this were implemented as a regex so that I could use a client-side regex validation control (ASP.NET).
I realize there's probably no way to get a 100% detection rate, I'm just looking for something that will work most of the time.
UPS also has tools that you can integrate to do this... that way you can verify an address exactly as to whether or not they will ship, what the cost would be, schedules, etc. I suggest visiting the UPS IT Solutions page for more information.
This should get you started. Test to see if the Address field matches this regex.
"^P\.?\s?O\.?\sB[Oo][Xx]."
Translation to English: That's a P at the beginning of the line, followed by an optional period and space, followed by an O, followed by an optional period, followed by a space, followed by "Box", followed by anything else.
You might be better off putting a disclaimer on the page warning that you can not ship to post office boxes, opposed to validating the input.
More than likely if you do create a regex that catches most of the P.O. Box scenarios, there's a good chance it'll also catch things you weren't intending (i.e. a customer with a street name containing the letters 'p' 'o' and 'box')
Unfortunately, UPS's online software allows P.O. Boxes to go through, but will choke on them once they're in the shipping channel.
In our case, our cart abandonment rate went up when we tried to gracefully prevent P.O. Boxes. We found it much more cost effective to leave it alone, accept the sale, bring it to the attention of customer service, and let them resolve it.
Of course, if you get a high incidence of P.O Boxes, this may not be the case for you.
I'd start with a regex ala Lizard (but use the "ignore case" flag :)), test on historical data, then iterate as you see what invalid inclusions and exclusions you see in testing.
Most shipping providers (for example FedEx) will validate the shipping address. For example, with FedEx web services, there is a call to validate a shipping address and get the estimated cost. This not only ensures that the address is not a PO Box, but also makes sure that the rest of the address is valid.
Regarding the OP's comment to Jason Coco's answer:
Since you're in a position to add regex validation to the shipping address, I assume that you have control of the application (i.e., you have the source and can modify it). If that's the case, then you should have the ability to, on reciept of the submitted data, check whether it is to be shipped via USPS, FedEx, or UPS and submit a request to the appropriate shipper-specific address validator, gaining all the benefits suggested in Jason's answer.
By making it shipper-specific, this would also allow you to avoid implementing one-size-fits-all rules, such as "no PO boxes because UPS doesn't deliver to them", even though the user can select non-UPS shippers who do deliver to PO boxes.
What if it doesn't start with "PO Box.." or "P.O. Box" ?
Example:
John Schmidt |
Silver Valley PO Box 3901 |
Whereswaldoville, SI. 78946
I used an onblur event for the address field to use a javascript function, indexOf, to recognize the input.toUpperCase "PO BOX" || "P.O" that is >= 0.
If either of these two searches are not found, the return is -1, otherwise, it will return the string's start position which will always be 0 or more.
This will ensure that lazy typing, 'po box,' 'p.o box,' and as well as 'p.o. box' will be recognized. I suppose you could add 'po. box' as well.
Anyway, the condition triggers an unobtrusive message to show that 'We can't ship to a PO Box address." It's a feature to not see it if it doesn't apply to you. Otherwise, for users who don't have js or css enabled, they'll just see the message. The only fail on this graceful degradation is if a user has css, but not js enabled (where they just won't see the message at all). I only came up with the solution today, but if I think of a better way, I'll come back to post it here.

Resources