Learn how to add your Oracle Digital Assistant to Twitter

twitter

Twitter is one of the most popular social media platforms and plenty of companies use it to provide customer service, among other services. In this post I will explain how to connect Twitter to the Oracle Digital Assistant .

This post is a follow-up of this other one where I explained how to create a simple webhook. If you are unfamiliar with webhooks, start with the below link.

The Use Case

I will create a Skill with some answer intents and small talk intents, nothing fancy, just to support this Channel Integration. Before that let’s look at the backend implementation.

The Twitter API

The entire communication will rely on a webhook server and on Twitter API’s.

It’s important to understand that Twitter released API v2 recently which is significantly different than the Standard v1.1. For more information check https://developer.twitter.com/en/docs/platform-overview

I used the Standard v1.1 in the past (wrapped around the npmjs Twit package), and that is what I will use in this post.

For this simple demo I will use the timeline and hastag (#) mentions to trigger a response. That uses the GET statuses/filter from v1.1, and you can see it has a different implementation in v2.

Both are synchronous request (as any other REST), which is not the ideal approach when using webhooks, which is meant to be an asynchronous framework. the V2 brings an added API, which does have a callback feature. That seems to be the best way to go about this – I will use the V1.1 for now, and create another post once I migrate my code to V2.

Account Activity – Twitter API V2

Account Activity API: Premium

The Account Activity API uses webhooks, meaning that unlike for the streaming APIs we don’t require you to have an open connection for us to send you information. Webhooks are also different from Rest APIs because you don’t have to pull us hundreds of times every 15 minutes to get the data you care about. This increases the efficiency between a user and your app, as it delivers data when it happens.

Ok let’s park this V2 and focus on how to implement this with V1.1

The Webhook Implementation

I will use the Twit package to facilitate using the Twitter API.

We need to have the proper credentials, which come from developer.twitter.com

Twit offers several wrappers around the Twitter v1.1 API’s. For this particular use case, I will use the streaming method, which allows us to filter in real time mentions or hashtags.

I will filter for #ODAPM and we also need to read user, text (obviously) and the reply_id so that we can reply to the tweet.

We send the message to ODA (userId and tweet content).

webhook.receiver() is actively listening for the messages coming from ODA. Once that happens the webhook.on(MESSAGE_RECEIVED) is triggered, and in this case it will reply to the original Tweet with the response from ODA.

If you look closely, there is a big shortcut in this implementation. I am passing the reply_id taken from the stream.on listener….but there is no guarantee that the reply_id actually correlates with the response coming from ODA. A solution for this would be to implement a queuing dispatcher to correlate request and response. An even better solution would be to use API v2 with Account Activity, which supports callback’s.

TEST

Ok, I started my webhook with node index.js, and we can now test this πŸ™‚

Immediately we see the Tweet being picked and sent to ODA, with a response arriving in a couple seconds.

I have a very simple Skill with some answer intents (make sure the length of the answer does not exceed Twitter limits)

And the answer to the original Tweet is….tweeted!

Very Important Notes

  • This is not (by far) production code.
  • Consider using API Account Activity v2 instead (with callback support)
  • API v1 is synchronous and that means we need to would need to correlated the reply_id of the calling request towards ODA so that we have the proper reply_id to tweet back. A sort of dispatcher helper function would implement this.
  • A more realistic use case would rely on DM instead of timelines and #