Problem/Motivation

Both Amazon Alexa and Api.ai support entities.

https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/doc...
https://api.ai/docs/reference/agent/entities

At present it is necessary to maintain these via their UI.

Proposed resolution

Add an API that supports identifying Drupal content entities as entities for pushing to each service's endpoint.
This would be the glue between Drupal entities but not provide the implementation - implementations would be backend specific and live in e.g. api_ai_webhook or alexa module

Remaining tasks

Review

User interface changes

API changes

Data model changes

Comments

larowlan created an issue. See original summary.

gambry’s picture

From my understanding Alexa entities definition can be done only from their UI, while Api.AI let you define entities either via UI or pushing to the entities endpoint.

Additionally developers seem to be able to use "on-the-fly entities" through webhook slot filling in Intents. If this is true and final result is the same as pushing values to the Entity, it may be easier and quicker to implement this one with api_ai_webhook rather then connecting to the Api.AI REST endpoint.

Either way this is an important feature request, and it's a shame Alexa doesn't have this feature.

@larowlan have you had a look if same can be done for Wit?

larowlan’s picture

larowlan’s picture

StatusFileSize
new48.62 KB

So here's my wip.

Architecture is as follows:

  • Config entity (EntityCollection) that defines a 'collection of entities we want to push somewhere'
  • This includes an entity type id, and bundle field - so we say 'Collection' of 'Taxonomy terms' from 'Tags' bundle
  • Also includes optional 'synonyms' field which will allow user to nominate a multi-value text field to derive synonyms from
  • On it is a plugin collection 'query handlers' which is an array of plugins that 'find me some entities to push' which will use the entity type and bundle to query for entities. There is a base implementation that just filters by bundle and published if those keys exist for the given entity type. There is a deriver so that the user one can add the status field (which is not part of its annotation).
  • On it is also a plugin collection 'push handlers' which is an array of plugins that 'push entities to an endpoint'
  • I've got a test one that just saves them in state, so we can test the wiring.
  • Have written one for api.ai that pushes there (see patch over there)
  • The module has hook_entity_{insert|update|delete} implementations which just query for a matching collection and add it to a queue
  • The a queue worker sends on cron, making sure to only send once - so multiple updates might queue the same collection multiple times, but we have a timestamp to check that

To do:

  • in the config entity presave, push handlers should be able to react to a new entity (so e.g. api.ai can push a shell and get a remote id, then store that with the config entity for update sake)
  • configuration form
  • config dependencies (needs to depend on bundle if config based and field for synonyms)
larowlan’s picture

done for today

larowlan’s picture

to do:

- edit form submit handler
- make ui test pass (complete the form - TDD)
- config dependencies test
- config dependencies

gambry’s picture

@larowlan thanks for the amazing work. Some services you use are new to me, so I'm sure this is going to be for me a great training exercise.

I like the architecture. I struggled at the begging with why you were pushing all entries every time, then I noticed this is the way Api.AI expects data in its /entries endpoint(s). That differs from - for instance - Wit, where you need to POST a single value for each HTTP request.
But I'm happy with the way you did, it's the best approach against any scenario.

One question I need to ask is how QueryHandler plugins work, in terms of what the logic for which plugin will be selected for execution is. I can see there are isEnabled() and applies() methods, which should control if the query is valid for the current collection, but I don't see those two used anywhere.
To me looks like at the moment all run. Is that correct?
Anyway the idea is brilliant, as I'm assuming QueryHandler let developers add complex queries/filtering like 'All articles with "Foo" value in the "bar" field' OR "children of 'Parent' taxonomy term'.

I'm going to do some test to better understand the UI and UX, but generally I'm happy with the work done so far.

Thanks again.

larowlan’s picture

Yep, the applies isn't yet implemented, but will be for the UI

i.e. limiting query handlers based on the entity type.

I'm going to do some test to better understand the UI and UX, but generally I'm happy with the work done so far.

The form still needs to be finished - that's what I'm working on now - hopefully it will make a bit more sense once that is done

larowlan’s picture

Status: Active » Needs review
StatusFileSize
new27.82 KB
new72.25 KB

This is ready for review now, working nicely on my local environment/api.ai account

larowlan’s picture

Issue summary: View changes
gambry’s picture

Hi @larowlan.

All looks very good, thank you for the hard work.
There are just few coding standard issues we should fix before commit, but really no major thing.

The only open question is if isEnabled() methods are of any use or not. I don't see they been called within their own plugin managers and in the Plugin system itself.

After an user save an Entity we need to explain what's going on. If first sync is going to happen after creating/editing an entity we should let the user know. Then when the entity is changed we should also flag actual sync will actually happen on cron run.

But I'm generally happy, UX/UI is friendly and fluid so feel free to make these minor changes and commit.

larowlan’s picture

Ah yeah - I changed the way the plugins were stored on the config entity, I filter out the disabled ones - so the isEnabled isn't needed.

Will remove on Monday

larowlan’s picture

Status: Needs review » Needs work

I didn't get to this hoping to get to it tomorrow

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new2.84 KB
new72.26 KB

Removed the isEnabled method from the base class and the interface.

Added some additional information regarding cron etc to the messages/UI

The last submitted patch, 14: interdiff.2904816.14.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 14: 2904816.14.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new4.13 KB
new72.02 KB

Proper interdiff this time
And a fix for test groups

gambry’s picture

Status: Needs review » Reviewed & tested by the community

Looks good. More than happy to have this in!
Thanks for your work.

The last submitted patch, 4: chatbot-api-2904816.wip_.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

The last submitted patch, 5: chatbot-api-2904816.wip2_.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

The last submitted patch, 9: chatbot-api-2904816.3.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

gambry’s picture

Removing/Hiding previous files.

  • larowlan committed 6b63796 on 8.x-1.x
    Issue #2904816 by larowlan, gambry: Add API for pushing content entities...
larowlan’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed to 8.x-1.x

Added @gambry in credits for all the reviews

Thanks! excited to get this in.

Will update project page to mention it.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.