loading...
Cover image for Using Github actions to send Tweets

Using Github actions to send Tweets

skippednote profile image Bassam Ismail ・3 min read

Recently I deprecated my Twitter account which I have been using for more than 12 years. As of today, the deprecated account is still running I just have updated the handle to _skippednote and created a new account. In the early days, I tweeted a lot about a lot of things that I don't believe in now and I don't want to carry that baggage. The implication of moving to a different account is that I have to start afresh which means 0 followers and 0 credibilities. So before I deactivate my account I wanted to send reminders to the followers on the older account notifying them that I have changed my account.

To run time-based jobs the most common solution available is cron (or cron job), however, we need a server to schedule and run these jobs. Setting up a server was too much work for my use case which is just sending a tweet once a day and so I opted for the next best thing: Github Actions. Github Actions is primarily used for CI/CD where we set up jobs to run when based on various Github events or a cron schedule. For our limited use, we can schedule jobs to send exactly one tweet every day and this costs nothing as it's within the free use limit.

I wrote a Node.js script that when run sends a tweet with a message that calculates numbers of days till 25th October which is when I plan to deactivate the account.

const Twit = require('twit');
const {
  CONSUMER_KEY,
  CONSUMER_SECRET,
  ACCESS_TOKEN,
  ACCESS_TOKEN_SECRET,
} = process.env;

const T = new Twit({
  consumer_key: CONSUMER_KEY,
  consumer_secret: CONSUMER_SECRET,
  access_token: ACCESS_TOKEN,
  access_token_secret: ACCESS_TOKEN_SECRET,
});

const daysToDeletion = 25 - new Date().getDate();

const message = `👋 Hey there folks!.
This is an automated message 🤖 to remind you that this account has been renamed to @_skippednote and will be deactivated in the next ${daysToDeletion} days.
I've moved to @skippednote, you can come follow me there ♥️`;

(async function main() {
  try {
    await T.post('statuses/update', { status: message });
    console.log('Successfully posted the tweet!');
  } catch (e) {
    console.log('Failed to post the tweet!');
    console.log(e.message);
  }
})();
Enter fullscreen mode Exit fullscreen mode

I'm using the Twit node module which use with Twitter v1.1 API and supports both promise and callback-based methods. The interesting bit here is how and where are the environment variables defined, we don't put them in the file as it then becomes a security risk. Similar to other CI/CD systems, Github Actions allows us to add Secrets (environment variables) via repository settings.

GitHub Secrets

To set up a Github Action, we need to create a .github directory at the root of our repository and within that, we create a workflows directory which contains jobs that would be run based on various Github Actions. The name of the file under the .github/workflows directory doesn't matter as long it's a yaml file. In our case we want a job to run on a schedule so I named it .github/workflows/cronjob.yml.

name: Twitter message

on:
  schedule:
    - cron: '15 6 * * *'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
      - name: Setup Node.js
        uses: actions/setup-node@v1
        with:
          node_version: '12'
      - name: Install Node modules
        run: npm i
      - name: Tweet message
        run: node tweet.js
        env:
          CONSUMER_KEY: ${{ secrets.CONSUMER_KEY }}
          CONSUMER_SECRET: ${{ secrets.CONSUMER_SECRET }}
          ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
          ACCESS_TOKEN_SECRET: ${{ secrets.ACCESS_TOKEN_SECRET }}
Enter fullscreen mode Exit fullscreen mode

The name attribute appears on the Github Action page to help you easily find the job. Since we called it Twitter message, you can see in the screenshot below in the left sidebar we have a workflow under the same name.

GitHub Workflows

on key here allows us to run the job on a cron schedule. We till Github actions to run it every day once at 6:15 am. It's important to note that Github Actions is configured to use UTC timezone.

In the job section of the file, we set up the environment to use the latest release of Ubuntu and then use preconfigure actions to:

  1. Checkout the repository
  2. Setup Node.js version 12
  3. Run the script we created earlier to send out the tweet.
    1. Here we are exposing the secret we defined on the settings page to the task using env

GitHub Build

Once the build run, the tweet is sent with the generated message.

GitHub Tweet
https://twitter.com/_skippednote/status/1316629984685981696

Discussion

pic
Editor guide