Actions on Google BrowserCarousel Not Rendering Properly - dialogflow-es

I'm using DialogFlow custom fulfilment with the actions-on-google library to build out a bot. The bot seems to be working perfectly fine but when I test it on a device, my BrowserCarousel responses are not rendering properly:
Shows up like this on the Actions On Google Simulator...
...and like this on Google Assistant on my test device.
Here's my fulfilment code:
const {
dialogFlow,
SimpleResponse,
Image,
BrowseCarousel,
BrowseCarouselItem,
LinkOutSuggestion,
Suggestions,
BasicCard
} = require('actions-on-google');
require('isomorphic-fetch');
module.exports = (conv, params) => {
// LOGIC: (1) GraphQL query fetches all pages with the tag
// (2) Filter by exact tag matches first
// (3) Add partial matches.
// (4) If no tag matches, put a custom message.
// (5) Add all cards to a custom Payload.
let search_term = params.search_term;
return new Promise((resolve, reject) => {
fetch('https://www.nayimanzil.com/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: '{ pages(last: 100) { nodes { title link tags(last: 10) { edges { node { name } } } featuredImage { sourceUrl } } } }' }),
})
.then(res => res.json())
.then(res => {
let filter_exact = new Array();
let filter_extend = new Array();
//console.log((res.data.pages.nodes.length));
for(var i=0; i<res.data.pages.nodes.length; i++) {
let extend_switch = false;
for(var j=0; j<res.data.pages.nodes[i].tags.edges.length; j++) {
let tag_name = res.data.pages.nodes[i].tags.edges[j].node.name;
/*console.log(i + " - " + j);
console.log(tag_name + " - " + search_term + (tag_name == search_term));
console.log(tag_name + " - " + search_term + (tag_name.includes(search_term)));*/
if(tag_name == search_term)
filter_exact.push(res.data.pages.nodes[i]);
else if(tag_name.includes(search_term) && extend_switch==false){
filter_extend.push(res.data.pages.nodes[i]);
extend_switch = true;
}
}
}
let carousel_items = new Array();
let share_chips = new Array();
let filter_joined = filter_exact.concat(filter_extend);
console.log("Filter Joined Length: " + filter_joined.length);
console.log(filter_joined);
for(var k=0; k<filter_joined.length; k++){
carousel_items.push(new BrowseCarouselItem({
title: filter_joined[k].title,
url: filter_joined[k].link,
image: new Image({
url: ((filter_joined[k].featuredImage==null) ? 'https://www.nayimanzil.com/wp-content/uploads/2018/06/nayimanzil-template.jpg' : filter_joined[k].featuredImage.sourceUrl),
// url: filter_joined[i].featuredImage.sourceUrl,
alt: "Search Result " + (k+1)
}),
footer: filter_joined[k].title,
description: filter_joined[k].title
}));
// FB share format -
// https://www.facebook.com/dialog/feed?app_id=288644845112477&link=https://www.nayimanzil.com&picture=https://www.nayimanzil.com/wp-content/uploads/2018/05/love009-landscape.jpg&name=NAME&description=DESCRIPTION&caption=CAPTION&redirect_uri=REDIRECT_URI
share_chips.push(new LinkOutSuggestion({
name: "Link " + (k+1),
url: "https://www.facebook.com/dialog/feed?app_id=288644845112477&link=" + filter_joined[k].link + "&picture="
+ ((filter_joined[k].featuredImage==null) ? 'https://www.nayimanzil.com/wp-content/uploads/2018/06/nayimanzil-template.jpg' : filter_joined[k].featuredImage.sourceUrl)
+ "&redirect_uri=https://www.nayimanzil.com"
}));
if(k>1) break;
}
conv.ask("खुशखबरी! मुझे कुछ लेख मिल गए।");
if(filter_joined.length<2){
conv.ask(new BasicCard({
title: filter_joined[0].title,
url: filter_joined[0].link,
image: new Image({
url: ((filter_joined[0].featuredImage==null) ? 'https://www.nayimanzil.com/wp-content/uploads/2018/06/nayimanzil-template.jpg' : filter_joined[0].featuredImage.sourceUrl),
alt: "Search Result 1"
}),
footer: filter_joined[0].title,
description: filter_joined[0].title
}));
}
else {
conv.ask(new BrowseCarousel({
items: carousel_items
}));
}
conv.ask("आप कौन सा लेख शेयर करना चाहते हैं?");
console.log("share_chips.length = " + share_chips.length);
for(var i=0; i<filter_joined.length; i++) {
conv.ask(new LinkOutSuggestion({
name: "Link " + (i+1),
url: "https://www.facebook.com/dialog/feed?app_id=288644845112477&link=" + filter_joined[i].link + "&picture="
+ ((filter_joined[i].featuredImage==null) ? 'https://www.nayimanzil.com/wp-content/uploads/2018/06/nayimanzil-template.jpg' : filter_joined[i].featuredImage.sourceUrl)
+ "&redirect_uri=https://www.nayimanzil.com"
}));
if(i>1) break;
}
return resolve();
});
});
}
And here's the response JSON:
{
"conversationToken": "[\"search-articles_followup\"]",
"expectUserResponse": true,
"expectedInputs": [
{
"inputPrompt": {
"richInitialPrompt": {
"items": [
{
"simpleResponse": {
"textToSpeech": "खुशखबरी! मुझे कुछ लेख मिल गए।"
}
},
{
"carouselBrowse": {
"items": [
{
"title": "शादी से पहले सेक्स? क्या है सही सोच?",
"description": "शादी से पहले सेक्स? क्या है सही सोच?",
"footer": "शादी से पहले सेक्स? क्या है सही सोच?",
"image": {
"url": "https://www.nayimanzil.com/wp-content/uploads/2018/05/love007-square.jpg",
"accessibilityText": "Search Result 1"
},
"openUrlAction": {
"url": "https://www.nayimanzil.com/%e0%a4%b6%e0%a4%be%e0%a4%a6%e0%a5%80-%e0%a4%b8%e0%a5%87-%e0%a4%aa%e0%a4%b9%e0%a4%b2%e0%a5%87-%e0%a4%b8%e0%a5%87%e0%a4%95%e0%a5%8d%e0%a4%b8-%e0%a4%95%e0%a5%8d%e0%a4%af%e0%a4%be-%e0%a4%b9%e0%a5%88/"
}
},
{
"title": "क्या है शादी टूटने के कारण? आज की संस्कृति में शादी बचाने के 7 उपाय।",
"description": "क्या है शादी टूटने के कारण? आज की संस्कृति में शादी बचाने के 7 उपाय।",
"footer": "क्या है शादी टूटने के कारण? आज की संस्कृति में शादी बचाने के 7 उपाय।",
"image": {
"url": "https://www.nayimanzil.com/wp-content/uploads/2018/06/nayimanzil-template.jpg",
"accessibilityText": "Search Result 2"
},
"openUrlAction": {
"url": "https://www.nayimanzil.com/%e0%a4%b6%e0%a4%be%e0%a4%a6%e0%a5%80-%e0%a4%9f%e0%a5%82%e0%a4%9f%e0%a4%a8%e0%a5%87-%e0%a4%95%e0%a5%87-%e0%a4%95%e0%a4%be%e0%a4%b0%e0%a4%a3/"
}
},
{
"title": "सच्चा प्यार क्या है? आओ जाने इसके गुण और निशानियां।",
"description": "सच्चा प्यार क्या है? आओ जाने इसके गुण और निशानियां।",
"footer": "सच्चा प्यार क्या है? आओ जाने इसके गुण और निशानियां।",
"image": {
"url": "https://www.nayimanzil.com/wp-content/uploads/2018/05/love001-square.jpg",
"accessibilityText": "Search Result 3"
},
"openUrlAction": {
"url": "https://www.nayimanzil.com/%e0%a4%b8%e0%a4%9a%e0%a5%8d%e0%a4%9a%e0%a4%be-%e0%a4%aa%e0%a5%8d%e0%a4%af%e0%a4%be%e0%a4%b0-%e0%a4%95%e0%a5%8d%e0%a4%af%e0%a4%be-%e0%a4%b9%e0%a5%88/"
}
}
]
}
},
{
"simpleResponse": {
"textToSpeech": "आप कौन सा लेख शेयर करना चाहते हैं?"
}
}
],
"linkOutSuggestion": {
"url": "https://www.facebook.com/dialog/feed?app_id=288644845112477&link=https://www.nayimanzil.com/%e0%a4%b8%e0%a4%9a%e0%a5%8d%e0%a4%9a%e0%a4%be-%e0%a4%aa%e0%a5%8d%e0%a4%af%e0%a4%be%e0%a4%b0-%e0%a4%95%e0%a5%8d%e0%a4%af%e0%a4%be-%e0%a4%b9%e0%a5%88/&picture=https://www.nayimanzil.com/wp-content/uploads/2018/05/love001-square.jpg&redirect_uri=https://www.nayimanzil.com",
"destinationName": "Link 3"
}
}
},
"possibleIntents": [
{
"intent": "assistant.intent.action.TEXT"
},
{
"intent": "d99a58da-d9fc-4762-ae0c-ad9d3ec30d7a"
}
],
"speechBiasingHints": [
"$search_term"
]
}
],
"responseMetadata": {
"status": {
"message": "Success (200)"
},
"queryMatchInfo": {
"queryMatched": true,
"intent": "d99a58da-d9fc-4762-ae0c-ad9d3ec30d7a",
"parameterNames": [
"search_term"
]
}
}
}
Also, I've created three LinkOutSuggestion objects but only one appears.
Any ideas what I'm doing wrong?

Related

Pagination doesn't work with datatables and nodejs/elasticsearch implementation

I'm using nodejs as back/front-end implementation for a quick UI overview of an index in nodejs, and I'd like to use datatables with server side processing to display the data in a properly formated table.
It grabs all of the data fine, however it just dumps all of the records into one page on the table.
Model:
const { Client } = require('#elastic/elasticsearch')
const client = new Client({
node: '',
auth: {
username: '',
password: ''
}
})
module.exports = function getElasticData(callback/*, size*/) {
//parseInt(inputSize) = size;
client.search({
index: 'anomalies02_bhc-lstm2',
size: 10000,
body: {
query: {
match_all: {}
}
}
}, function (error, response, status) {
if (error) {
console.log("search error: " + error)
}
if (response) {
var elasticList = [];
//console.log("EL:" + JSON.stringify(response))
response.body.hits.hits.forEach(function (hit) {
elasticList.push(hit);
})
//callback(elasticList.sort());
//console.log("SORTED LIST: " + JSON.stringify(elasticList))
callback(elasticList);
}
else {
console.log("<p>No results</p>");
}
});
}
Controller:
var elasticDataModel = require('../model/getDataElastic');
exports.getData = function (req, res) {
elasticDataModel(function (elasticList) {
var searchStr = req.body.search.value;
var recordsTotal = 0;
var recordsFiltered = 0;
var size = parseInt(req.body.length);
var recordsFiltered = elasticList.slice(0, size)
console.log("LENGTH: " + JSON.stringify(req.body.length))
console.log("FILTERED: " + JSON.stringify(recordsFiltered))
//console.log(elasticList[0]._source);
console.log(typeof parseInt(req.body.draw))
console.log(elasticList.length)
recordsTotal = elasticList.length;
//console.log("DRAW " + req.body.draw);
var data = JSON.stringify({
"data": elasticList,
"draw": parseInt(req.body.draw),
"recordsTotal": recordsTotal,
"recordsFiltered": recordsFiltered
});
res.send(data);
});
}
HTML:
$(document).ready(function () {
var t = $('#example2').DataTable({
"paging": true,
"processing": true,
"serverSide": true,
'ajax': {
'type': 'POST',
'url': '/populateData'
},
'pageLength': 20,
'lengthMenu': [5, 10, 20, 50, 100, 200, 500],
'columns':
[
{ 'data': '_id', "defaultContent": "", 'name': 'ID' },
{ "defaultContent": "", 'name': 'Kibana Link' },
{ 'data': '_source.Environment', "defaultContent": "", 'name': 'Environment' },
{ 'data': '_source.Cause', "defaultContent": "", 'name': 'Downtime cause' },
{ 'data': '_source.Start', "defaultContent": "", 'name': 'Detected start' },
{ 'data': '_source.End', "defaultContent": "", 'name': 'Detected end' },
{ "defaultContent": "", 'name': 'Actual start' },
{ "defaultContent": "", 'name': 'Actual end' },
{ "defaultContent": "", 'name': 'Reason category' },
{ "defaultContent": "", 'name': 'Reason details' },
{ "defaultContent": "", 'name': 'Submit' },
],
"columnDefs": [
{
"searchable": true,
"orderable": true,
"targets": 0
}
]
});
});
I modifed my code accordingly with help from Kevin at the datatables forums and now it works flawlessly.
Changed code:
Controller
var elasticDataModel = require('../model/getFilteredDataElastic');
var pageLength;
var pageStart;
exports.getData = function (req, res) {
pageLength = req.body.length;
pageStart = req.body.start
console.log("MODEL Length: " + pageLength)
elasticDataModel(pageLength, pageStart, function (elasticFilteredList) {
var searchStr = req.body.search.value;
var recordsTotal = 0;
var recordsFiltered = 0;
console.log("PAGE LENGTH: " + pageLength)
if (req.body.search.value) {
var regex = new RegExp(req.body.search.value, "i")
searchStr = { $or: [{ '_id': regex }, { 'Environment': regex }, { 'Downtime cause': regex }, { 'Detected start': regex }, { 'Detected end': regex }, { 'Reason details': regex }] };
}
else {
searchStr = {};
}
var size = parseInt(req.body.length);
var recordsFiltered = elasticFilteredList
var data = JSON.stringify({
"data": elasticFilteredList,
"draw": parseInt(req.body.draw),
"recordsTotal": elasticFilteredList[0],
"recordsFiltered": recordsFiltered
});
res.send(data);
});
}
Model:
const { Client } = require('#elastic/elasticsearch')
const client = new Client({
node: '',
auth: {
username: '',
password: ''
}
})
module.exports = function getElasticData(arg, arg2, callback) {
console.log("CONTROLLER SIZE: " + arg)
console.log("CONTROLLER FROM: " + arg2)
client.search({
index: 'anomalies02_bhc-lstm2',
from: arg2,
size: arg,
body: {
query: {
match_all: {}
}
}
}, function (error, response, status) {
if (error) {
console.log("search error: " + error)
}
if (response) {
var elasticFilteredList = [];
console.log("VALUE: " + response.body.hits.total.value);
elasticFilteredList.push(response.body.hits.total.value);
response.body.hits.hits.forEach(function (hit) {
elasticFilteredList.push(hit);
})
callback(elasticFilteredList);
}
else {
console.log("<p>No results</p>");
}
});
}

Can chrome extension context menu (for links) extract the link content before it popups up?

I want to create a context menu item depending on what the context link is.
For instance, I want to display "AAA" for a link that starts with "https://www.google.com" and "BBB" for a link that starts with "https://twitter.com".
var context_twitter_search = chrome.contextMenus.create({
"title":'AAA', // This is what I want to change depending on the info.linkUrl.
"contexts":["link"],
"onclick":function(info, tab) {
var target_content = '';
target_content = info.linkUrl; // I can ONLY get the content after right-click.
chrome.tabs.create({url:"https://twitter.com/search?q="+target_content});
}
});
Try this in your background script:
function onClickHandler(info, tab) {
let tp = info.menuItemId;
let url = info.linkUrl;
switch (tp) {
case 'AAA':
alert('hi google user');
break;
case 'BBB':
alert('hi Tweeter user');
break;
}
}
function handleInstalled(details) {
var contextMenuItem = [
{
"id": "AAA",
"title": "AAA",
"contexts": ["link"],
"targetUrlPatterns": ["https://*.google.com/*"]
}, {
"id": "BBB",
"title": "BBB",
"contexts": ["link"],
"targetUrlPatterns": ["https://*.twitter.com/*"]
}
];
let cmi;
for (let k = 0; k < contextMenuItem.length; k++) {
cmi = contextMenuItem[k];
chrome.contextMenus.create({
"id": cmi.id,
"title": cmi.title,
"contexts": cmi.contexts,
"enabled": true,
"targetUrlPatterns": cmi.targetUrlPatterns
}, () => {
if (chrome.runtime.lastError) {}
else {}
})
}
chrome.contextMenus.onClicked.addListener(onClickHandler)
}
chrome.runtime.onInstalled.addListener(handleInstalled);

How to convert for urlencoded array into json in node js

I am having a form-urlencoded request as follows:
but I have to convert this request in json as follows:
{
"version":4.2,
"auth_token": "xxxxxxxx",
"zcontacts":[
{ "phone": "xxxxx", "name": "xxxx" },
{ "phone": "112", "name": "Distress Number" },
{ "phone": "1800-300-xxxx", "name": "UIDAI" },
{ "phone": "44 xxxxx, "name": "Ab zz" }
]
}
Here below is my code which I am trying:
index(req_data) {
const self = this;
return new Promise((resolve, reject) => {
console.log(typeof req_data)
let req_body = {}
req_body.version = req_data.version;
req_body.auth_token = req_data.auth_token;
let contacts_list = [];
return Promise.each(req_data.zcontacts,(contact, key, length) => {
// Logic starts from here
if(key === 0) {
contacts_list.push({
phone: req_data.zcontacts[key],
name: req_data.zcontacts[(key+1)]
})
} else if(key > 0) {
contacts_list.push({
phone: req_data.zcontacts[(key+3)],
name: req_data.zcontacts[(key+4)]
})
}
}).then(() => {
req_body.zcontacts = contacts_list;
resolve(req_body)
});
Can anyone suggest what should be changed in the code under the loop?
I got it:
return Promise.each(req_data.zcontacts,(contact, key, length) => {
if(key % 2 === 0) {
contacts_list.push({
phone: req_data.zcontacts[key],
name: req_data.zcontacts[(key+1)]
})
}
}).then(() => {
req_body.zcontacts = contacts_list;
resolve(req_body)
});

Alexa Skill Learning: TypeError: Cannot read property 'value' of undefined

I keep getting an error when I try to test my basic skill (I'm trying to learn how to create them).
Here is the error from the log:
2018-11-21T16:10:55.759Z 06a36441-eda8-11e8-a421-f996bf66c592
Unexpected exception 'TypeError: Cannot read property 'value' of
undefined':
TypeError: Cannot read property 'value' of undefined at
Object.getSuggestion (/var/task/index.js:31:54) at emitNone
(events.js:86:13) at AlexaRequestEmitter.emit (events.js:185:7) at
AlexaRequestEmitter.EmitEvent
(/var/task/node_modules/alexa-sdk/lib/alexa.js:216:10) at
AlexaRequestEmitter.ValidateRequest
(/var/task/node_modules/alexa-sdk/lib/alexa.js:181:23) at
AlexaRequestEmitter.HandleLambdaEvent
(/var/task/node_modules/alexa-sdk/lib/alexa.js:126:25) at
AlexaRequestEmitter.value
(/var/task/node_modules/alexa-sdk/lib/alexa.js:100:31)
at exports.handler (/var/task/index.js:52:9)
How can I figure this out?
Here is my code:
var Alexa = require('alexa-sdk');
const APP_ID = 'amzn1.ask.skill.ab07421a-0a92-4c2b-b3bd-998e14286xxx';
const skillData = [
{
city: "Austin",
suggestion: "Austin has some of the most outstanding people."
},
{
city: "San Antonio",
suggestion: "San Antonio has some of the most outstanding people."
},
{
city: "Dallas",
suggestion: "The Dallas metroplex is one of the hottest places."
}
];
var number = 0;
while(number<3){
var handlers = {
'LaunchRequest': function () {
this.emit(':ask', 'Tell me the name of the major city you are closest to'
},
'Unhandled': function () {
this.emit(':ask', 'Try saying a city name like Austin, San Antonio, or Dallas');
},
'getSuggestion': function() {
var city = this.event.request.intent.slots.City.value;
this.emit(':ask', getSuggestion(skillData,'city', city.toUpperCase()).suggestion + '. Give me another city and I\'ll hook you up with the best peeps.');
},
'AMAZON.HelpIntent': function () {
this.emit(':ask', "What can I help you with?", "How can I help?");
},
'AMAZON.CancelIntent': function () {
this.emit(':tell', "Okay!");
},
'AMAZON.StopIntent': function () {
this.emit(':tell', "Goodbye!");
},
};
number = number+1;
}
exports.handler = function(event, context, callback){
var alexa = Alexa.handler(event, context);
alexa.appId = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
function getSuggestion(arr, propName, cityName) {
for (var i=0; i < arr.length; i++) {
if (arr[i][propName] == cityName) {
return arr[i];
}
}
}
Update
I've made some changes that were suggested below, however, I am still getting an error after the initial response.
"errorMessage": "Cannot read property 'city' of undefined"
Please look at my new code and help me figure this out:
var Alexa = require('alexa-sdk');
const APP_ID = 'amzn1.ask.skill.ab07421a-0a92-4c2b-b3bd-998e14286xxx';
const skillData = [
{
city: 'Austin',
suggestion: "Austin is blahblahblahblahlshflashdfasldfha blah."
},
{
city: 'San Antonio',
suggestion: "San Antonio has blahblahblahblahlshflashdfasldfha blah."
},
{
city: 'Dallas',
suggestion: "The Dallas metroplex is one of the hottest blahblahblahbla blahblahblahblahblahblah."
}
];
var number = 0;
while(number<3){
var handlers = {
'LaunchRequest': function () {
this.emit(':ask', 'Tell me the name of the major city you are closest to!', 'Which major city are you closest to?');
},
'Unhandled': function () {
this.emit(':ask', "Try saying a city name like Austin, San Antonio, or Dallas");
},
'getSuggestion': function() {
var city = this.event.request.intent.slots.city.value;
this.emit(':ask', getSuggestion(skillData,'city', city.toUpperCase()).suggestion + '. Give me another city and I\'ll hook you up with the best peeps.');
},
'AMAZON.HelpIntent': function () {
this.emit(':ask', "What can I help you with?", "How can I help?");
},
'AMAZON.CancelIntent': function () {
this.emit(':tell', "Okay!");
},
'AMAZON.StopIntent': function () {
this.emit(':tell', "Goodbye!");
},
};
number = number+1;
}
exports.handler = function(event, context, callback){
var alexa = Alexa.handler(event, context);
alexa.appId = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
function getSuggestion(arr, propName, cityName) {
for (var i=0; i < arr.length; i++) {
var prop = arr[i][propName];
prop = prop.toUpperCase();
if (prop == cityName) {
return arr[i];
}
}
}
UPDATE #2
After a lot of trying different things, I've gotten the skill to run with the help of bal simpson!
However, the skill still errors out when the user utters a city name. There must be an error in my Interaction Model, which is below:
{
"interactionModel": {
"languageModel": {
"invocationName": "city picker",
"intents": [
{
"name": "AMAZON.FallbackIntent",
"samples": []
},
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": [
"stop"
]
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "getSuggestion",
"slots": [],
"samples": [
"san antonio",
"dallas",
"austin"
]
}
],
"types": []
}
}
}
Getting close!!
As a last-ditch effort:
Here is my index.js housed in Lambda. Would anyone mind looking at this?
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "LaunchRequest";
},
handle(handlerInput) {
console.log("LaunchRequestHandler");
let speechText = 'Lets get you into your new home. Tell me the name of the major city you are closest to!';
let prompt = 'Which major city are you closest to?';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(prompt)
.getResponse();
}
};
const GetSuggestionIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
handlerInput.requestEnvelope.request.intent.name === "getSuggestion"
);
},
handle(handlerInput) {
let intent = handlerInput.requestEnvelope.request.intent;
let city = intent.slot.city.value;
let suggestion = getSuggestion(skillData,'city', city.toUpperCase()).suggestion;
return handlerInput.responseBuilder
.speak(suggestion)
.reprompt('prompt')
.getResponse();
}
};
const HelpIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
handlerInput.requestEnvelope.request.intent.name === "AMAZON.HelpIntent"
);
},
handle(handlerInput) {
const speechText = "Try saying a city name like Austin, San Antonio, or Dallas";
const promptText = "How can I help?";
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(promptText)
// .withSimpleCard("City Details", speechText)
.getResponse();
}
};
const CancelAndStopIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
(handlerInput.requestEnvelope.request.intent.name ===
"AMAZON.CancelIntent" ||
handlerInput.requestEnvelope.request.intent.name ===
"AMAZON.StopIntent" ||
handlerInput.requestEnvelope.request.intent.name ===
"AMAZON.PauseIntent")
);
},
handle(handlerInput) {
const speechText = `Seeya later!`;
return (
handlerInput.responseBuilder
.speak(speechText)
.withShouldEndSession(true)
.getResponse()
);
}
};
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
},
handle(handlerInput) {
console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
return handlerInput.responseBuilder.getResponse();
},
};
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
console.log(`Error handled: ${error.message}`);
return handlerInput.responseBuilder
.speak('Sorry, I can\'t understand the command. Try saying a city name like Austin, San Antonio, or Dallas')
.reprompt('Try saying a city name like Austin, San Antonio, or Dallas')
.getResponse();
},
};
const SystemExceptionHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type ===
"System.ExceptionEncountered"
);
},
handle(handlerInput) {
console.log(
`System exception encountered: ${
handlerInput.requestEnvelope.request.reason
}`
);
}
};
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
LaunchRequestHandler,
GetSuggestionIntentHandler,
CancelAndStopIntentHandler,
HelpIntentHandler,
SystemExceptionHandler,
SessionEndedRequestHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();
function getSuggestion(arr, propName, cityName) {
for (var i=0; i < arr.length; i++) {
var prop = arr[i][propName];
prop = prop.toUpperCase();
if (prop == cityName) {
return arr[i];
}
}
}
And here is my Interaction Model from the Developer Portal:
{
"interactionModel": {
"languageModel": {
"invocationName": "city picker",
"intents": [
{
"name": "AMAZON.FallbackIntent",
"samples": []
},
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": [
"stop"
]
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "getSuggestion",
"slots": [
{
"name": "city",
"type": "CITY_NAMES"
}
],
"samples": [
"{city}"
]
}
],
"types": [
{
"name": "CITY_NAMES",
"values": [
{
"name": {
"value": "dallas"
}
},
{
"name": {
"value": "san antonio"
}
},
{
"name": {
"value": "austin"
}
}
]
}
]
}
}
}
ok. alexa-sdk has been deprecated link. To get the new SDK, do this.
1 - Create a new function in Lambda.
2 - Choose AWS Serverless Application Repository.
3 - Choose alexa-skills-kit-nodejs-factskill.
4 - Click on deploy. Once deployed, click on functions and you should see the new function you just created with a name like aws-serverless-repository-alexaskillskitnodejsfact-NR8HPILH8WNI.
5 - Delete the code and replace the code with this.
const Alexa = require('ask-sdk');
const skillData = [
{
city: 'Austin',
suggestion: "Austin is blahblahblahblahlshflashdfasldfha blah."
},
{
city: 'San Antonio',
suggestion: "San Antonio has blahblahblahblahlshflashdfasldfha blah."
},
{
city: 'Dallas',
suggestion: "The Dallas metroplex is one of the hottest blahblahblahbla blahblahblahblahblahblah."
}
];
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "LaunchRequest";
},
handle(handlerInput) {
console.log("LaunchRequestHandler");
let speechText = 'Tell me the name of the major city you are closest to!';
let prompt = 'Which major city are you closest to?';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(prompt)
.getResponse();
}
};
const GetSuggestionIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
handlerInput.requestEnvelope.request.intent.name === "getSuggestion"
);
},
handle(handlerInput) {
let intent = handlerInput.requestEnvelope.request.intent;
let city = intent.slots.city.value;
let suggestion = getSuggestion(skillData,'city', city.toUpperCase()).suggestion;
return handlerInput.responseBuilder
.speak(suggestion)
.reprompt('prompt')
.getResponse();
}
};
const HelpIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
handlerInput.requestEnvelope.request.intent.name === "AMAZON.HelpIntent"
);
},
handle(handlerInput) {
const speechText = "Try saying a city name like Austin, San Antonio, or Dallas";
const promptText = "How can I help?";
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(promptText)
// .withSimpleCard("City Details", speechText)
.getResponse();
}
};
const CancelAndStopIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
(handlerInput.requestEnvelope.request.intent.name ===
"AMAZON.CancelIntent" ||
handlerInput.requestEnvelope.request.intent.name ===
"AMAZON.StopIntent" ||
handlerInput.requestEnvelope.request.intent.name ===
"AMAZON.PauseIntent")
);
},
handle(handlerInput) {
const speechText = `Goodbye`;
return (
handlerInput.responseBuilder
.speak(speechText)
.withShouldEndSession(true)
.getResponse()
);
}
};
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
},
handle(handlerInput) {
console.log(`Session ended with reason: ${handlerInput.requestEnvelope.request.reason}`);
return handlerInput.responseBuilder.getResponse();
},
};
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
console.log(`Error handled: ${error.message}`);
return handlerInput.responseBuilder
.speak('Sorry, I can\'t understand the command. Try saying a city name like Austin, San Antonio, or Dallas')
.reprompt('Try saying a city name like Austin, San Antonio, or Dallas')
.getResponse();
},
};
const SystemExceptionHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type ===
"System.ExceptionEncountered"
);
},
handle(handlerInput) {
console.log(
`System exception encountered: ${
handlerInput.requestEnvelope.request.reason
}`
);
}
};
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
LaunchRequestHandler,
GetSuggestionIntentHandler,
CancelAndStopIntentHandler,
HelpIntentHandler,
SystemExceptionHandler,
SessionEndedRequestHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();
function getSuggestion(arr, propName, cityName) {
for (var i=0; i < arr.length; i++) {
var prop = arr[i][propName];
prop = prop.toUpperCase();
if (prop == cityName) {
return arr[i];
}
}
}
6 - Go to developer.amazon.com and change your Alexa Skill endpoint to the new lambda ARN.
To add a slot type:
Specify slot in your sample phrases like this:
Change your slot name to city:
So instead of musicStations it will be city. Make sure you have entered the three values in your slot values like this:
Add your custom slot values to CITY_NAMES:
If you have done it right, your interaction model should be something like this:
"name": "getSuggestion",
"slots": [
{
"name": "city",
"type": "CITY_NAMES"
}
],
"samples": [
"city name is {city}",
"{city}"
]
Testing Lambda code
In the drop down menu, choose 'configure test events'.
Create new test event with JSON from your developer test portal which should look like this.
{
"version": "1.0",
"session": {
"new": true,
"sessionId": "amzn1.echo-api.session.XXXXXX",
"application": {
"applicationId": "amzn1.ask.skill.XXXXXX"
},
"user": {
"userId": "amzn1.ask.account.XXXXXX"
}
},
"context": {
"AudioPlayer": {
"playerActivity": "IDLE"
},
"System": {
"application": {
"applicationId": "amzn1.ask.skill.XXXXXX"
},
"user": {
"userId": "amzn1.ask.account.XXXXXX"
},
"device": {
"deviceId": "amzn1.ask.device.XXXXXX",
"supportedInterfaces": {
"AudioPlayer": {}
}
},
"apiEndpoint": "https://api.eu.amazonalexa.com",
"apiAccessToken": "ACCESS_TOKEN"
},
},
"request": {
"type": "IntentRequest",
"requestId": "amzn1.echo-api.request.XXXX",
"timestamp": "2018-12-03T20:28:29Z",
"locale": "en-IN",
"intent": {
"name": "PlayRadioIntent",
"confirmationStatus": "NONE",
"slots": {
"musicStation": {
"name": "musicStation",
"value": "classic rock",
"resolutions": {
"resolutionsPerAuthority": [
{
"authority": "amzn1.er-authority.XXXX.RadioStations",
"status": {
"code": "ER_SUCCESS_MATCH"
},
"values": [
{
"value": {
"name": "Classic Rock",
"id": "b8a5bd97a8a02691f9f81dcfb12184dd"
}
}
]
}
]
},
"confirmationStatus": "NONE",
"source": "USER"
}
}
}
}
Click on test button
Check Logs
Does the test result look like this? To see the logs, click on logs. It might have additional error details.

Mvc5 getting data list from controller to ajax function c#

i am getting data list from controller to ajax function to my datatable.all works well but my question is, I want to get one of list property to textbox and other values to datatable columns.for example:
list= TotalAMount,PAidAmount,RemAmount
and datatable
Totalamount| PaidAMount | RemAmount| ---------??
20 | 4 | 16 |
so this works fine but i want to get TotalAmount value to some textbox also like textbox=20.
my JS function==>>
`
function AddGetHistoryView(SupplierID) {
$('#HistoryModal').modal('show');
Datatabless = $("#HistoryTable").DataTable({
"autoWidth": false,
"ajax": {
"type": "GET",
"url": "#Url.Action("getHistoryData", "Supplier")/" + SupplierID,
"datatype": "JSON",
data: {
"Amount": $("#TotalAmount").val()
},
data: { SupplierID: SupplierID },
},
"columns": [
{
"data": "DetailID",
"visible": false,
},
{
"data": "TotalAmount",
"width": "5%",
},
{
"data": "PaidAmount",
"width": "5%",
},
{
"data": "RemAmount",
"width": "5%",
},
{
"data": "PaidDate",
"width": "5%",
},
{
"data": "PaymentType",
"width": "5%",
},
{
"data": "DetailID", "render": function (data) {
return "<a class='btn btn-success' onclick=EditRow(" + data + ") style='margin-left:12px'><i class='glyphicon glyphicon-edit'> Update</i><a/>,<a class='btn btn-danger' onclick=deleteRow(" + data + ") style='margin-left:12px'><i class='glyphicon glyphicon-trash'> Delete</i> <a/>";
},
"width": "40%",
"orderable": false,
"pagingType": "full_numbers",
"paging": true,
},
],
});
}
`
Controller Method==>
public ActionResult getHistoryData(int SupplierID)
{
ob.Configuration.ProxyCreationEnabled = false;
var data = ob.Table_Supplier.Join(ob.Table_SupplierDetails, sup => sup.SupplierID, det => det.SupplierID, (sup, det) => new
{
DetailID=det.DetailID,
SupplierID = sup.SupplierID,
TotalAmount = det.TotalAmount,
RemAmount = det.RemAmount,
PaidAmount = det.PaidAmount,
PaidDate = det.PaidDate,
PaymentType = det.PaymentType,
Amount = sup.Amount
}).Where(x=>x.SupplierID==SupplierID).ToList();
return Json(new { data = data }, JsonRequestBehavior.AllowGet);
}

Resources