How to locally test your Webhooks using Ruby

8 min read
Tags:

Utilizing Webhooks is an excellent method to receive notifications when specific events occur, such as receiving an email, an event getting updated, or a contact being created. Normally, an externally accessible web server would be required to work with webhooks. However, thanks to the latest update on the Nylas Ruby SDK, all we need to test webhooks in a local setup is our Ruby environment.

What are we going to talk about?

Ways to test Webhooks

As we’ve seen, we can employ a web server to test our webhooks, as demonstrated using Ruby, Python, and PHP. Additionally, we can test webhooks locally using the Nylas CLI.

In Episode 26 of Coding with Nylas, titled Exploring Nylas’ Webhook Utilities we received a glimpse of using the NodeJS SDK to test webhooks locally.

Now, let’s delve into our main focus: demonstrating how to use another one of our SDKs to test webhooks locally—the Ruby SDK.

Why test Webhooks locally

Testing anything on our local machine is preferable, as it allows for quick fixes if anything goes wrong. Testing on a web server can be more complex, often requiring a repetition of a lengthy workflow to implement necessary changes.

Local testing ensures everything works correctly before transferring it to an external web server.

What does our application look like?

Our application is designed as a terminal application, eliminating the need for any involvement of a web server. Each time a new webhook notification occurs, it will appear automatically.

To enhance the user experience, we’ll integrate the curses library to add some vibrant colours to our otherwise terminal application.

Test local webhooks with Ruby

As we can here, we’re going to have the following information available:

  • Id → The message id. This will help us to retrieve the message information.
  • Date → Date and time when the webhook notification gets generated.
  • Email From → Who is sending the message
  • Email To → Who is receiving the message
  • Title → Subject of the message
  • Type → Type of Webhook, created, updated or opened.

Is your system ready?

If you already have the Nylas Ruby SDK installed and your Ruby environment configured, feel free to continue reading this blog.

However, if you haven’t done so yet, I recommend checking out the post on How to Send Emails with the Nylas Ruby SDK to grasp the setup basics.

Installing the Curses gem

The installation process is straightforward. Simply type the following command in your terminal window:

$ gem install curses

Creating our terminal application

We just need to create a single file named local_webhook.rb and add the following code:

#!/usr/bin/env ruby
# frozen_string_literal: true

# Import your dependencies
require 'dotenv/load'
require 'nylas'
require 'curses'

# To call the library directly
include Curses

# Initialize the nylas client as an instance variable
@nylas = Nylas::API.new(
  app_id: ENV['CLIENT_ID'],
  app_secret: ENV['CLIENT_SECRET'],
  access_token: ENV['ACCESS_TOKEN']
)

# Define the callback for the on_message event
def on_message(delta)
  @win.refresh
  # Check the type of webhook received
  unless delta.type == WebhookTrigger::MESSAGE_CREATED || 
         delta.type == WebhookTrigger::MESSAGE_OPENED || 
         delta.type == WebhookTrigger::MESSAGE_UPDATED
    return
  end

  # Get information about the email
  begin
     message = @nylas.messages.find(delta.id)
  rescue => error
    message = @nylas.messages.find(delta.metadata["message_id"])
  end
  @x_pos += 1
  @win.setpos(@x_pos, 0)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)
  @win.setpos(@x_pos, 1)
  Curses.init_pair(2, 2, 0)
  @win.attrset(color_pair(2))
  # Get the message id
  @win.addstr(message.id)
  @win.setpos(@x_pos, 26)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)
  Curses.init_pair(2, 2, 0)
  @win.attrset(color_pair(2))
  @win.setpos(@x_pos, 27)
  # Get the date
  @win.addstr(message.date.to_s[0..19])
  @win.setpos(@x_pos, 46)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)
  @win.setpos(@x_pos, 47)
  Curses.init_pair(2, 2, 0)
  @win.attrset(color_pair(2))
  # Who's the email owner
  @win.addstr(message.from.first.email)
  @win.setpos(@x_pos, 70)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)
  Curses.init_pair(2, 2, 0)
  @win.attrset(color_pair(2))
  @win.setpos(@x_pos, 71)
  # Who's receiving the email
  @win.addstr(message.to.first.email)
  @win.setpos(@x_pos, 94)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)  
  @win.setpos(@x_pos, 95)
  Curses.init_pair(2, 2, 0)
  @win.attrset(color_pair(2))  
  # Get the email subject
  @win.addstr(message.subject[0..28])
  @win.setpos(@x_pos, 123)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)
  Curses.init_pair(2, 2, 0)
  @win.attrset(color_pair(2))
  @win.setpos(@x_pos, 124)
  # Type of webhook received
  @win.addstr(delta.type)
  @win.setpos(@x_pos, 138)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)

  @x_pos = @x_pos + 1

  @win.setpos(@x_pos, 1)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addstr('-----------------------------------------------------------------------------------------------------------------------------------------')

  @win.refresh
end

# Config that sets the region, triggers, and callbacks
config = {
  "region": 'us',
  "triggers": [WebhookTrigger::MESSAGE_CREATED,
               WebhookTrigger::MESSAGE_OPENED,
               WebhookTrigger::MESSAGE_UPDATED],
  "on_message": method(:on_message)
}

begin
  # Define a new window
  @win = Curses::Window.new(0, 0, 1, 2)
  # Initialize the screen
  init_screen
  # Hide the cursor
  curs_set(0)
  # We want to use colors
  start_color
  # Initialize the color
  Curses.init_pair(208, 208, 0)
  # Set color number and set font to bold
  @win.attrset(color_pair(208) | A_BOLD)
  @x_pos = 4
  # Define the text position
  @win.setpos(0, 62)
  # Write the text
  @win.addstr('Webhooks')

  @win.setpos(2, 1)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addstr('-----------------------------------------------------------------------------------------------------------------------------------------')

  @win.setpos(3, 0)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  # We using a character instead of a string
  @win.addch('|'.ord)
  @win.setpos(3, 1)
  Curses.init_pair(32, 32, 0)
  @win.attrset(color_pair(32))
  @win.addstr('           Id           ')
  @win.setpos(3, 26)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)
  @win.setpos(3, 27)
  Curses.init_pair(32, 32, 0)
  @win.attrset(color_pair(32))
  @win.addstr('        Date       ')
  @win.setpos(3, 46)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)
  @win.setpos(3, 47)
  Curses.init_pair(32, 32, 0)
  @win.attrset(color_pair(32))
  @win.addstr('     Email From    ')
  @win.setpos(3, 70)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)
  @win.setpos(3, 71)
  Curses.init_pair(32, 32, 0)
  @win.attrset(color_pair(32))
  @win.addstr('     Email To      ')
  @win.setpos(3, 94)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)  
  @win.setpos(3, 95)
  Curses.init_pair(32, 32, 0)
  @win.attrset(color_pair(32))
  @win.addstr('           Title                 ')
  @win.setpos(3, 123)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)
  @win.setpos(3, 124)
  Curses.init_pair(32, 32, 0)
  @win.attrset(color_pair(32))
  @win.addstr('     Type     ')
  @win.setpos(3, 138)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addch('|'.ord)
  @win.setpos(4, 1)
  Curses.init_pair(0, 0, 0)
  @win.attrset(color_pair(0))
  @win.addstr('-----------------------------------------------------------------------------------------------------------------------------------------')

  # Refresh the window
  @win.refresh
  # Create, register, and open the webhook tunnel for testing
  Nylas::Tunnel.open_webhook_tunnel(@nylas, config)
  # Refresh the window again
  @win.refresh
# Ensure gets always evaluated
ensure
  # Close the screen and finish the application
  close_screen
end

First, let’s create a new curses window and begin setting up the interface of our application. This involves defining the titles of the components that we intend to display:

No webhook recieved yet

The config variable will store the region, and the registered webhook triggers, and define an on_message method.

The line Nylas::Tunnel.open_webhook_tunnel(@nylas, config) establishes a webhook tunnel connecting our application with the Nylas service:

Creating a new webhook

The on_message method will be invoked whenever a new webhook notification occurs. In this section, we’ll examine the notification type and define the content of our terminal application.

Leveraging the curses library, we can designate the text’s colour and its position on the screen.

Tracking emails

How do we trigger the opened event? We can achieve this by sending a trackable email. For that purpose, let’s create a simple application named EmailTracking.rb:

#!/usr/bin/env ruby
require 'dotenv/load'
require 'nylas'

nylas = Nylas::API.new(
    app_id: ENV["CLIENT_ID"],
    app_secret: ENV["CLIENT_SECRET"],
    access_token: ENV["ACCESS_TOKEN"]
)

tracking = {
        "links": true,
        "opens": true,
        "thread_replies": true,
        "payload": "new-payload",
}

nylas.send!(
    to: [{ email: '[email protected]', name: "Blag" }],
    subject: "With Love, from Nylas",
    body: "This email was sent using the Ruby SDK for the Nylas Email API.",
    tracking: tracking
    ).to_h

Running our terminal application

The only thing we need to do is to run our script like this:

$ ruby local_webhook.rb

And start sending and receiving emails.

To run our EmailTracking.rb application, type this on the terminal window:

$ ruby EmailTracking.rb

What’s next?

Test local webhooks with Ruby saves you a lot of time and helps you to prevent errors.

If you want to learn more about Webhooks, go to our documentation.

You can sign up for Nylas for free and start building!

Don’t miss the action, join our LiveStream Coding with Nylas:

Related resources

How to block time slots in Outlook and Google calendar with Nylas Calendar API

Key Takeaways Managing calendar availability is essential for professionals, teams, and businesses to stay organized…

How to Solve Webhook Integration Challenges with PubSub Notification Channel

Key Takeaways This article addresses the challenges of webhook integration and introduces the PubSub Notification…

How to Send Emails Using an API

Key Takeaways This post will provide a complete walkthrough for integrating an email API focused…