ALEXA - How to send slot ID in service request - node.js

I am creating custom Alexa skill, with custom slots. I have created predefined values for the slot and assigned an ID to each. During my tests I can see that in the service request there is no ID key-value pair:
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.xXxxxxXXXx-xxXX-xXXx-xXXX-xxxXXXXXXxxx",
"intent": {
"name": "HowToIntent",
"slots": {
"action": {
"name": "action",
"value": "clear cache"
}
}
},
Is there any possibility to pass slot ID in the request?

"languageModel": {
"types": [
{
"name": "action",
"values": [
{
"id": "1",
"name": {
"value": "clear cache",
"synonyms": [
"flush cache",
"clean cache"
]
}
},
{
"id": "2",
"name": {
"value": "perform reindex",
"synonyms": [
"reindex",
"do reindex"
]
}
},
{
"id": "3",
"name": {
"value": "create a product",
"synonyms": [
"add product",
"make product"
]
}
},
{
"id": "4",
"name": {
"value": "create a category",
"synonyms": [
"add category",
"make category"
]
}
}
]
},
{
"name": "element",
"values": [
{
"id": "1",
"name": {
"value": "category tree",
"synonyms": [
"category structure",
"categories"
]
}
},
{
"id": "2",
"name": {
"value": "simple product",
"synonyms": []
}
},
{
"id": "3",
"name": {
"value": "gift card",
"synonyms": []
}
}
]
}
],
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "HowToIntent",
"samples": [
"how to {action}"
],
"slots": [
{
"name": "action",
"type": "action"
}
]
},
{
"name": "WelcomeIntent",
"samples": [],
"slots": []
},
{
"name": "WhatIsIntent",
"samples": [
"what is {element}"
],
"slots": [
{
"name": "element",
"type": "element"
}
]
}
],
"invocationName": "my assistant"
}
}

Related

Filtering Arrays in NodeJS without knowing where the value's location is

I'm working on this project that should scrape websites and output HTML in the form of a JSON, now the only useful things in those JSONs to us are "forms".
I wanted to filter that but the native array filter only works when I know the attribute's location relative to the entire page (DOM??) but that won't always be the case, and I fear checking every object's value till I reach the desired value isn't viable due to
some pages being humongous,
form being a string in other places we don't want, this is in NodeJS
Snippet of input:
[
{
"type": "element",
"tagName": "p",
"attributes": [],
"children": [
{
"type": "text",
"content": "This is how the HTML code above will be displayed in a browser:"
}
]
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "form",
"attributes": [
{
"key": "action",
"value": "/action_page.php"
},
{
"key": "target",
"value": "_blank"
}
],
"children": [
{
"type": "text",
"content": "\nFirst name:"
},
{
"type": "element",
"tagName": "br",
"attributes": [],
"children": []
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "input",
"attributes": [
{
"key": "type",
"value": "text"
},
{
"key": "name",
"value": "firstname0"
},
{
"key": "value",
"value": "John"
}
],
"children": []
},
{
"type": "element",
"tagName": "br",
"attributes": [],
"children": []
},
{
"type": "text",
"content": "\nLast name:"
},
{
"type": "element",
"tagName": "br",
"attributes": [],
"children": []
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "input",
"attributes": [
{
"key": "type",
"value": "text"
},
{
"key": "name",
"value": "lastname0"
},
{
"key": "value",
"value": "Doe"
}
],
"children": []
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "br",
"attributes": [],
"children": []
},
{
"type": "element",
"tagName": "br",
"attributes": [],
"children": []
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "input",
"attributes": [
{
"key": "type",
"value": "submit"
},
{
"key": "value",
"value": "Submit"
}
],
"children": []
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "input",
"attributes": [
{
"key": "type",
"value": "reset"
}
],
"children": []
},
{
"type": "text",
"content": "\n"
}
]
},
{
"type": "text",
"content": "\n"
}
]
A snippet of output:
[
{
"type": "element",
"tagName": "form",
"attributes": [
{
"key": "action",
"value": "/action_page.php"
},
{
"key": "target",
"value": "_blank"
}
],
"children": [
{
"type": "text",
"content": "\nFirst name:"
},
{
"type": "element",
"tagName": "br",
"attributes": [],
"children": []
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "input",
"attributes": [
{
"key": "type",
"value": "text"
},
{
"key": "name",
"value": "firstname0"
},
{
"key": "value",
"value": "John"
}
],
"children": []
},
{
"type": "element",
"tagName": "br",
"attributes": [],
"children": []
},
{
"type": "text",
"content": "\nLast name:"
},
{
"type": "element",
"tagName": "br",
"attributes": [],
"children": []
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "input",
"attributes": [
{
"key": "type",
"value": "text"
},
{
"key": "name",
"value": "lastname0"
},
{
"key": "value",
"value": "Doe"
}
],
"children": []
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "br",
"attributes": [],
"children": []
},
{
"type": "element",
"tagName": "br",
"attributes": [],
"children": []
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "input",
"attributes": [
{
"key": "type",
"value": "submit"
},
{
"key": "value",
"value": "Submit"
}
],
"children": []
},
{
"type": "text",
"content": "\n"
},
{
"type": "element",
"tagName": "input",
"attributes": [
{
"key": "type",
"value": "reset"
}
],
"children": []
},
{
"type": "text",
"content": "\n"
}
]
}
]
TL;DR: only retain forms and any of its children.
First of all, this input looks like very incomplete, it may be an array or an object. If I assume it's an array of objects, then I can use jsonpath to access any of the values.
var jp = require('jsonpath');
var formNodes = jp.query(nodes, `$..[?(#.tagName=="form")]`);
You can achive the same using vanila javascript, there was several stackoverflow questions for that. But I found jsonpath and xpath being easier to implement than those.

How to fix "it doesn't support that" when I query Alexa retrievable property

I have this endpoint with powerState and connectivity properties both retrievable:
{
"endpointId": "123",
"manufacturerName": "abc",
"friendlyName": "lamp",
"description": "lamp",
"displayCategories": [
"LIGHT"
],
"capabilities": [
{
"type": "AlexaInterface",
"interface": "Alexa.PowerController",
"version": "3",
"properties": {
"supported": [{
"name": "powerState"
}],
"retrievable": true
}
},
{
"type": "AlexaInterface",
"interface": "Alexa.EndpointHealth",
"version": "3",
"properties": {
"supported": [{
"name": "connectivity"
}],
"retrievable": true
}
}
],
"cookie": {}
}
I respond to ReportState request by sending the state of both properties:
{
"context": {
"properties": [
{
"namespace": "Alexa.PowerController",
"name": "powerState",
"value": "ON",
"timeOfSample": "2019-01-10T10:17:19.99Z",
"uncertaintyInMilliseconds": 50
},
{
"namespace": "Alexa.EndpointHealth",
"name": "connectivity",
"value": {
"value": "OK"
},
"timeOfSample": "2019-01-10T10:17:19.90Z",
"uncertaintyInMilliseconds": 50
}
]
},
"event": {
"header": {
"namespace": "Alexa",
"name": "StateReport",
"payloadVersion": "3",
"messageId": "cde",
"correlationToken": "efg123"
},
"endpoint": {
"scope": {
"type": "BearerToken",
"token": "ab123"
},
"endpointId": "123",
"cookie": {}
},
"payload": {}
}
}
And I send the same context in the PowerController response.
In the Alexa app I can see my device, turn it on and off and view its state rightly. I can ask Alexa to turn on and off my device and the response in "OK", but if I try to ask:** "Is my device turned on?" ** Alexa answers that this device doesn't support that.
The skill language is Italian and PowerController documentation https://developer.amazon.com/it/docs/device-apis/alexa-powercontroller.html says that query is supported.
What am I missing?

Why does Alexa SDK throw an error when migrating from Dialogflow

I'm trying to migrate my action form Dialogflow, and the most important thing is the intent schema. But after uploading the .json file, the error Intent name must not be empty. Error code: MissingIntentName is thrown. Here is Intent schema.json
{
"intents": [
{
"intent": "SelectedSubjectsYes"
},
{
"intent": "UserIsOk",
"slots": [
{
"name": "okslot",
"type": "OK"
}
]
},
{
"intent": "SelectedSubjectsNo"
},
{
"intent": "UserIsNotOk",
"slots": [
{
"name": "not_okslot",
"type": "NOT_OK"
}
]
},
{
"intent": "DefaultWelcomeIntent"
},
{
"intent": "HowAreYou?"
},
{
"intent": "SelectedSubjects",
"slots": [
{
"name": "subjectslot",
"type": "SUBJECT"
}
]
}
]
}
I've in no way edited it, so why the error? Thanks in advance.
The JSON structure for interaction model is sightly different. This is how it should look now.
{
"interactionModel": {
"languageModel": {
"invocationName": "Your invocation name",
"intents": [
{
"name": "SelectedSubjectsYes",
"slots": [],
"samples": [
"provide sample for SelectedSubjectsYes intent",
"sample for SelectedSubjectsYes intent"
]
},
{
"name": "UserIsOk",
"slots": [
{
"name": "okslot",
"type": "OK"
}
],
"samples": [
"provide other samples for UserIsOk",
"I'm {okslot}",
"{okslot}"
]
},
{
"name": "SelectedSubjectsNo",
"slots": [],
"samples": [
"provide sample for SelectedSubjectsNo intent",
"sample for SelectedSubjectsNo intent"
]
},
{
"name": "UserIsNotOk",
"slots": [
{
"name": "not_okslot",
"type": "NOT_OK"
}
],
"samples": [
"provide other samples for UserIsNotOk",
"i'm {not_okslot}",
"{not_okslot}"
]
},
{
"name": "HowAreYou?",
"slots": [],
"samples": [
"provide sample for HowAreYou intent",
"sample for HowAreYou intent"
]
},
{
"name": "SelectedSubjects",
"slots": [
{
"name": "subjectslot",
"type": "SUBJECT"
}
],
"samples": [
"provide other samples for SelectedSubjects",
"i choose {subjectslot}"
]
}
],
"types": [
{
"name": "OK",
"values": [
{
"name": {
"value": "ok"
}
},
{
"name": {
"value": "yes"
}
}
]
},
{
"name": "NOT_OK",
"values": [
{
"name": {
"value": "not ok"
}
},
{
"name": {
"value": "nope"
}
}
]
},
{
"name": "SUBJECT",
"values": [
{
"name": {
"value": "Physics"
}
},
{
"name": {
"value": "Biology"
}
}
]
}
]
}
}
}
Rather than converting from Dialog flow, it's pretty easy to design one in Alexa skill builder. Also, it is recommended to use predefined AMAZON.YesIntent and AMAZON.NoIntent for "yes" or "no" utterances.

Amazon Alexa Entity Resolution

I am having trouble getting Alexa to understand any synonyms for the words I'm speaking to her. She will always return that she does not know the meaning of the synonym despite having added it as part of the intent schema:
{
"languageModel": {
"types": [
{
"name": "LIST_OF_DEFINITIONS",
"values": [
{
"id": "USER_EXPERIENCE",
"name": {
"value": "user experience",
"synonyms": [
"ux"
]
}
}
]
}
],
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.RepeatIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "RecipeIntent",
"samples": [
"what is a {Definition}"
],
"slots": [
{
"name": "Definition",
"type": "LIST_OF_DEFINITIONS"
}
]
}
],
"invocationName": "digital dictionary"
}
}
Am I missing something?
Your synonym "ux" isn't going to be understood because the user won't pronounce it like a word but rather they will say two letters. So, try adding "u x" and "U.X.". That should work.

Adaptive Cards doesn't work in MBF's Emulator running in Ubuntu 16.04

I am trying to implement AdaptiveCard into one of my dialogs using node.js. However once I run the emulator I get the following message instead of rendered AdaptiveCard:
[File of type 'application/vnd.microsoft.card.adaptive'].
Can anyone tell me what can be the problem?
I am running on Ubuntu 16.04, MBF Emulator v.3.5.31-alpha, microsoft-adaptivecards v.0.6.1.
Here is code from inside of one of my dialogs:
var msg = new builder.Message(session)
.addAttachment({
contentType: "application/vnd.microsoft.card.adaptive",
content: {
type: "AdaptiveCard",
body: [
{
"type": "TextBlock",
"text": msg_text,
},
{
"type": "Input.ChoiceSet",
"id": "myColor4",
"isMultiSelect": true,
"value": "1",
"style": "expanded",
"choices": [
{
"title": "Red",
"value": "1",
"isSelected": true
},
{
"title": "Green",
"value": "2"
},
{
"title": "Blue",
"value": "3",
"isSelected": true
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Sent",
"data": {
"myProperty": 12
}
}
],
}
});
session.send(msg);
This is detailed response, it contains all elements of the AdaptiveCard that I declared(but still it does not render):
{
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "What color do you want?"
},
{
"type": "Input.ChoiceSet",
"id": "myColor4",
"isMultiSelect": true,
"value": "1",
"style": "expanded",
"choices": [
{
"title": "Red",
"value": "1",
"isSelected": true
},
{
"title": "Green",
"value": "2"
},
{
"title": "Blue",
"value": "3",
"isSelected": true
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Sent",
"data": {
"myProperty": 12
}
}
]
}
}
],
"locale": "en-US",
"localTimestamp": "2017-09-17T19:21:17+02:00",
"from": {
"id": "default-bot",
"name": "Bot"
},
"recipient": {
"id": "default-user"
},
"inputHint": "acceptingInput",
"id": "heam84b9dn5b",
"replyToId": "71j1d6mbmk3l",
"channelId": "emulator",
"timestamp": "2017-09-17T17:21:17.379Z",
"conversation": {
"id": "fdikc23llm5"
}
}

Resources