Writing GitHub bots in .NETMar 4, 2022 · 4 minute read · Comments
I wanted to give a quick example of how to get up and running with
Octokit.Webhooks, and what better way than to write a small GitHub bot?
The default template is set up to be a weather forecast API, but I can simplify it a bit more for this sample. My
Program.cs looks like this:
Next up I’m going to install the Octokit.Webhooks.AspNetCore package:
This package consumes the Octokit.Webhooks package, which contains core functionality like deserializers and processors, and adds ASP.NET Core specific code, like automatic API endpoint mapping and shared secret verification.
Now that I’ve got my project set up, I need to create my own processor to handle incoming webhooks.
Octokit.Webhooks ships with an abstract class called
WebhookEventProcessor that does all the heavy lifting of deserializing incoming webhooks. All I need to do is to create my own class that inherits from it, and write some logic to act on the webhook events.
I created a small class
MyWebhookEventProcessor that inherits from
WebhookEventProcessor, and has an override for
ProcessIssueCommentWebhookAsync that logs out the comment body. I also get the headers and the action passed to this method, so I could write a switch case and have different handling for created, edited, and deleted actions, but this is enough for now.
I also need to hook up
MyWebhookEventProcessor in my startup class.
This is enough to tell ASP.NET to hook up dependency injection for
MyWebhookEventProcessor, enable routing. It will also automatically add a route to handle incoming GitHub webhooks. By default it’s exposed at
/api/github/webhooks, but you can use any route you’d like.
MapGitHubWebhooks also accepts a shared secret which allows you to verify the content signature of GitHub webhooks.
That’s all the code required on my side. Now I just need to expose my service to the internet, and configure GitHub to start sending me webhooks.
GitHub webhook configuration
For GitHub to be able to send me webhooks, my service needs to be publicly accessible to the internet. I recently discovered a neat little service to do this with nothing more than ssh: localhost.run.
If I run my app with
dotnet run then I can find the port that it’s running on:
And using localhost.run I can create a tunnel for that port:
Now on GitHub if I visit the settings for a repository, and go to webhooks, I can create a new webhook configuration using that domain name.
Now all I need to do is create a comment on an issue in the same repository….
And it’ll get logged in my terminal!
Making it interactive
Logging things to the terminal is great and all, but to make it a bot it should really do something. For that I’ll need the
And I’ll use it in
For this example I’m using a personal access token. You can create your own here. If I were deploying this as a production service, I would probably use something a bit more robust, like a GitHub App.
I need to do that cast from
Octokit still has an open PR to convert all its IDs to
long. I’ve also got to add the
async modifier to my method, so I can
await the issue comment creation method in Octokit.
Once I’ve done all that, I can create an issue comment on my repository on GitHub and my “bot” will reply!
If you find the library useful or interesting, give it a star on GitHub. And create an issue or pull request if you find find a bug or have a feature request.
If you want to create a fully-fledged bot, check out the GitHub documentation on creating a GitHub app. It’s the next progression from PATs, and allows you to more easily share your bot.