How I built a History Twitter Bot
Tags: twitter, node, javascript, tutorial
Published: 2021-12-08 08:42:35


Here is the titular [Twitter bot](https://twitter.com/jayanthisabot). 
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`
 
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">235 : Pope Anterus succeeds Pontian as the nineteenth pope. During the persecutions of emperor Maximinus Thrax he is martyred. <a href="https://t.co/eecbAnRmCZ">https://t.co/eecbAnRmCZ</a></p>&mdash; OnceUponThisDay (@jayanthisabot) <a href="https://twitter.com/jayanthisabot/status/1462334309675806721?ref_src=twsrc%5Etfw">November 21, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



## Concept

The idea is very simple, steps involved would be

1. Get current date
2. 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](https://en.wikipedia.org/wiki/November_22)
3. Tweet it!!

My task was made easy thanks to two wonderful npm packages

[wtf_wikipedia](https://www.npmjs.com/package/wtf_wikipedia) : Library to parse data from wikipedia

[Twit](https://www.npmjs.com/package/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

```javascript
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.

```javascript
 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

```javascript
 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.

```javascript
    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("&ndash;", ":") + 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

[More on developer account](https://developer.twitter.com/en)

Now lets tweet

```javascript
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

```javascript
setInterval(getRandomWiki, 1000 * 60 * 60 * 12)
```

I hosted the app on Heroku.
You can find the hosting details [here](https://www.freecodecamp.org/news/how-to-deploy-an-application-to-heroku/)

Now you have a [bot](https://twitter.com/jayanthisabot) that tweets daily about random events of the past.

![Botbot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxjg7gpup7s7u7wzh250.gif)

You can find the full code [here](https://github.com/jayanthra/HistoryBot)


Cover Photo by <a href="https://unsplash.com/@aronvisuals?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Aron Visuals</a> on <a href="https://unsplash.com/s/photos/hourglass?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>