Actions on Google API v2 using c# webhook - dialogflow-es

I currently have an app running on actions on google using API.AI. I have modified all the response members to be camelCase as suggested and got it working. Now I am trying to return a basic card, but I can not figure out how to properly return it.
Does anyone have the most basic JSON response, returning a basic card to the Google assistant?
currently, the most basic v2 API response I can have is the following:
{
speech: "",
displayText: "",
data: {
google: {
expectUserResponse: true,
isSsml: true,
permissionsRequest: null
}
},
contextOut: [ ],
source: "webhook"
}

I have some Gists showing the JSON responses here.
Right now, it includes Lists, Basic Card and Carousel, but I will add Transactions hopefully soon. Hope it might help somehow

This is what I use for Voice Tic Tac Toe
"google": {
"expect_user_response": true,
"rich_response": {
"items": [
{
"simple_response": {
"text_to_speech": "Your move was top. I moved left"
}
},
{
"basic_card": {
"image": {
"url": "https://server/010200000.png",
"accessibility_text": "Tic Tac Toe game board"
}
}
}
]
}
}
I ran the facts about google action and looked at the fulfillment JSON output to learn how to do this.
https://github.com/actions-on-google/apiai-facts-about-google-nodejs

Note that all responses must include at least one, and no more than two, simple_response items.

Related

(NodeJS) WordPress API, updating Events Calendar event (tribe event) removes featured image from post

I'm using the Wordpress API to update tribe events. The updates are successfully sent (and the change is made) but as a side-effect, any time I do it, the featured image is removed from the post...
wpapi package setup:
Because The Events Calendar has it's own routes that aren't built-in by default in the wpapi package, I use the wp.registerRoute function to set that up. I don't think there's a problem with the way I set that up because otherwise it works.
var WPAPI = require( 'wpapi' );
var wp = new WPAPI({
endpoint: 'https://www.example.com/wp-json',
username: 'username',
password: 'mypassword'
});
wp.tribeevent = wp.registerRoute('tribe/events/v1', '/events/(?P<id>)');
example update:
function showEvent (post_id) {
let data = { "hide_from_listings" : false }
wp.tribeevent().id(post_id).update(data)
}
Haven't been able to find anyone with this issue online, so I'm posting here after exhausting myself trying to get it to work without removing the image... Am I doing this wrong? Is this just a bug? Any suggested workarounds?
I've also tried adding the existing image info into the update data sent, but I get this response when doing so:
{
"error": {
"code": "rest_invalid_param",
"message": "Invalid parameter(s): image",
"data": {
"status": 400,
"params": {
"image": "Invalid parameter."
},
"details": []
}
}
}
Otherwise, when making an update such as { "hide_from_listings" : false }, when the json response comes back, the value of the image key just comes back as false: { "image" : false }
Would greatly appreciate any kind of input on this issue...

Lex V1 group message

I am working on chat bot in Amazon lex v1 ,In that I want to display two messages when the client invoke the bot. But I am facing issue .with lambda
var messageToUse = {
contentType : "Composite",
content :{"messages":[{"type":"PlainText","group":1,"value":"welcome"},{"type":"PlainText","group":2,"value":"To GAC"}]}
};
const response = {
"dialogAction":
{"type": "Close",
"fulfillmentState": "Fulfilled",
"message": messageToUse
}
};
callback(response);
Expected Result should be this
Lex V1 is limited when it comes to working with the API for message groups. The tutorial you were following was able to get multiple messages by using message groups in the content designer (Lex's designer UI). This is different than returning multiple messages through a Lambda function.
Adding the responses in the content designer
A preview of how the responses will look
Unfortunately, the JSON for messages was not a list/array in Lex V1. It only supported key value pairs. This means that a Lex V1 Bot only expects a single message from the Lambda and you cannot return more than one at a time.
The only way you can make Lex V1 appear like it is returning multiple messages is to use a custom front end. If you plan on using a custom front end, you can parse the message.content JSON into different message bubbles yourself.
If you would like to be able to set message groups through a lambda function, I recommend you try using Lex V2. The JSON for messages in Lex V2 expects a list, meaning that you can return multiple messages at once and they will appear in separate bubbles in the Lex V2 test console.
Here is an example of how to do this in Lex V2:
return {
"sessionState": {
"dialogAction": {
"type": "Close"
},
"intent": {
"confirmationState": "None",
"name": "TestIntent",
"state": "Fulfilled"
}
},
"messages": [
{ "contentType": "PlainText", "content": "Hi" },
{ "contentType": "PlainText", "content": "How are you?" },
{ "contentType": "PlainText", "content": "How may I help?" }
]};
And also how they appear in the test console.
I'm sorry this isn't the answer you were hoping for but I hope it helps anyway.

Update chrome.webRequest header modification from V2 to V3

I'm trying to update my chrome extension from V2 to V3.
The part that doesn't seem to work right now is where I modify incoming headers
V2:
function modifyHeadersForUrls(urls: string[]) {
chrome.webRequest.onHeadersReceived.addListener((details) => {
details.responseHeaders.testHeader = 'barfoo';
return details.responseHeaders;
}, { urls }, ['blocking', 'responseHeaders']);
}
For this code to work in V2 I needed to add 2 permission to my manifest:
"webRequest",
"webRequestBlocking"
In V3 I get the impression that I should switch to
"declarativeNetRequest",
"declarativeNetRequestWithHostAccess",
"declarativeNetRequestFeedback"
Or at least to one of them. I think I need declarativeNetRequestWithHostAccess
but I'm not sure what I should do here. It is needed to declare a declarative_net_request block in the manifest, but in my case the urls are dynamic.
Normally I can figure it out with the docs and a couple of examples, but the problem is, is that I can't find any example using declarativeNetRequestWithHostAccess.
Any help would be appreciated!
Based on the example given below I was able to produce the following code
const urls = ['localhost:8000'];
chrome.declarativeNetRequest.updateDynamicRules({
// chrome.declarativeNetRequest.updateSessionRules({
// removeRuleIds: ....,
addRules: [
{
id: 1,
priority: 1,
condition: {
initiatorDomains: urls,
resourceTypes: ['main_frame']
},
action: {
type: 'modifyHeaders',
responseHeaders: [
{ header: 'Content-Security-Policy', operation: 'remove' },
{ header: 'Content-Security-Policy-Report-Only', operation: 'remove' },
],
}
}
]
});
In my case I need to remove the CSP headers for a given url. What the above code is suppose to do, is to remove these headers for any url from localhost:8000? Unfortunate, it didn't work. Any ideas what might be wrong in my code?
Also, it is unclear what exactly updateSessionRules does? What is a session in terms of the background service worker?
Thanks alot!

Lex bot getting value only in digit representation not from words

I am a newbie to Amazon Lex, I have created a bot that offers several services:
open a case
check status
status via email
when a user checks the status, he is forced to provide a "case number." The issue I am facing is that it only gets value from digits such as digit representation.
When the user uses "nine" instead of 9, it doesn't work. You can see it here.
Guide me on that issue, I would be very thankful to you.
It seems an AWS Lambda will be best suited to assist you with what you're trying to achieve.
When testing via the AWS Lex console, click the "Inspect" button and view the JSON-formatted requests and responses.
What you will find is that when the user enters a numeric value in words - as in your example "nine" instead of "9" - Lex will provide you with the original input as well as the numeric form of the input.
Take a look at the JSON payload below that I've extracted from my own example:
{
"messages":[
{
"content":"Well done!",
"contentType":"PlainText"
}
],
"sessionState":{
"dialogAction":{
"type":"Close"
},
"intent":{
"name":"MainIntent",
"slots":{
"quantity":{
"value":{
"originalValue":"two",
"interpretedValue":"2",
"resolvedValues":[
"2"
]
}
}
},
"state":"ReadyForFulfillment",
"confirmationState":"None"
},
"originatingRequestId":"e309a92b-124b-4250-bbd3-2fb8891aa90f"
},
"interpretations":[
{
"nluConfidence":{
"score":1
},
"intent":{
"name":"MainIntent",
"slots":{
"quantity":{
"value":{
"originalValue":"two",
"interpretedValue":"2",
"resolvedValues":[
"2"
]
}
}
},
"state":"ReadyForFulfillment",
"confirmationState":"None"
}
},
{
"intent":{
"name":"FallbackIntent",
"slots":{
}
}
}
],
"sessionId":"858917309331613"
}
Have a look at the interpretedValue field in the payload. This is the numeric value that you're looking for.
Using a Lambda function, you can extract this value and perform any validation that you may need before continuing with the rest of the flow or user journey.
You can find out more about integrating Lambda functions into Lex from the developer guide:
https://docs.aws.amazon.com/lexv2/latest/dg/lambda.html

postback button in dialogflow messenger cx

Hello I'm trying to create a flow in dialogflow cx, where in case of multiple options I want my user to select 1 option where all the options are buttons.
I have used the default payload but not sure how can I send back which button got clicked to my webhook and return respective info, currently if I click on button it simply open example.com, if I exclude the link it opens same page in new tab.
{
"type": "button",
"icon": {
"type": "chevron_right",
"color": "#FF9800"
},
"text": "Button text 1",
"link" : "www.example.com",
"event": {
"name": "some name",
"languageCode": "en",
"parameters": {}
}
}
For your use case, since the button response type always redirects to a page when clicked, you can consider using suggestion chips instead.
{
"richContent": [
[
{
"options": [
{
"text": "Chip 1"
},
{
"text": "Chip 2"
}
],
"type": "chips"
}
]
]
}
Suggestion chips act like a user text query when the user clicks on it, therefore, you can just create a route that can be triggered by text of the chip and get the text query from the webhook request sent to your webhook to return the respective information. For example:
Intent:
Route:
Then in your webhook, you can get the parameter value in the text field of the webhook request which you will refer to in order to create a webhook response with the respective information.
Here’s an example in Node.js using Express:
app.post("/webhook", (req, res) => {
let option = req.body.text;
let jsonResponse = {
fulfillment_response: {
messages: [
{
text: {
//fulfillment text response to be sent to the agent
text: [`You've chosen the ${option} option`]
}
}
]
}
};
res.json(jsonResponse);
});
Alternatively, you can also use entity types and assign the selected chip into a parameter that will be also sent to your webhook.
To assign the text of the chip to a parameter, the intent of the route should contain training phrases that are annotated to an entity type containing all of the options. For example:
Intent:
Entity Type:
Then in your webhook, you can get the parameter value in the intentInfo.parameters.parameter_id.resolvedValue field of the webhook request which you will refer to in order to create a webhook response with the respective information.
Here’s an example in Node.js using Express:
app.post("/webhook", (req, res) => {
let option = req.body.intentInfo.parameters.options.resolvedValue;
let jsonResponse = {
fulfillment_response: {
messages: [
{
text: {
//fulfillment text response to be sent to the agent
text: [`You've chosen the ${option} option`]
}
}
]
}
};
res.json(jsonResponse);
});
Results:
There is a simple albeit hacky way I have discover possible (tested in es). Which is to make a chip and get its element then force clicking it
We can listen to button click and I detect that it was empty button with just text. Then I use renderCustomCard to make a chip. Everything inside dialogflow messenger are hidden deep inside nested shadowRoot. But as of now its structure allow us to get the chip out to call click() on it. In effect it make it seem very the same as user manually click the chip
const dfMessenger = document.querySelector('df-messenger');
dfMessenger.addEventListener('df-button-clicked',function(event) {
if(event.detail.element.event || event.detail.element.link)
return;
dfMessenger.renderCustomCard([
{
"type": "chips",
"options": [
{
"text": event.detail.element.text
}
]
}
]);
var messageList = dfMessenger.shadowRoot.querySelector("df-messenger-chat").shadowRoot.querySelector("df-message-list").shadowRoot;
var chips = [...messageList.querySelectorAll("df-chips")].flatMap((chips) => [...chips.shadowRoot.querySelectorAll(".df-chips-wrapper>a")]).filter((a) => a.innerHTML.indexOf(event.detail.element.text) > -1);
if(chips.length > 0)
chips.slice(-1)[0].click();
});
Working for today. No guarantee they will block this method in the future. But I actually guess they would implement actual postback button in similar manner later after beta version

Resources