Create a Webhook from the Aircall Dashboard
Beginner guide to create a Webhook and listen to Aircall events.

This tutorial will guide you through the creation of a Webhook integration on Aircall Dashboard.

Getting started

Before starting to code, you will need to have:

  • A server, to run the backend application we are going to create. You can use Heroku or any hosted solution you prefer.
  • An Aircall account - sign up here.

Step by step

Now we are all setup, here are the steps we are going to follow:

  1. Create an Aircall Webhook from the Aircall Dashboard
  2. Create API endpoints
  3. Listen to specific Aircall events

1 - Create a Webhook from the Aircall Dashboard

You can create and manage Webhooks from your Dashboard. For this tutorial, we will only subscribe to the call.created event but you can activate the ones that suit your needs.

  1. Go to the Integration page in your dashboard
  2. Click on the Webhook integration and on the Install button
  3. Toggle the switches of the events you want to receive
  4. Optional: In the integration name (custom) field, set a name to easily identify your Webhook in the integrations list
  5. In the url field, set the value to the url of your future web server followed by /aircall/calls (i.e. https://my-webhook-integration.herokuapp.com/aircall/calls)
  6. Click on the Save button to confirm the creation of the webhook

Webhook creation

There is a limit of 100 webhooks you can create per account

2 - Create new endpoints

At this point, you will need to have a running server to move forward (for Heroku, check the Getting starting documentation).

  • Let's start by adding an index route responding to the GET method - if you don't already have one:
javascript
const app = require('express')(); const bodyParser = require('body-parser'); app.use(bodyParser.json()); app.get('/', (req, res) => { res.json({'message': 'Server is running'}); });
ruby
# config/routes.rb Rails.application.routes.draw do # You can have the root of your site routed with "root" root 'welcome#index' end # controllers/welcome_controller.rb class WelcomeController < ApplicationController # GET / def index render :ok, json: { message: 'Server is running' } end end
go
package main import ( "log" "net/http" "github.com/gin-gonic/gin" ) func main() { port := os.Getenv("PORT") if port == "" { log.Fatal("$PORT must be set") } router := gin.Default() router.GET("/", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "Server is running"}) }) router.Run(":" + port) }
  • Then we need to add a new route POST /aircall/calls which will handle all incoming webhooks:
javascript
// POST /aircall/calls app.post('/aircall/calls', (req, res) => { res.sendStatus(200); });
ruby
# config/routes.rb Rails.application.routes.draw do # You can have the root of your site routed with "root" root 'welcome#index' # Post route that invoke 'calls' method from WebhookController post 'aircall/calls' => 'webhook#calls' end # controllers/webhook_controller.rb class WebhookController < ApplicationController # POST /aircall/calls def calls head :ok end end
go
router.POST("/aircall/calls", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) })

Your server should always return a "200" HTTP status code. After 10 failed attempts, Aircall will automatically disable your webhook.

3 - Listen for specific events

Once our routes are created, we want them to handle specific events. Aircall will send the event type in the body of the request, set as the event attribute.

Here is an example of the call.created payload:

json
{ "resource": "call", "event": "call.created", "timestamp": 1512588391, "token": "123ASECRETTOKEN456", "data": { "id": 123, ... "direction": "inbound", "raw_digits": "+19171234567" ... } }
  • We will update our webhook handler to execute business logic when we receive call.created:
javascript
app.post('/aircall/calls', (req, res) => { if (req.body.event === 'call.created') { // Run some logic } else { console.warn('Even type non-handled:', request.body.event); } res.sendStatus(200); });
ruby
def calls if params[:event] == 'call.created' # Run some logic else logger.warn "Event type non-handled: #{params[:event]}" end head :ok end
go
type Call struct { Event string `json:"event" binding:"required"` } router.POST("/aircall/calls", func(c *gin.Context) { var body Call c.BindJSON(&body) if body.Event == "call.created" { // Run some logic } else { log.Println("Event type non-handled: " + body.Event) } c.JSON(http.StatusOK, gin.H{}) })

Now, it's time for you to add your business logic! If you need more information about the objects sent with the events, follow this link.

We wrote other tutorials to help you out
building awesome integrations

Discover them now