Making a Node-RED Twitter Bot

by Christian Mohn · Read in about 5 min (913 words)

Node-RED logo
I use Node-RED extensively for home automation purposes, in conjunction with Home Assistant. See the Home Automation tag for posts in that series.

This post, however, is for a different use case and not home automation. For years I’ve been using Zapier to automatically tweet new posts for this site via the @vninjanet account, but that has proven rather inflexible and I wanted a better way to automate this, while adding features that Zapier currently does not support like adding specific hashtags automatically.

I have been using the sites RSS feed as the trigger in Zapier, and wanted to continue doing that, even if moving it to Node-RED.

Project Outline #

  1. Automatically tweet when a new post is published
  2. Ability to add hashtags to the tweet itself, from Hugo
  3. Learn something in the process

Since I already have Node-RED up and running, it was a natural choice to start looking for ways to accomplish this with that tool. As it turns out, Node-RED already has nodes for RSS feed parsing and Twitter, so the grunt of it already exists.

The solution I ended up with is a combination of several things in order to make everything work together.

Customizing the Hugo RSS Feed #

First off, I needed to customize the Hugo RSS feed to make sure the Twitter hashtags I wanted to include was also included in the RSS feed. Using Adding Author tag to RSS Feed using Hugo static site generator as a starting point, I added the following to my rss.xml file as the last line before </item>

<category>{{ .Params.hashtags }}</category>

This picks up whatever I have put in a posts front matter, under the hashtags variable like this:

hashtags: node-red, automation

After verifying that this indeed shows up in the feed, I moved on to Node-RED to create the flow.

Node-RED Flow #

The final flow looks like this:

Node-RED RSS to Twitter flow

1. Feedburner node (vNinja) #

The feedburner node is pretty simple, all it needs is a valid Feed url, which in this case points to this sites feed.

feedburner node

The only other configuration items are the refresh schedule, and a name.

2. rbe node #

The rbe node, report-by-exception, is there to ensure that it only triggers if there is a change in the feed. When that is in place it only passes data if the input data has changed, like when a new item appears in the feed that the feedburner node monitors.

rbe node

While testing this flow on a test Twitter account, the account got temporarily suspended when I was testing due to posting >300 tweets in a few seconds, and the rbe node is there to ensure that doesn’t happen again…

3. Function node (Format Tweet) #

The function node is where I get into deep water. I am not a developer, and have not really done anything in javascript before. But, in order to format the data received from the feedburner node into something that can be passed on to the Twitter node I had to get my hands dirty. In the feed, after the edits I did in Customizing the Hugo RSS Feed, the hashtags defined in the front matter look like this:

<category>node-red, automation</category>

In order to separate these out, and prepend the hash I used the following javascript code in the function node:

rbe node

The javascript code looks like this:

var hashtags = msg.article.categories[0];
var splitHashtags = hashtags.replace(/, /g, " #");
var finalHashTags = "#"+splitHashtags;

var tweet = "New post: " + msg.article.title + " " + msg.article.link + " " +finalHashTags; 
msg.payload = tweet;
return msg;

Warning

Caveat emptor: I am no developer. Never have been. There is probably way better methods to doing this in javascript, but it’s what I hacked together with zero to no experience at all.

Basically this takes the input that is contained in the categories node in the feed, and removes the commas with spaces, and ads the hash before storing it in the msg.payload variable. It also adds New Post:, the title of the post and the link to the post before it appends the hashtags to the end of the string.

This pretty fragile, and will certainly not work right if I don’t define my hashtags in the front matter correctly, as it expects them to be separated by commas, and not include the hashbang. There should probably be some error checking in there as well, but for now this is what I have.

4. Twitter out node (Tweet vNinja.net post) #

The last node in the flow, is the Twitter out node. Before that can be used, it needs to be configured with proper Twitter credentials, like API keys and Access tokens.

You can get yours at developer.twitter.com/en/apps.

rbe node

Once that’s configured, the Twitter out node will compose a tweet of whatever gets passed to it in the msg.payload object. Since the function node takes care of the formatting, that’s all the configuration that is needed.

If everything still works as it did during testing, this post should now be autotweeted via @vninjanet with a tweet that looks something like this:

New Post: Making a Node-RED Twitter Bot https://vninja.net/2021/01/20/node-red-twitter-bot/ #node-red #automation

Let’s hope it still works! I’ll post the tweet below here once it is published.

This accomplished eveything I set out to do, and I learned something in the process.

Post last updated on January 21, 2021: Markdownlint and new header

About the author

Christian Mohn works as a Chief Technologist SDDC for Proact in Norway.

See his About page for more details, or find him on Twitter.

Sponsors