Twitter Automation - automatically tweets about your new blog on DEV.to
Tags: node, react, twitter, javascript
Published: 2021-03-29 20:24:01

Hello there,
If you are reading this article chances are you also write articles on DEV.to. And you might already know that promoting what you write - to reach more audience, is as important as writing a good article. I always use social media platforms like Twitter, Facebook to promote my articles i.e. posting about your article on social media. About a month ago I thought of automating this process and here we are discussing it.  This post will tell you about how you can build a personal app to do this.

The entire code can be found on [github](https://github.com/Kedar-K/twitter-automation)

## Contents
[The Plan](#the-plan)
[Tech Stack or modules](#tech-stack-or-modules)
[Implementation](#implementation)
[Hosting](#hosting) (Suggestions/help appreciated)
[Scheduling](#scheduling)
[Contributing](#contributing)

## The plan
Since this is automation, the program needs to continuously run somewhere in the background so it gives us required results without human intervention. One of the approaches was to create a node.js program, but there was no such thing to schedule the node jobs online after quite some research, either I have to use [node-schedule](https://www.npmjs.com/package/node-schedule) module and never close my laptop or buy a new server and neither one looks feasible.
 
So I thought why not make a React app using create-react-app since using this I can make use of npm modules like `axios` on the client-side and hence I can host a web-app and then every time the app is opened/refreshed it will check if any new blog is available and if it is, The program posts about your latest blog.

Well, there is not much in the frontend, after reloading it just displays the message `Tweet has been tweeted (or) canceled`, you might think why to react if there is no frontend as such, well In future it will be easy for me to add developments and avoid designing the flow of data again from scratch. And all the magic happens in the express. Without spending a lot of time let's look at the implementation.

---
## Tech Stack or modules

Here are some of important stuff that I have used to create app
- [create-react-app](https://www.npmjs.com/package/create-react-app)
- [axios](https://www.npmjs.com/package/axios)
- [express](https://www.npmjs.com/package/express)
- [dotenv](https://www.npmjs.com/package/dotenv)
- [twit](https://www.npmjs.com/package/twit)


---

## Implementation

#### FRONTEND
After create-react-app, a file - tweet.js, in the src folder state is maintained and it looks like this

```javascript
  state = {
    blog_data: "", // data that we receive from DEV api
    got_data: false, // Turns to true if we got data
    error: false, // Tuen to true if error while fetching data
    final_post_content: "", // Final content to post on twitter
    content_tweeted: false, // Turns true if tweeted
  };
```

next will be a function to fetch the data from DEV.to

```javascript
    getUser = async () => {
    try {
      const response = await axios.get(
        "https://dev.to/api/articles?username=kedark"
      );
      this.setState({
        blog_data: response.data,
        got_data: true,
      });
      // console.log(this.state);
      return this.state.got_data;
    } catch (error) {
      console.error(error);
      this.setState({ error: true });
    }
  };
```
The function that we see above is called in the main function where we create the final_post_content and here are few lines from it

```javascript
      main = async () => {
    var result = await this.getUser();
    if (result && !this.state.error) {
      try {
        let latest_article = this.state.blog_data.find(
          (article) => article["type_of"] === "article"
        );

        let url = latest_article["canonical_url"];
        let tag_list = latest_article["tag_list"];
        let hash_tags = "\n";
        hash_tags += tag_list.map((tag) => "#" + tag + " ");
        hash_tags = hash_tags.replace(/,/g, "");
        let published_time = latest_article["published_at"];
        let full_content = `Hello guys, Check out my latest article
${latest_article["title"]}
${hash_tags} #100DaysofCode
${url}`;
        this.setState({
          final_post_content: full_content,
        });
        return [published_time];
      } catch (e) {
        console.log("caught an error", e);
      }
    }
  };

```

the content looks like this
> Hello guys, Check out my latest article 
10 Unique VS code extensions- Boost Your Productivity😎 
#productivity #vscode #webdev #github  #100DaysofCode 
https://dev.to/kedark/10-unique-vs-code-extensions-boost-your-productivity-8e7

and one last function i.e. for tweeting. This function calls the one we created above, let's have a look at it

```javascript
const latest_article_interval = Math.ceil(
      Math.abs(today - published_date) / (1000 * 60 * 60 * 24)
    ); // to calculate number of dates between two dates
    if (latest_article_interval === 1) {
      console.log("posting tweet");
      this.setState({
        content_tweeted: true,
      });

      axios
        .post("/api/tweet/post", {
          content: this.state.final_post_content,
        }) // send the content to express for posting
 //you can check .then(full-code), etc on github
    } else {
      console.log("no new tweets available");
      console.log("after fetching");
      console.log(this.state.final_post_content);
    }
``` 

Well, that's all for the frontend side, lets move to the backend

---

#### BACKEND

**First thing to do - Apply for the [Twitter developer account](https://developer.twitter.com/en/apply-for-access) and get the API keys in case you don't have one.**

I have used [twit module](https://www.npmjs.com/package/twit) for this purpose and [dotenv module](https://www.npmjs.com/package/dotenv) for storing API keys. let's look at some snippets now

```javascript
app.post("/api/tweet/post", (req, res) => {
  //   console.log(req.body.content);
  res.json(req.body.content);
  var T = new Twit({
    consumer_key: process.env.APIKEY,
    consumer_secret: process.env.APISECRETKEY,
    access_token: process.env.ACCESSTOKEN,
    access_token_secret: process.env.ACCESSTOKENSECRET,
  });
  console.log(req.body.content);
  T.post(
    "statuses/update",
    { status: req.body.content }, // content to post
    function (err, data, response) {
      console.log(data);
    }
  );
```

And that's it you are good to go...

---

## Hosting

For hosting you have many options like [Heroku](https://dashboard.heroku.com/), [Vercel](https://vercel.com/), etc. I personally haven't hosted this anywhere yet as I am learning to host react with express app and handling environment files while hosting, etc. Hence I am open to suggestions from you guys and any help will be appreciated.

---

## Scheduling

For scheduling, you can use [Cron-Job](https://console.cron-job.org/dashboard). Here you can give the link to your app and schedule it to run once a day at your convenient time

Here is what it looks

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kp2uwfgup0vn8yy7nj6j.png)

here are some of the other services you can use

- [Easy Cron](https://www.easycron.com)
- [My web cron service](http://www.mywebcron.com/)
- [Cronless](https://cronless.com/)
- [Cronjob Service](https://www.cronjobservice.net)
- [Set Cron](https://www.setcron.com/)
- [CallMyApp](http://callmyapp.com/)

---

## contributing

Well, any suggestions about hosting, code improvement, etc are appreciated. You can directly create a topic on GitHub or let's talk in the comments below. For contributing here are a few things to get you started.

#### Getting Started

- Clone the repository
  ```shell
  git clone https://github.com/Kedar-K/twitter-automation.git
  ```
- add environment variables

  ```shell
  cd twitter-automation
  vi .env
  ```

  and now add the following variables to the .env file

  ```
  NODE_ENV = development
  PORT = port which you would like to use ex :5000
  APIKEY = twitter api key
  APISECRETKEY = twitter api secret
  ACCESSTOKEN = twitter access token
  ACCESSTOKENSECRET = twitter access token secret
  ```

  If you dont have there you can [apply for access](https://developer.twitter.com/en/apply-for-access)

- install npm modules\
  make sure you are in twitter-automation folder

  ```shell
  npm install
  ```

  once it's completed

  ```shell
  cd frontend
  npm install
  ```

- change dev api to your blog\
   `frontend -> tweet.js -> get_user() -> change the link i.e. https://dev.to/api/articles?username={your user name} `

- run application

  ```
  cd ..
  npm run dev
  ```

---

That's all for the post guys, Hope you enjoyed it. Please consider giving an ❤ in case you liked it. This will definitely push me to write more interesting content for you guys.

Thank you.
Have a great day,
Happy Coding! 🥂