DEV Community

Cover image for Twitter Automation - automatically tweets about your new blog on DEV.to
Kedar Kodgire
Kedar Kodgire

Posted on

Twitter Automation - automatically tweets about your new blog on DEV.to

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

Contents

The Plan
Tech Stack or modules
Implementation
Hosting (Suggestions/help appreciated)
Scheduling
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 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


Implementation

FRONTEND

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

  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
  };
Enter fullscreen mode Exit fullscreen mode

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

    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 });
    }
  };
Enter fullscreen mode Exit fullscreen mode

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

      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);
      }
    }
  };

Enter fullscreen mode Exit fullscreen mode

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

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);
    }
Enter fullscreen mode Exit fullscreen mode

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


BACKEND

First thing to do - Apply for the Twitter developer account and get the API keys in case you don't have one.

I have used twit module for this purpose and dotenv module for storing API keys. let's look at some snippets now

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);
    }
  );
Enter fullscreen mode Exit fullscreen mode

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


Hosting

For hosting you have many options like Heroku, Vercel, 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. 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

here are some of the other services you can use


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
  git clone https://github.com/Kedar-K/twitter-automation.git
Enter fullscreen mode Exit fullscreen mode
  • add environment variables
  cd twitter-automation
  vi .env
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

If you dont have there you can apply for access

  • install npm modules\ make sure you are in twitter-automation folder
  npm install
Enter fullscreen mode Exit fullscreen mode

once it's completed

  cd frontend
  npm install
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

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! 🥂

Top comments (0)