1. Webhook Pirate, credit: blog.mailchimp.com

These days many service providers (stripe, mailchimp, sendgrid, superfeedr etc) provides webhooks, which can push an event(usually a post request) with appropriate payload to your web application whenever a certain event occurs. This is pretty handy as you don’t have to keep polling or implement a service, which will keep asking for update from these third party services.

Use-cases:

You want to update a subscription, whenever your customer makes a payment via a third party payment service(e.g. stripe). You want to parse a email reply from a user and display it’s content on your web application something like Basecamp. (e.g. SendGrid, Mailchimp webhooks) You want to consume RSS feeds generated by several feed sources using a third party service (e.g. Superfeedr) And many more…(Right now, I could recall only above 3 use-cases from our past projects ;-)

In this tutorial, we’ll learn:

What is webhook? How to develop a secure callback end-points? How to consume webhook calls in development environment?

What is webhook?

A webhook can be considered as inverted API endpoint, where instead of your application calling an API endpoint, you provide a callback URL to the third party service for a particular event. The third party service will make a post request to your callback URL with payload whenever the event occurs, which can be consumed by your application.

Let’s say whenever someone makes a payment via Stripe, you want to update subscription in your application database. Thus you setup a callback URL on stripe for all successful subscription. Whenever user makes a successful payment, stripe will post a request to your predefined callback URL with appropriate payload, thus enabling you to update the payment in your database. The setup of webhooks might involve a few more steps depending upon your service provider. For example, inbound email parsing with sendgrid involves adding MX record with your DNS provider. Thus, you must refer your service provider documentation for the webhook setup.

2. Webhook and Callback Triggering

How to develop a secure callback end-points?

Since your callback URL is exposed to public, thus you must ensure the requests to your callback URL is secure. While registering your callback URL, many service provider also gives you an option to provide a secure token, so that your application will process the callback request if and only if the request contains the valid token. Another good way to secure your callback URL is by obscurity.

Security by Obscurity: Let’s say we’re using a subscription model payment service FaodailPayments, where user will be subscribed with individual callback end-point. The payment service will be pushing all events triggered by a user to the callback end-point assigned to the user at the time of subscription with a payload with required details about the event. The service also provides an API end-point to register the user with them.

Step 1: Subscription

We’ll store subscriptions in Subscription model. At the time of subscribing each user via service provider API end-point, we’ll generate an obscure token as below:

/app/models/faodail_payment/subscription.rb

Please note that, we’ve used FaodailPayment namespace for the model, as you might already have another Subscription model in your application. It’s always a good practice to namespace external services, even if you don’t have a model with same name.

The FaodailPayment::Base class will look something like below:

/app/models/faodail_payment/base.rb

Step 2: Create routes and action

Now we have an obscure webhook_token associated with each user, we’ll create a route to consume the callback requests.

routes.rb

Here we’re consuming the service provider callbacks on faodail subdomain. Now we’re free to consume the webhook callbacks via following controller:

/app/controllers/faodail_webhooks_controller.rb

Best practices while developing callback end-points

Use different sub-domain for each service provider. If you’re using send-grid, you might want to all of your end-point hitting sendgrid.example.com Wherever possible, set obscure token for each endpoint while registering callback URL with service providers. Wherever possible, create obscure end-points for callback URLs Namespace each services independently.

How to consume webhook calls in development environment?

When we integrate such external services, we need a way to consume the service callback requests on our development machine. There are many tools (ngrok, pagekite, zipidoo etc) which can help you tunnel your localhost to external web. I’ve used ngrok and did not find any reason to switch away from it.

You can download ngrok from here. You can start ngrok with following command from the directory where you’ve downloaded ngrok:

./ngrok http 3000

If your server is running on other port than 3000, you must change the port number in above command. If you want a subdomain, you can execute:

./ngrok http 3000 -subdomain=faodail

ngrok localhost tunnelling

You can share the above URL with anyone and they’ll be able to view what’s running on your localhost :)

Congratulations! You’ve successfully integrated a secure webhook :)