How to use Dialog.ElicitSlot for Python as Runtime environment - alexa

I want to fill a slot not at the beginning of the invocation of the intent, but at a later part in the intent request. I want to provide user some options, and I want them to select one out of those. For that I'm trying to use Dialog.ElicitSlot, but somehow I'm getting an error :
"Request to skill endpoint resulted in an error."
I'm returning this when I need the user to select an option from my list.
return {
"version": "1.0",
"sessionAttributes": {},
"response": {
"outputSpeech": {
"type": "PlainText",
"text": "These are the multiplex" + ("es" if len(multi_list) > 1 else "") + " " + outputSpeech + ". Please select one out of these."
# outputSpeech contains the list of options I want the user to select from
},
"shouldEndSession": False,
"directives": [
{
"type": "Dialog.ElicitSlot",
"slotToElicit": "MULTIPLEX",
"updatedIntent": {
"name": "GetMovieDetails",
"confirmationStatus": "NONE",
"slots": {
"CITY" : {
"name" : "CITY",
"confirmationStatus" : "NONE",
"value" : city # this is already filled, it is just anti-capitalised
},
"NAME" : {
"name" : "NAME",
"confirmationStatus" : "NONE",
"value" : movie_name # this is already filled, it is just anti-capitalised
},
"MULTIPLEX" : {
"name" : "MULTIPLEX",
"confirmationStatus" : "NONE",
}
}
}
}
]
}
I'm testing my skill using python-lambda-local, it is working fine on my local machine (I just had to change the dialogState to "COMPLETED" manually, like the one here). It returns everything written above. But It gives an error while testing it on Skill Tester. Here is the output which is returned in the Skill Tester.
PS : I did not check the Slot Filling check box in the Build Section. (As I need the slot to be filled later), and here is the complete code just in case.

Try with omitting the entire "updatedIntent" part, as this information is not required for ElicitSlot.
But more important: You have to make sure that your script returns actual text in JSON-format!
Have a look at http://flask.pocoo.org/docs/1.0/api/#flask.json.jsonify
or https://docs.python.org/2/library/json.html

God, I hate to admit this.
The Dialog.ElicitSlot works fine, and the way I expect it to do so.
The error with my code is, there is no error. I figured my skill was taking some time to fetch data from remote site and doing some calculations on it. So I increased the time out and bam, it worked.
It is always a better to test your skill locally, but it is great to test it once on the aws lambda console. I don't know why I didn't do that earlier.
So to conclude, I just had to increase the timeout in my skill.

Related

How to get Resource Group name from within Logic App

In an Azure Logic App, how can I get the name of the Resource Group containing the current logic app?
I want to include some tracking details in the JSON output that I am sending to another system.
I can get the run Identifier ( using #{workflow()['run']['name']} ),
and the current logic app name ( using #{workflow()['name']} )
However, I cant work out how to get the name of the resource group to which the logic app is deployed.
As a last resort, I will use the resource group name used by the deployment template, but that will be wrong if the logic app is moved later.
I could also use tags, but again that could get out of step if the logic app is moved.
Thanks
A simple formula may be:
split(workflow().id, "/")[4]
If you're deploying the Logic Apps using ARM templates (e.g. edit in Visual Studio, check into Azure DevOps git repo and deploy using release pipeline), you can create an ARM parameter:
"resGroup_ARM": {
"type": "string",
"defaultValue": "[resourceGroup().name]",
"metadata": {
"description": "Resouce group name"
}
}
Then, you can create a workflow parameter:
"resGroup_LA": {
"type": "string",
"defaultValue": "ResGroup LA default"
}
... and give it a value in the parameters initialisation section:
"resGroup_LA": {
"value": "[parameters('resGroup_ARM')]"
}
You can get all the other properties of resourceGroup() in a similar manner, see: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-resource?tabs=json#resourcegroup
First we can create a "Initialize variable" action to get all of the data in workflow, shown as below screenshot:
Then we can find the data in workflow is:
{
"id": "/subscriptions/*****/resourceGroups/huryTest/providers/Microsoft.Logic/workflows/hurylogicblob",
"name": "hurylogicblob",
"type": "Microsoft.Logic/workflows",
"location": "eastus",
"tags": {},
"run": {
"id": "/subscriptions/*****/resourceGroups/huryTest/providers/Microsoft.Logic/workflows/hurylogicblob/runs/*****",
"name": "*****",
"type": "Microsoft.Logic/workflows/runs"
}
}
It contains the resource group name, so we just need to get the property "id" and substring it to get resource group name. The length of "resourceGroups/" is 15, so in the expression below I use add(,15) and sub(,15).
You can use the expression as below:
substring(workflow()['id'],add(indexOf(workflow()['id'],'resourceGroups/'),15),sub(sub(indexOf(workflow()['id'],'/providers'),indexOf(workflow()['id'],'resourceGroups/')),15))
At last, I got the resource group name of the logic app:

MS Flow (Azure) and Double quote

I hope you can help me as I'm a little stuck on this problem and cannot find a nice solution.
I would like to create an HTTP POST and the body of my request need to be something like this
.... (code)
{
"table":"DimDate"
}
.... (code)
The "table" : "Dimdate" is built , part by a string variable ( myVar='{"table":"' ) and a dynamic field (all stored on another string variable called myString).
Meaning I've got on my MS Flow a variable myString = "table": "DimDate"
Till there no issue. My problem appear when I want to embed my variable in the body of the HTTP Post.
It seems all is converted as
.... (code)
{
\"table\":\"DimDate\"
}
.... (code)
Question is why do I have those "\" ? and how to remove them ?
I've check and it seems they appear by default from the start , in my different variables. How to remove them when I use the variable myString in the HTTP POST body ?
I've already try to convert to plain-text, look for use char (no idea how), etc...
Any idea ?
Thanks
Addendum
a) Idea is to be able to add in the body of my HTTP POST the following body
{
"CommitMode": "transactional",
"MaxParallelism": 2,
"Objects": [
{ "Table": "table1" },
{ "Table": "table2"},
{ "Table": "table3"}
],
"RetryCount": 2,
"Type": "Full"
}
b) For that I set an initial variable _mystring as '{"table":"'
c) with a loop I put in a variable _myVar a concatenation of _mystring with a array of table ( table1,2 and 3) . the variable _myVar at the end is ok. No issue there
d) the HTTP POST body appear on the screen "as this" :
{
"CommitMode": "transactional",
"MaxParallelism": 4,
"Objects": [
{
"Table": "#{variables('_Table')}"
}
],
"RetryCount": 2,
"Type": "Full"
}
e) Like that all appear perfect. The problem is that when I run the flow, the body of the HTTP is not OK as even the variable _mystring which is used. It seems the " is replaced by \" and this generate a wrong output of the HTTP POST.
Is there a way to avoid Microsoft Flow replace the " by \" ?
Miguel
Finally an easy solution was found.
Microsoft fix that during their next Logic App release.
Topic close

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.

ARM template array parameter

I have an ARM template with a web app alerting rule, where I want to be able to configure which e-mails get the alerts.
The snippet for the e-mail alerting action is this:
"action": {
"odata.type": "Microsoft.Azure.Management.Insights.Models.RuleEmailAction",
"sendToServiceOwners": false,
"customEmails": [
"email1#example.com",
"email2#example.com"
]
}
The same template is used for setting up production, test, and dev environments. So I would like to use a parameter for the e-mail alerting.
How can I generate an array to be used as the "customEmails" property based on either a comma separated string, or an array type parameter?
I have tried "customEmails": "[array(parameters('AlertEmailRecipients'))]", and also
"customEmails": [
[array(parameters('AlertEmailRecipients'))]
]
but neither work. I don't know how to tell it that the "customEmails" property value should come from a parameter.
I used the following using an array parameter:
parameter declaration:
"customEmails": {
"type": "array",
"metadata": {
"description": "alert email addressess"
}
}
in the parameters file:
"customEmails": {
"value": [
"email1#domain.com",
"email2#domain.com"
]
}
usage:
"customEmails": "[parameters('customEmails')]"
I found a solution. The main problem was that my comma separated list of e-mail addresses had a space after each comma.
The way I have implemented it now is like this:
Define a string parameter with a comma separated list of e-mail addresses. Don't have spaces in the list.
Define a variable like this:
"customEmails" : "[split(parameters('AlertEmailRecipients'), ',')]"
and then reference that variable in the alerting action:
"action": {
"odata.type": "Microsoft.Azure.Management.Insights.Models.RuleEmailAction",
"sendToServiceOwners": false,
"customEmails": "[variables('customEmails')]"
}
The example actually does this, but doesn't make it clear the the list of e-mails can't contain spaces.

What is the meaning here list in array calling

Below I have environment file and recipe can you explain I am not getting what is the list here.
{
"json_class": "Chef::Environment",
"description": "prod environment",
"default_attributes": {
},
"chef_type": "environment",
"override_attributes": {
"user": {
"mapr": {
"id": "application",
"group": "application",
},
"local" : {
"id": "chef",
"group": "chef"
},
"ldap" : {
"id": "ldap",
"sudo": true,
},
}
"name": "prod"
}
Below is the recipe what is the list here i did not get
node['user_create'].each do |list, user|
group user['group'] do
group_name user['group']
gid user['gid']
action [:create]
ignore_failure true
end
user user do
username user['id']
uid user['uid']
group user['gid']
home user['home']
manage_home true
end
if list !='ldap'
How list is passing here in if condition
You are not actually passing in any attributes via the environment, which you can see because the values of default_attributes and override_attributes are both just empty hashes { }. The data you've included there is just ignored by Chef as noise. In the future I recommend you use the Ruby DSL for environment files as it has more error checking for things like this (though not perfect error checking).
As an aside, you've been asking a lot of questions on here and seem to be struggling with Chef. Please consider joining the Chef community Slack team and asking there instead as it's a full chat system and thus the community could offer real-time help rather than here random blurbs.

Resources