Skip to main content

How to use node-red to interact with twitter

Recently I had to setup an application that was able to read twitter and, based on some predefined keywords,  had to reply to specific tweets. I decided to have a look at node-red to set this stuff up. It proofed to be rather straightforward and easy to implement. The hardest part was to get approval for a twitter developer account. In this post I describe how I used node-red and how I implemented the interaction with twitter.

What is node-red, and how to use it?

Node-RED  (https://nodered.org/) is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways. It provides a browser-based editor that makes it easy to wire together flows using the wide range of nodes in the palette that can be deployed to its runtime in a single-click.  You can use node-RED in many ways, but for the purpose of this demo I decided to run it in a docker image. I used the way described here (https://hub.docker.com/r/nodered/node-red-docker/), as this is a node-RED provided docker image. Assuming you have docker up and running, it is simple to install and run node-RED.
docker run -it -p 1880:1880 --name mynodered nodered/node-red-docker

This will pull the latest image, and start a node-RED instance for you.
When you now browse to http://127.0.0.1:1880 you will see the Node-RED flow editor.
I will not explain how to use the node-RED flow editor, as there is a whole lot of documentation. These docs (https://nodered.org/docs/) are very helpful, and for the twitter example there is not much need to read the entire node-RED documentation.

Getting permission to use twitter API's

As of late July, twitter implemented a new policy (https://blog.twitter.com/developer/en_us/topics/tools/2018/new-developer-requirements-to-protect-our-platform.html) that will protect the twitter platform from mis-use and spam. That new policy also means that I was not able to create an app that can listen for tweets and reply to them without applying for a twitter developer account.  All developers must apply for a developer account to access Twitter APIs. Once approved, you can begin to use the standard APIs and the new premium APIs.
To apply for a developer account, go to http://developer.twitter.com and sign in with your twitter account. Next, click apply in the upper right corner and follow the instructions. Getting you developer account approved could take some time. I had to wait for about 4 weeks, but eventually I got approved.
Next you are able to create a new app in the my apps page (https://developer.twitter.com/en/apps).  Once created, you are provided with the API keys and access tokens that you need to use in the app that you are building, in this case the node-RED twitter flow,


Building the twitter interaction flow.

What we will use to make this work are 2 'twitter' components. One for twitterIn and one for twitterOut. These two components will be connected by a function component that we will use to construct an outgoing tweet. The twitterIn component has to be hooked up to your twitter account. You can also add a comma separated list of words and/or hashtags you want to listen for:
You also need to enter the API keys and Access tokens that were created in the previous step.  
With the twitterIn component configured, we are now ready to create a function node that can work with the tweet and reply with an answer. All information that flows between the steps in a node-red flow is based on "msg". This means that the tweet that was intercepted by the tweetIn components is forwarded to the function component as "msg".
From that "msg" we can now retrieve all necessary information, such as the tweet text ("msg.tweet"), the name of the twitter user ("msg.user.screen_name") and the id of the tweet ("msg.tweet.id_str"), which we will need to send back an inline reply to that message. The code below shows you how we can use all of the above information to construct a new "msg" that contains the tweet that we will send out.

Note that when we don't use the in_reply_to_status_id, the tweet will be posted as an individual tweet without any relation to the tweet that invoked the 'conversation'.
You might want to add some debug steps (the green ones below) that help you to understand what is happening. The complete flow will look similar to the image below:
The final step here is to "deploy" your node-red flow. This can be simply done by clicking the "deploy" button in the upper right corner of the node-red IDE.

The result.

When you now send out a tweet that contains your hashtag, our node-red sample will reply to that tweet with the words "You mentioned me! @" + name + ' ' + 'You are super cool!", as can be seen in the thread below where me and my collegae Ardhendu were testing this interaction.

Note.

Node-RED also provides a Runtime API. This API can be used when embedding Node-RED into another application. Node-RED can be loaded into another node.js application using the standard require module loader. This opens up a lot of possibilities that can be worthwhile to explore.



Comments

Popular posts from this blog

ADF 12.1.3 : Implementing Default Table Filter Values

In one of my projects I ran into a requirement where the end user needs to be presented with default values in the table filters. This sounds like it is a common requirement, which is easy to implement. However it proved to be not so common, as it is not in the documentation nor are there any Blogpost to be found that talk about this feature. In this blogpost I describe how to implement this.

The Use Case Explained
Users of the application would typically enter today's date in a table filter in order to get all data that is valid for today. They do this each and every time. In order to facilitate them I want to have the table filter pre-filled with today's date (at the moment of writing July 31st 2015).


So whenever the page is displayed, it should display 'today' in the table filter and execute the query accordingly. The problem is to get the value in the filter without the user typing it. Lets first take a look at how the ADF Search and Filters are implemented by the f…

ADF 12.2.x : Conditional Showing Message Instead of List of Values Popup

Today I had to fix an issue in one of our ADF applications. For those of you working with ADF (as I do too occasionally) this might be valuable, so I decided to share this. The application is based on an old Oracle Forms applications and I had to implement the following functionality:

FRM-41830 : List of Values contains no entries.

In other words (more ADF like) : If you are about to render a List of Values and that List of Values contains no rows, just show a message instead of showing the List of Values.

In this post I will describe how I was able to implement this although it turned out to be a challenge.
Below are the steps that I took. Note that the Application can be downloaded from GIT.

1) I use a UI pattern where we use readonly table and do edits in a popup. That means that any List of Values will add an additional popup to the UI.



2) The List of Values that I use in this sample only shows entries where the minimum salary is less then the employees current salary. Not that …

ADF 11g Quicky 3 : Adding Error, Info and Warning messages

How can we add a message programatically ? Last week I got this question for the second time in a months time. I decided to write a short blogpost on how this works.

Adding messages is very easy, you just need to know how it works.
You can add a message to your faces context by creating a new FacesMessage. Set the severity (ERROR, WARNING, INFO or FATAL ), set the message text, and if nessecary a message detail. The fragment below shows the code for an ERROR message.

1: public void setMessagesErr(ActionEvent actionEvent) {
2: String msg = "This is a message";
3: AdfFacesContext adfFacesContext = null;
4: adfFacesContext = AdfFacesContext.getCurrentInstance();
5: FacesContext ctx = FacesContext.getCurrentInstance();
6: FacesMessage fm =
7: new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, "");
8: ctx.addMessage(null, fm);
9: }


I created a simple page with a couple of buttons to show the result of setting the message. When the butto…