Here is the titular Twitter bot.
Its daily mission : To recount what happened in history on that particular day.
For example on Nov 22, 2021 The bot tweeted a historical event that took place on Nov 22
235 : Pope Anterus succeeds Pontian as the nineteenth pope. During the persecutions of emperor Maximinus Thrax he is martyred. https://t.co/eecbAnRmCZ
— OnceUponThisDay (@jayanthisabot) November 21, 2021
Concept
The idea is very simple, steps involved would be
- Get current date
- Get some historical event for that date: Wikipedia is a great source as you can search for a day and get all events for that day eg : November 22
- Tweet it!!
My task was made easy thanks to two wonderful npm packages
wtf_wikipedia : Library to parse data from wikipedia
Twit : Twitter API Client for node, Supports both the REST and Streaming API.
Using these libraries the idea was to create a NodeJS app and host in publicly.
Implementation
Getting data from Wikipedia
Once I had the current date, I formatted it as required by Wikipedia search
function getFormattedDate() {
const date = new Date();
const month = date.toLocaleString('default', { month: 'long' });
const day = date.getDate();
return month + '_' + day;
}
Once the date is created I can use the wtf_wikipedia
to get the details of the page.
const doc = await wtf.fetch(date, 'en');
const data = doc.json()
Seeing the structure of the page, I would like to exclude Deaths
and Births
data and only stick to Events
Poking around the json data, I decided to filter out the data as follows
for (let i = 0; i < data.sections.length; i++) {
if (data.sections[i].title.toLowerCase() === 'deaths' || data.sections[i].title.toLowerCase() === 'births') {
break;
}
if (data.sections[i].title && data.sections[i].title.toLowerCase() !== 'events') {
events.push(data.sections[i])
}
}
Now it is just matter of selecting one of the events by random from the events list.
Some cleaning and formatting I finally have the link to tweet.
const randomSectionList = events[randomNumber(0, events.length)].lists[0]
const randomListItem = randomSectionList[randomNumber(0, randomSectionList.length)]
const page = randomListItem.links[randomListItem.links.length - 1].page
const pageLink = ` https://en.wikipedia.org/wiki/${page.replace(/ /g, "_")}`
const tweet = randomListItem.text.replace("–", ":") + pageLink
Tweeting the event
Twit is a powerful library, I should probably use its other streaming features in future project, for now let's stick to the basics and just use the tweet functionality.
Initial configuration would require some keys and tokens to be set in .env file
CONSUMER_KEY=<CONSUMER_KEY>
CONSUMER_SECRET=<CONSUMER_KEY>
ACCESS_TOKEN=<ACCESS_TOKEN>
ACCESS_TOKEN_SECRET=<ACCESS_TOKEN_SECRET>
These keys can be got from the Twitter developer console
Now lets tweet
const T = new Twit(config);
T.post('statuses/update', { status: tweet }, function (err, data) {
if (!err) {
console.log("Tweeted", data.text)
}
})
That's it!! the bot has searched for events in Wikipedia and tweeted. Now just matter of enclosing these functions in an interval so that the actions are repeated.
I set it tweet every 12 hours
setInterval(getRandomWiki, 1000 * 60 * 60 * 12)
I hosted the app on Heroku.
You can find the hosting details here
Now you have a bot that tweets daily about random events of the past.
You can find the full code here
Cover Photo by Aron Visuals on Unsplash
Top comments (2)
This is great, love to see a Twitter bot! You should note that the
twit
library is very outdated (e.g. it uses deprecated node.js functions and has not been updated in a long time; it also only uses the Twitter API v1.1, and the new version is v2). There are a bunch of newer libraries out there for API v2. Thanks for sharing your project and your code!Also: my degree is in History! 😀
Thanks for the feedback Andy, the original project was implemented years back.
It started off a Twitter account which tweeted chuck Norris jokes.
I'll be checking the new libraries you mentioned for my future work