Whenever something happens in one of your repos on GitHub, you can configure a webhook to be sent to your app. This way, you can perform some extra logic when a particular event occurs on the repo. A silly example would be to send someone a mail when an issue is opened.

We’ve created a new package called spatie/laravel-github-webhooks that makes it easy to consume GitHub webhooks in a Laravel app. In this blog post, I’d like to tell you all about it.

Are you a visual learner?

In this stream, I show how to use the package, go over the source code, and explain how it is tested.

Using spatie/laravel-github-webhooks

After you’ve installed the package in your app, you can start configuring what should happen when GitHub webhooks hit your app. GitHub expects your app to respond as fast as possible. That’s why the package will, when a webhook comes in, create a GitHubWebhookCall model with the payload of the webhook in the database. It will pass that model to a queued job so that an HTTP response can be sent very quickly, and the actual work that needs to be done can be performed on the queue.

In the jobs key of the github-webhooks config file, you can configure which jobs should be executed when certain events come in. Here’s an example:

<span class="line"><span>// in the `github-webhooks` config file</span></span>
<span class="line"></span>
<span class="line"><span>'jobs'</span><span> </span><span>=></span><span> [</span></span>
<span class="line"><span>    </span><span>'issues.opened'</span><span> </span><span>=></span><span> </span><span>AppJobsHandleIssueOpenedWebhookJob</span><span>::class</span><span>,</span></span>
<span class="line"><span>],</span></span>
<span class="line"></span>

In this example, the HandleIssueOpenedWebhookJob job will be dispatched when a webhook of type issues comes in with an action of opened in the payload.

Here’s how the HandeIssueOpenedWebhookJob could look like:

<span class="line"><span>namespace</span><span> </span><span>AppJobsGitHubWebhooks</span><span>;</span></span>
<span class="line"></span>
<span class="line"><span>use</span><span> </span><span>IlluminateBusQueueable</span><span>;</span></span>
<span class="line"><span>use</span><span> </span><span>IlluminateQueueSerializesModels</span><span>;</span></span>
<span class="line"><span>use</span><span> </span><span>IlluminateQueueInteractsWithQueue</span><span>;</span></span>
<span class="line"><span>use</span><span> </span><span>IlluminateContractsQueueShouldQueue</span><span>;</span></span>
<span class="line"><span>use</span><span> </span><span>SpatieGitHubWebhooksModelsGitHubWebhookCall</span><span>;</span></span>
<span class="line"></span>
<span class="line"><span>class</span><span> </span><span>HandleIssueOpenedWebhookJob</span><span> </span><span>implements</span><span> </span><span>ShouldQueue</span></span>
<span class="line"><span>{</span></span>
<span class="line"><span>    </span><span>use</span><span> </span><span>InteractsWithQueue</span><span>, </span><span>Queueable</span><span>, </span><span>SerializesModels</span><span>;</span></span>
<span class="line"></span>
<span class="line"><span>    </span><span>public</span><span> </span><span>GitHubWebhookCall</span><span> $gitHubWebhookCall;</span></span>
<span class="line"></span>
<span class="line"><span>    </span><span>public</span><span> </span><span>function</span><span> </span><span>__construct</span><span>(</span></span>
<span class="line"><span>        </span><span>public</span><span> </span><span>GitHubWebhookCall</span><span> $webhookCall</span></span>
<span class="line"><span>    ) {}</span></span>
<span class="line"></span>
<span class="line"><span>    </span><span>public</span><span> </span><span>function</span><span> </span><span>handle</span><span>()</span></span>
<span class="line"><span>    {</span></span>
<span class="line"><span>        </span><span>// React to the issue opened at GitHub event here</span></span>
<span class="line"></span>
<span class="line"><span>        </span><span>// You can access the payload of the GitHub webhook call with `$this->webhookCall->payload()`</span></span>
<span class="line"><span>    }</span></span>
<span class="line"><span>}</span></span>
<span class="line"></span>

And that is all you have to do to handle an incoming GitHub webhook in your app.

In closing

spatie/laravel-github-webhooks is very much a meat-and-potatoes kind of package. No new big ideas are introduced here. Still, the package handles a lot of work for you:

  • storing the incoming webhook
  • easy configuration of webhook handling jobs
  • pruning handle webhooks
  • sane exception management

To know more about the package, head over to the readme on GitHub. There are a lot of options not mentioned in this post. Also, be sure to look at this list of packages our team has created previously.

If you want to support our open source efforts, consider picking up one of our paid products.

Categories: PHP