google conversational action with button link - action

I'm looking for a way to write a Google conversational action returning a card with a link (e.g. pointing to an Open Street map, but this is not relevant to the problem description).
Reading the documentation on returning rich responses, I thought I could use basic cards with a button pointing to the desired link. Using NodeJS and the package #assistant/conversation (version 3.8.1) I'm currently returning the following response:
...
"content": {
"card": {
"title": "Project map",
"subtitle": "Locate your project",
"text": "Open the map to locate your project",
"image": {
"url": "https://wiki.openstreetmap.org/w/images/thumb/7/79/Public-images-osm_logo.svg/240px-Public-images-osm_logo.svg.png",
"alt": "Open Street Map logo"
},
"button": {
"name": "Open",
"open": {
"url": "http://www.google.com"
}
}
}
}
...
Unfortunately, the effect is not the desired one: below you can see that the displayed card does not have a button or a link. Am I doing something wrong here?

Related

DynamoDB LIKE '%' (contains) search over an array of objects using a key from the object, NodeJS

I am trying to use a "LIKE" search on DynamoDB where I have an array of objects using nodejs.
Looking through the documentation and other related posts I have seen this can be done using the CONTAINS parameter.
My question is - Can I run a scan or query over all of my items in DynamoDB where a value in my object is LIKE "Test 2".
Here is my DynamoDB Table
This is how it looks as JSON:
{
"items": [
{
"description": "Test 1 Description",
"id": "86f550e3-3dee-4fea-84e9-30df174f27ea",
"image": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/86f550e3-3dee-4fea-84e9-30df174f27ea.jpg",
"live": 1,
"status": "new",
"title": "Test 1 Title"
},
{
"description": "Test 2 Description",
"id": "e17dbb45-63da-4567-941c-bb7e31476f6a",
"image": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/e17dbb45-63da-4567-941c-bb7e31476f6a.jpg",
"live": 1,
"status": "new",
"title": "Test 2 Title"
},
{
"description": "Test 3 Description",
"id": "14ad228f-0939-4ed4-aa7b-66ceef862301",
"image": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/14ad228f-0939-4ed4-aa7b-66ceef862301.jpg",
"live": 1,
"status": "new",
"title": "Test 3 Title"
}
],
"userId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
I am trying to perform a scan / query which will look over ALL users (every row) and look at ALL items and return ALL instances where description is LIKE "Test 2".
I have tried variations of scans as per the below:
{
"TableName": "my-table",
"ConsistentRead": false,
"ExpressionAttributeNames": {
"#items": "items",
},
"FilterExpression": "contains (#items, :itemVal)",
"ExpressionAttributeValues": {
":itemVal":
{
"M": {
"description": {
"S": "Test 2 Description"
},
"id": {
"S": "e17dbb45-63da-4567-941c-bb7e31476f6a"
},
"image": {
"S": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/e17dbb45-63da-4567-941c-bb7e31476f6a.jpg"
},
"live": {
"N": "1"
},
"status": {
"S": "new"
},
"title": {
"S": "Test 2 Title"
}
}
}
}
}
The above scan works but as you can see I am passing in the whole object as an ExpressionAttributeValues, what I want to do is just pass in the description for example something like the below (which doesnt work and returns no items found).
{
"TableName": "my-table",
"ConsistentRead": false,
"ExpressionAttributeNames": {
"#items": "items.description",
},
"FilterExpression": "contains (#items, :itemVal)",
"ExpressionAttributeValues": {
":itemVal":
{
"S": "Test 2"
}
}
}
Alternatively, would it be better to create a separate table where all the items are added and they are linked via the userId? I was always under the impression there should be one table per application but in this instance I think if I had all the item data at the top level, scanning it would be a lot safer and faster.
So with nearly 200 views since posting and no responses I have come up with a solution that does not immediately solve the initial problem (I honestly do not think it can be solved) but have come up with an alternative approach.
Firstly I do not want two tables as this seems overkill, and I do not want the aws costs associated with two tables.
This has lead me to restructure the primary keys with prefixes which I can search over using the "BEGINS_WITH" dynamodb selector query.
Users will be added as U_{USER_ID} and items will be added as I_{USER_ID}_{ITEM_ID}, this way I only have one table to manage and pay for and this allows me to run BEGINS_WITH "U_" to get a list of users or "I_" to get a list of items.
I will then flatten the item data as strings so I can run "contains" searches on any of the item data. This also allows me to run a "contains {USER_ID}" search on the primary keys for items so I can get a list of items for a particular user.
Hope this helps anyone who might come up against the same issue.

About Generating Sitelinks Searchbox

I have used below given Schema.org code on my website, but still, I am not getting site links.
<script type="application/ld+json">
{
"#context": "https://schema.org/",
"#type": "WebSite",
"name": "website-name",
"url": "https://website-name.com.au",
"potentialAction": {
"#type": "SearchAction",
"target": "https://prabingautam.com.au/?s={search_term_string}",
"query-input": "required name=search_term_string"
}
}
</script>
Moreover, I am confused about which query-input to use to get the site link search box. Either
"query-input": "required name=search_term_string"
or
"query-input": "required name=searchbox_target"
You have to use the same value you used as placeholder in target.
"target": "https://prabingautam.com.au/?s={search_term_string}",
"query-input": "required name=search_term_string"
"target": "https://prabingautam.com.au/?s={searchbox_target}",
"query-input": "required name=searchbox_target"
"target": "https://prabingautam.com.au/?s={foobar}",
"query-input": "required name=foobar"
You can choose whatever you like. There is no reason not to use search_term_string (this value gets used in Google’s examples, so copy-pasting the code would be easier).

ListSelect - getting no optionInfo key on second click in list

I am using a webhook for my Google Action that shows a ListSelect to the user. If the user clicks the first time on an item, my webhook receives the respective optionInfo key. Everything works as expected. But if the user scrolls up and clicks on another item in that list, I only receive the title of item as text and not the connected optionInfo key as attribute.
After the user has clicked on an item the first time, my Google Action sends a SimpleResponse with some text, so that there is no more the 'action.intent.OPTION' intent given as possibleIntent then. In each response the "actions.intent.TEXT" intent is included in the "possibleIntents" field.
So my question is, is there any way to get the optionInfo key of the selected item from the list anytime the user selects an item?
My list looks like this:
"possibleIntents": [
{
"intent": "actions.intent.OPTION",
"inputValueData": {
"listSelect": {
"title": "Select an item",
"items": [
{
"optionInfo": {
"key": "item_1"
},
"title": "Item #1",
"description": "Description 1"
},
{
"optionInfo": {
"key": "item_2"
},
"title": "Item #2",
"description": "Description 2"
},
{
"optionInfo": {
"key": "item_3"
},
"title": "Item #3",
"description": "Description 3"
}
]
},
"#type": "type.googleapis.com/google.actions.v2.OptionValueSpec"
}
},
{
"intent": "actions.intent.TEXT"
}
]
After the user selects an item my webhooks sends these possible intents:
"possibleIntents": [
{
"intent": "actions.intent.TEXT"
}
]
If the user now scrolls up and selects another item from the list I don't receive the optionInfo key.
Google fixed it by hiding the other items in that list after a click on one item was made.

Ember DS.hasMany children not showing up with JSON API

I am trying to use the JSON API Adapter with ember-cli 2.5.1 , but I'm having a bit of trouble.
I have a todo-list.js model, which has a "hasMany" relationship to todo-list-item.js. Getting the todo-list, the server returns this:
{
"links": {
"self": "http://localhost:4200/service/v1/todolists/b-tlst-af69786c-cbaf-4df9-a4a3-d8232677006a"
},
"data": {
"type": "todo-list",
"id": "b-tlst-af69786c-cbaf-4df9-a4a3-d8232677006a",
"attributes": {
"name": "b1-TodoList",
"created-on": 1468474962458,
"modified-on": 1468474962458
},
"relationships": {
"todolistitems": {
"data": {
"type": "todo-list-item",
"id": "b-todo-b5e3c146-d93a-4f97-8540-875bbcd156ca"
}
}
}
}
}
If there had been two TodoListItem children instead of one, the value of that "data" key would have been an array, rather than an object.
After receiving this, I was expecting the Ember Chrome plug-in's "Data" tab to show 1 TodoList and 1 child TodoListItem. Instead, it shows 1 TodoList and 0 TodoListItems.
I note from the Network tab that the browser never makes a request to get the items listed in the "data" section of the response.
Is the relationships section above correct and sufficient?
It turns out to have been caused by promise misunderstandings on the client side, and additionally, on the server I had to put dashes in the "relationships" key (i.e. "todo-list-items") and make the value of "data" an array.

Suggesting an action to consumer in HATEOAS

I'm working on a web service API using the HATEOAS REST representation.
My client can create an item (e.g. a stub of a blogpost):
POST /item
204 Created
Content-Type: application/vnd.foo.item+json
{
"id": 42,
"title": "Lorem Ipsum",
"status": "STUB",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"activate": {
"href": "/item/42/activate"
},
}
}
After that the client can activate the item following the activate link (e.g. go live with the post). So it makes another call to the API:
POST /item/42/activate
200 Ok
Content-Type: application/vnd.foo.item+json
{
"id": 42,
"title": "Lorem Ipsum",
"status": "ACTIVE",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"permalink": {
"href": "/item/42/permalink"
}
}
}
Up to here it is fine. But the problem is that I'm looking for a way to tell the client a suggestion about the next action to do (it's backend business logic).
In my case could be:
Bring the user to post page following the permalink
Bring the user to a shop cart to buy post extra features (visibility, more images, homepage positions and so on...)
Tell the user that the post is pending content review
I don't have an idea on how I could encapsulate this information in HATEOAS.
I was thinking to something like:
POST /item/42/activate
200 Ok
Content-Type: application/json
{
"suggested-action": "check-censure-panel",
"censure-reason": "censored (gambling)",
"_embedded": {
"foo.item": {
"id": 42,
"title": "Lorem Ipsum",
"status": "ACTIVE",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"permalink": {
"href": "/item/42/permalink"
}
}
}
}
But the problem is that every suggested action is heterogeneous for extra attributes, another example may be:
"suggested-action": "go-to-checkout",
"product-order": 424242100,
They don't have a common interface, so I can't make a a vnd.foo.suggestedAction+json type.
What is the best way to design this response?
The next action is a state transition, and you seem to be using HAL so any state transitions should be presented as HAL.
Clients of your app need to react to what state transitions your app provides. So one very simple thing you could do is send a Location header to the next resource the app should present. You could even 302 redirect them there instead of 200'ing them with the updated resource.
You could provide the next action as a link...and not necessarily a HAL link. You could do it as a Link header (https://www.rfc-editor.org/rfc/rfc5988) but i think that would be weird, i just bring it up to knock home the point that your app needs to tell your client about a link.
You seem to want to use custom media types, but you could use profile links (https://www.rfc-editor.org/rfc/rfc6906) and mix in a profile into your vnd.foo type. You can stick to your vnd.foo type and just have it defined that there is an optional suggested-action link relationship. The problem in your example is you're defining it with data fields, but use a link:
{
"id": 42,
"title": "Lorem Ipsum",
"status": "ACTIVE",
"body": "Very long text."
"_links": {
"self": {
"href": "/item/42"
},
"permalink": {
"href": "/item/42/permalink"
},
"x:suggested-action" : {
"href" : "/path/to/best/action"
}
}
the client can follow that link, present the user with an option to follow that link, or ignore it. In the middle case, it's nice if your app provides some context to the user, like a title field:
"x:suggested-action" : {
"href" : "http://path/to/check/censure/panel",
"title" : "Check Censure Panel"
}
Also you can give a hint as to the resource the app can expect:
"x:suggested-action" : {
"href" : "http://path/to/check/censure/panel",
"title" : "Check Censure Panel",
"type" : "vnd.censure.panel/json"
}
I personally don't like doing that as i like my client to react to whatever i send them, but it's useful when you give multiple suggested actions:
"x:suggested-action" : [
{
"href" : "http://path/to/check/censure/panel",
"title" : "Check Censure Panel",
"type" : "vnd.censure.panel/json"
},
{
"href" : "http://path/to/checkout",
"title" : "Start Checkout",
"type" : "vnd.checkout/json"
}
]
now the app can decide based on well defined media types which of the suggested actions it wants to do, present, or ignore.