Automatically Tweet popular articles from DEV
Tags: opensource, showdev, nextjs, javascript
Published: 2022-01-24 08:47:57

Hi everyone, over last week I've built this project which will automatically tweet my popular posts from DEV. It is live on [Tweet My Articles](https://tma.theanshuman.dev) and you can also fork it from [GitHub](https://github.com/Anshuman71/tweet-my-articles).

## Tweet My Articles

This is an open-source tool made to automatically tweet famous DEV posts to an author's Twitter account.

## Motivation

I am a technical blogger on DEV. Recently, my posts have been getting a lot of traction on the platform, and to me, it is news worth sharing with the world. So, I started tweeting milestones like 1000 views and all.

At the start, it was good but, then one day Daily.dev @dailydevtips1 tagged me in this tweet.
 {% twitter 1483503834291126272 %}
And it got me thinking that "if they can automate it, so can I". 

And that's how my friends, I started bootstrapping this project.

---

## Technical Problem statement

We want to send a tweet when article X on DEV crosses a pre-defined milestone.

## Breakdown

- Run a Cron job using GitHub Actions
- Make POST request to our API endpoints

and the API will

- Fetch all published articles of the Author from DEV
- if the article exists in the database:
   - if a new milestone is achieved:
      - Create and article a tweet on Twitter
      - Update database entry with new milestone
   - else:
      - do nothing
- the article does not exist in the database:
   - create a shortUrl for article URL using Rebrandly
   - create a new database item for the article

## Technical Stack

This project is a hobby project, for a nonprofit. All the tools used here are free and openly available.

1. **NextJS**: this project is bootstrapped using NextJS.
2. **GitHub**: is used for source code management and running the cron jobs using GitHub actions.
3. **Vercel**: as the platform. We use their "Serverless and Edge functions".
4. **MongoDB Atlas**: is used as a Database provider to persist milestone information for each article.
5. **Rebrandly**: as a link shortener service

---

## How do I use this project?

### Step 1

Fork this project from [GitHub](https://github.com/Anshuman71/tweet-my-articles)

### Step 2

Create an account on

- Vercel
- Twitter Developer
- Atlas
- Rebrandly

### Step 3

Set up and get the following credentials from each platform

#### DEV

```
DEV_USERNAME=<xxxxxxxxxxxxxxxxxx>
DEV_API_URL=<xxxxxxxxxxxxxxxxxx>
DEV_API_KEY=<xxxxxxxxxxxxxxxxxx>
```

You can get the `API_KEY` from Settings > Account > DEV Community API Keys

> This needs to be specified in Vercel Environment variables


#### Vercel

Sign up using your GitHub to allow Continuous Deployment.


#### Twitter

Sign up for the [Twitter developer program](https://developer.twitter.com/en).

> Please read all instructions there to make sure you get API access to tweet on behalf of your account.

Create a New project > Create New App > Allow Oauth1.0 with Read & Write Access.

Then get the following

```
CONSUMER_KEY=<xxxxxxxxxxxxxxxxxx>
CONSUMER_KEY_SECRET=<xxxxxxxxxxxxxxxxxx>
TWITTER_ACCESS_TOKEN=<xxxxxxxxxxxxxxxxxx>
TWITTER_ACCESS_TOKEN_SECRET=<xxxxxxxxxxxxxxxxxx>
```

> This needs to be specified in Vercel Environment variables


#### MongoDB Atlas

[Sign up](https://www.mongodb.com/atlas/database) on Atlas, create a new cluster, click on Connect > Connect using Application

```
DB_NAME=<xxxxxxxxxxxxxxxxxx>
ATLAS_URI_PROD=<xxxxxxxxxxxxxxxxxx>
```

> The DB_NAME should be the same as specified in the Connection URI

Here is a sample URI

```
mongodb+srv://<user>:<password>@cluster0.mongodb.net/<database-name>?retryWrites=true&w=majority
```

> This needs to be specified in Vercel Environment variables


#### Rebrandly

Sign up and register your custom domain there. Then get an API KEY.
```
SHORTNER_API_KEY=<xxxxxxxxxxxxxxxxxx>
SHORTNER_DOMAIN=<xxxxxxxxxxxxxxxxxx>
```

> This needs to be specified in Vercel Environment variables


#### Secure API key

We would also want to secure our own API from unauthorized users. Let's generate a long enough random string to use as API_KEY for our service. Requests with this key will be rejected.

```
API_KEY=<xxxxxxxxxxxxxxxxxx>
```

This needs to be specified at

1. Vercel Environment variables
2. GitHub Environment variables (to be used by actions)

#### One-click deploy using Vercel

If you just want to use the tool, this is all you need to do.

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FAnshuman71%2Ftweet-my-articles&project-name=tweet-my-articles)

#### Step 4

Copy the same credentials in a `.env.local` file for development purposes. A sample `.env.development` file is present in the repo for help.


#### Step 5

1. Run `yarn` in the repo to install dependencies.
2. Run `yarn dev` to run the local server.
3. Push to the remote repo on GitHub to automatically deploy to Vercel.

---

## FAQs

1. Why do we need a link shortener?
The default URL provided by DEV is sometimes too long for Twitter to load preview and without preview, the article doesn't look all that good. So I used a shortener to solve this issue. Rebrandly provides free custom domain usage up to 500 links which are good enough for our use case.

2. Why not make a SAAS?
Well, I would love to. But because this project holds a lot of sensitive information like Twitter API keys, I would feel better in letting people own their data. That way everyone is responsible for keeping their project safe.

---

I'm going to extend this article into a series to explain each step in detail as well. Please follow me to get updates on that as well.

_I hope you enjoyed reading this article as much as I enjoyed writing it! If so, leave a ❤️ or a 🦄! Should you have any feedback or questions, please feel free to put them in the comments below. I would love to hear and work on them._

For more such content, please follow me on [Twitter](https://twitter.com/sun_anshuman)

> Until next time

<img width="100%" src="https://media.giphy.com/media/kRkJXYahXjSE0/giphy.gif" />