Creating a GitHub Issues Autoresponder using Webask.io

Creating a GitHub Issues Autoresponder using Webask.io

A Cry in the Twitterverse

Yesterday Brad Wilson tweeted about his frustration with people posting poor quality issues on his various GitHub projects. Ted Neward responded suggesting that this sounds like a job for Auth0 Webtasks. Starting next Monday, I am going to be joining the Extend team at Auth0 as a Developer Success Engineer. Ted's suggestion sounded like a fun little project to work on while I learn about our platform. So I dug in and pieced a solution to it together. The solution I came up with involves tying together GitHub's existing webhooks and Rest API using a webtask as the glue.

Just to be clear, I am not yet an Auth0 employee. I am also new to the platform. So, there could be a lot of naivety in this post. Don't take this post as advice, it is just me playing around with webtasks. In the coming weeks, as I discover new things, I will update this post.

Create a Webtask

To start off, create an account at webtask.io. Just click the big green Try It Now button and follow along. Eventually, you will be dropped into the webtask editor. You should be presented with the Creat new dialog. If not simply click the New button on the left hand menu, or hit alt-ctrl-n on windows or cmd-ctrl-n on mac to bring it up. Select the webtask option and enter a name like on-github-issue.

You should now see the default webtask "Hello World!" code. GitHub webhooks will post to your url handing in a json object in the body of the request. So, modify the webtask code to write that object to the console. You can use this to verify the webhook is working as expected.

module.exports = function(ctx, cb) {
  console.log(ctx.body);
  cb(null, null);
};

To view your console logs, click the Logs button in the upper right hand menu, or hit alt-shift-l/ cmd-shift-l. You should see a logs view slide in from the bottom. Immediately below the logs view, in the status bar is a section that displays your webtask url. Click the copy button and head over to GitHub to create your webhook.

Create a GitHub Webhook

Click the Settings tab at the top of your GitHub repository, then the Webhooks link on the left hand menu. Click the Add webhook button; you will be prompted for your password. Next, paste the webtask url into the Payload URL field. Switch the Content type to application/json. Finally, select the Let me select individual events option, tick the box next to Issues and click the big green Add webhook button.

You should be able to test the webhook now. Create a new issue on your repository. Flip back to your webtask editor and you should see a GitHub Issues object in your logs output. If you do not, review the steps above and verify you followed them exactly or drop a comment on this post and I'll try to help you troubleshoot the issue.

The GitHub Issue object is pretty big, but the parts we care about currently look something like this.

{ 
  action: 'opened',
  issue: { 
      comments_url: 'https://api.github.com/repos/user/project/issues/1/comments',
     comments: 0,
     body: '' 
    } 
}

The action allows you to filter our responses to only the opened action. Any other value you can safely ignore. The issue object gives you the body text of the issue, a count of comments as well as a api end point url to add comments. All of these elements you could potentially use to filter your responses.

Create a GitHub Personal Access Token

Before you can post a comment, you need a way to authorize the request. The simplest way to do that is to use a personal access token. This token is associated with your user account, so it is good for all of your repositories.

On the GitHub personal access token page, click the Generate new token button. Enter a name in the Token description field and select the tickbox for repo in the Select scope list. Then click the big green Generate token button. On the next screen, you will see your token highlighted in green. Click the Copy token button and flip back to your webtask editor.

Update your Webtask

Click the Settings button in the upper left hand menu, it is the one that looks like a wrench. Then select the Secrets menu item. This will cause the Secrets dialog to slide in from the left. Click the Add secret button. Enter the key github-token and paste the copied token into the value field. Click Save.

Now, update your webtask code using the code below. Be sure to click the Save button in the upper right hand menu or hit alt-s/cmd-s.

var request = require('request');

module.exports = function(ctx, cb) {

  var token = ctx.secrets['github-token'];
  var message = {
    uri: ctx.body.issue.comments_url,
    auth: { bearer: token },
    headers: { 'User-Agent': 'issue-bot' },
    body: { body:'Plz give detailed steps to reproduce.' },
    json: true
  };
  
  if(ctx.body.action !== 'opened'){
    return cb(null, null);
  }
  
  request.post(message, function(err, res){
    if(err) {
      console.error(err);
      throw err;
    }
    
    console.log(res.statusCode);
    console.log(res.body);
    
    return cb(null, res);
  });
};

This code uses the request node module to send a message to the GitHub. You can use any npm package you comfortable with. Many of them are pre-installed and available. Simply, enter require('') in the editor and start typing in between the single quotes to see a list of all the pre-installed modules.

For each GitHub webhook call, this code pulls the personal access token out of the webtask context's secrets collection. Be careful not the write this value to your logs or send it along in the response from your webtask, keep your secrets secret.

The code then constructs a message to send to GitHub. The message will be sent to is the comments url of the issue that was just created. The token is used as a standard bearer token. GitHub requires a User-Agent header for all requests on it's API. Finally, the body of the message contains the autoresponder text to post to the newly opened issue.

Finally, the code checks action property of the payload and early outs if it is anything other than opened. If not it uses request's post method to send the message to GitHub providing a callback function that simply logs errors or successes to the logs view.

Testing and Caveats

You should now be able to create an issue on your GitHub repository and see the autoresponder in action. There is one big caveat to consider, webtasks will throttle requests to the endpoint to one per second. It is lenient according to the documentation, but large repositories with lots of activities might trigger the throttling. Remember that GitHub is going to be hitting your webhook for ALL Issue events. An active repository like Angular or .NET Core could send hit a limit. To see if this is happening, check the Recent Deliveries section of your GitHub webhook details. Look for a red error triangle.

"OPB_0013" By Orin Blomberg is licensed under CC BY 2.0

Follow me on Mastodon!