loading...
Cover image for How to create a chatbot to talk with your GitHub repos

How to create a chatbot to talk with your GitHub repos

jcabot profile image Jordi Cabot Originally published at livablesoftware.com ・6 min read

Sustainability of open source is a huge problem. There are many ways to help the maintainers but one growing trend is the creation of bots that automate some of the tasks. See a good list of existing bots you can add to your OSS project.

In this post, we'll show you how you could easily build your own bot for GitHub. Not just a "simple" bot, but a chatbot!. Once we're done you'll be able to chat with your GitHub repositories. To make things even more interesting, we'll deploy the chatbot as a Slack app. As example bots, we'll create two chatbots:

  1. (for users) A bot that helps your users write good bug reports so that you don't waste your time trying to reproduce their bugs with incomplete information
  2. (for maintainers) A bot that pings you on Slack when a new issue is created and lets you assign labels and developers to it.

To create such a chatbot you'll need to interact with the Slack API, the GitHub API and at least a Natural Language Understanding (NLU) component, like DialogFlow. Instead of manually doing all this work ourselves, we will rely on Xatkit platform (an open-source low-code chatbot development framework). Xatkit already provides an abstraction of these three elements, heavily simplifying the development of chatbots, as you'll see in a moment (for the TL;DR people, check the Xatkit organization in GitHub and take a look at the code of the example bot).

In Xatkit, you define the bot behaviour via two different files: the intent library (that specifies the potential intentions of the user when talking to the chatbot) and the execution model (that defines how to react to the user intentions or other events directly received by the bot). Let's see how we can use Xatkit to create our two bots.

Filing a bug report from Slack

If you look at any OSS project, the firsts iterations in any new bug report consist in the maintainer trying to get from the user who submitted the report all the information needed to reproduce it. This is a huge waste of time for both sides. And one that delays significantly the bug fixing since the communication is not synchronous so depending on the respective availability and time zones, it can go on for a few days.

I'll show you how a chatbot can make sure a bug report has all the basic information a maintainer needs. In the example, we assume the project is a WordPress plugin. Typically, to debug a potential error there we always need to know the WP version and the PHP version the website is running. So to illustrate the capabilities of our chatbot approach for GitHub we'll make sure the chatbot collects this information.

We start by defining the intents. Note that some of the intents are only possible after a previous intent has been matched. Some of the intents store conversation data that we'll use to open the bug at the end.

intent OpenBug {
    inputs {
        "The plugin is not working"
        "I have a problem with the plugin"
        "I'd like to report an error"
        "I want to open a bug"
        "I want to report a bug"
        "There is an error in the plugin"
    }
    
}

intent DescribeBug follows OpenBug {
    inputs {
        "My error is Error"
        "The problem is Error"
        "I get this error: Error"
        "My error is that Error"
        "The problem is that Error"
        "I get the error Error"
    }
    creates context bug {
        sets parameter title from fragment Error (entity any)
    }
}

intent TellWPVersion follows DescribeBug {
    requires context bug
    inputs {
        "My version number is WPVersion"
        "I use number WPVersion"
        "It's version WPVersion"
    }
    creates context bug {
        sets parameter wpversion from fragment WPVersion (entity number)
    }
}

intent TellPHPVersion follows TellWPVersion {
    requires context bug
    inputs {
        "My version is PHPVersion"
        "I use PHPVersion"
        "It's version PHPVersion"
        "The server is on php version PHPVersion"
    }
    creates context bug {
        sets parameter phpversion from fragment PHPVersion (entity number)
    }
}

This is an example dialog with this chatbot.

Chatbot to fill a bug report from Slack

And once all the error info has been gathered, we just need to put it all together and open an issue with it. As you can see in the following code excerpt, once the last intent has been matched we ask GitHub to create a new issue with the title and body parameters we collected along the way. We end up labeling the new issue as a bug.

on intent TellPHPVersion do
    action SlackPlatform.Reply(message : "Thanks for your detailed info")   
    def newissue = action GithubPlatform.OpenIssue(user : "jcabot", repository : "xatkit-tests", issueTitle : context(bug).get("title") , 
            issueContent : "WP version is " + context(bug).get("wpversion") + " PHP version is " + context(bug).get("phpversion") 
    )
    action GithubPlatform.SetLabel(issue : newissue, label : "bug")

This generates as end result the following issue created from the above dialog.

From GitHub to Slack: receiving and reacting to GitHub notifications

Let's now how we can get notified in Slack of things happening in GitHub. In this example, we'll just look at "New issue" notifications. The bot should be able to:

  1. Receive New Issue notifications from GitHub
  2. Save time to the maintainer by enabling her to assign a label to the issue and a potential developer that could follow-up on it

To process the OpenIssue notification and forward it to Slack, we just need to write this piece of code

on event Issue_Opened do
    action SlackPlatform.PostMessage(message : "An issue has been opened with the title " + context(issue).get("issue->title"), channel: config(slack.channel))
    def issue = action GithubPlatform.GetIssue(user : config(github.repository.username), repository : config(github.repository.name), issueNumber : context(issue).get("issue->number"))
    session.store("issue", issue)

where we get the issue information from the event and post it to Slack (SlackPlatform is part of the predefined Slack platform in Xatkit). The issue itself is also stored in the session for further use.

Once the maintainer gets the notification, the chatbot starts listening to see if the maintainer expresses any intention to add a label or assign a user to it. These intents definitions will try to match whatever the maintaner writes in Slack to these two potential actions.

intent SetLabel {
    requires context issue
    inputs {
        "Set label Label"
        "Give label Label"
    }
    creates context  issue {
        sets parameter issueLabel from fragment Label (entity any)
    }
}

intent AssignUser {
    requires context issue
    inputs {
        "Assign user Username"
        "Username will take care of it"
    }
    creates context  issue {
        sets parameter assignedUsername from fragment Username (entity any)
    }
}

Note that, as for the previous bot, intents are defined via a set of training sentences. Training sentences try to represent the different ways a maintainer can express that intention (e.g. set label or give label). Thanks to our DialogFlow integration, additional variations will also be recognized: see the following dialog, where I write "Add label" instead of Set or Give.

After this chat, the new issue gets properly tagged and assigned in the GitHub repo. No need for the maintainer to move out of Slack to do so. The execution actions associated with the intents take care of this.

on intent SetLabel do
    action GithubPlatform.SetLabel(issue : session.get("issue"), label : context(issue).get("issueLabel"))
    action SlackPlatform.Reply(message : "Done!")

GitHub issue created from Slack

Summary: chatting with GitHub

To sum up, in a few lines of code we've been able to create a bidirectional Slack-GitHub chatbot to help open source maintainers. This was just an example but I hope it's a good enough example to showcase the potential of (chat)bots to significantly improve the sustainability of open-source.

Posted on by:

jcabot profile

Jordi Cabot

@jcabot

ICREA Research Professor at IN3 (UOC) where I’m leading the SOM Research Lab focusing on the intersection between software engineering, AI and open source. Xatkit founder.

Discussion

markdown guide
 

Very interesting! But I can't help but ask what would be a practical use case for something like this. Without thinking too hard only very overengineered solutions come to my mind.

 

Hi Johannes,

I think (chat)bots make sense for maintainers of either lots of projects or projects with a large community behind.

In the end, the platform allows you to provide a chat interface on top of GitHub (and get notifications from GH to manage GH events from another platform).

You could for instance easily create something like Pull Reminders (recently bought by GitHub so I guess at least there were some people that find it useful :-) ) or use the chatbot to enforce the guidelines for user contributions or requests.

 

Thanks for explaining. Totally makes sense.