Build Webhooks using Ruby and HostedHooks May 2021 · ian

Introduction

This article will be a walkthrough of how to implement HostedHooks - Webhooks as a Service platform using Ruby.

Before you dive into integrating the API you should go through the process to correctly setup your HostedHooks instance. This will give you the requisite ids and setup the test endpoint that you will be sending your webhook messages to.

We cover that setup in this post - How To Setup Your HostedHooks Instance

If you have already setup your instance, you can skip that and continue on with the Ruby implementation.

We will walk through how to use Ruby to construct the API calls needed to send Webhook messages to your susbcribers.

API Setup

For every HostedHooks API call you will need to pass in your API_KEY, this can be found in your settings here.

We'll reference that API key in the examples with the environment variable

HOSTEDHOOKS_API_KEY

Now that we have our API key we need to grab some data for the API call. In the example below we will be sending a webhook message whenever a new user has been created. I've setup this webhook event on the HostedHooks platform and labeled it as 'user.created'.

There are two ways to send webhook API calls:

  1. Send the message to the app level, which will notify all subscribers of that app that are also subscribed to the specific webhook event that was triggered (user.created in our case). This method is easy, but may not work if you need to send record specific data to your subscribers. If that is the case you should use the 2nd method.
  2. Send the message directly to an endpoint, which will notify only the subscriber of that endpoint. This method is much more direct, but requires you to map subscriberid and endpointid to your users.

We'll walk through both examples and then move on to the sample code.

Method 1: Send a Message to an App

For this API call we will be sending a POST request to the messages (app) API but will be targeting a specific app. To make this call we will need the App UUID that we want to send the message to. You can copy that UUID by heading to your dashboard, clicking on the App that you want to use and copy the UUID at the top of the page.

Hosted Hooks - copy app uuid

We will need to take that App UUID and pass it into the Messages API URL which will look like this:

https://www.hostedhooks.com/api/v1/apps/:app_uuid/messages

If you need to send subscriber specific data inside your webhook message than this next method is likely the route you will want to take.

Method 2: Send a Message to an Endpoint

For this API call we will be sending a POST request to the messages (endpoint) API, but will be targeting a specific endpoint. To make this call we will need the Subscription UUID for the Subscriber and the respective Endpoint UUID which defines where we will send the message to. You can copy that UUIDs by heading to your dashboard, clicking on the Subscriber that you want to use and copy the UUID at the top of the page.

Hosted Hooks - copy subscription uuid

Hosted Hooks - copy endpoint uuid

We will need to take that Subscription UUID and Endpoint UUID and pass it into the Messages API URL which will look like this:

https://hostedhooks.com/api/v1/subscriptions/:subscription_uuid/endpoints/:endpoint_uuid/messages

Now that we have all of the data required for the API call, let's walk through the code.

Setting Up The Code

Lastly, we will want to update the data JSON object which is being sent. You are free to put whatever you want inside that data object. We will pass everything inside onto your subscribers. For the sake of this example we will add a nested user object and add some user data.

message_payload = {
  data: {
    user: {
       id: user.id, 
       created_at: user.created_at
      }
    },
    version: "1.0",
    event_type: "user.created",
    event_id: "07a1cf3fd7cced67a7fd"
  }
}

Outside of the data object there are a few additional parts of the message payload, let's go through them here:

  • version - This is the version of the payload that you are sending (more info here)
  • event_type - This is the event that you are sending webhooks on behalf of (user.created in our case)
  • eventid - This is a unique string that HostedHooks will check to maintain idempotency. You should generate this on your end and could store this if you wanted to. We will ignore multiple requests with the same eventid

Once you've constructed your request payload, you can now make the request using whatever HTTP library you want. In our example we've used Net/HTTP. See the example request below. Note we have provided two URIs, one for each method of sending messages. You would need to pick which one suits your usecase.

require 'net/https'
require 'uri'

# Callback when a user is created
def after_user_created
  send_webhook_message(user)
end

# POST Messages 
def send_webhook_message(user)

  #Method 1 - Send message to App   
  uri = URI("https://www.hostedhooks.com/api/v1/apps/:app_uuid/messages")

  #Method 2 - Send message to Endpoint
  uri = URI("https://hostedhooks.com/api/v1/subscriptions/:subscription_uuid/endpoints/:endpoint_uuid/messages")

  # Set Headers
  headers = {"Content-Type": "application/json", "Authorization": "Bearer #{ENV['HOSTEDHOOKS_API_KEY']}"}

  # Build Message JSON payload
  message_payload = {
    data: {
        user: {
          id: user.id, 
          created_at: user.created_at
        }
      },
      version: "1.0",
      event_type: "user.created",
      event_id: "07a1cf3fd7cced67a7fd"
    }
  }

  # Create Request
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  request = Net::HTTP::Post.new(uri.request_uri, headers)
  request.body = message_payload.to_json

  # Send the request
  response = http.request(request)

  puts "Response HTTP Status Code: #{ response.code }"
  puts "Response HTTP Response Body: #{ response.body }"
rescue StandardError => e
  puts "HTTP Request failed (#{ e.message })"
end

If that request is succesful you will get back a 200 and JSON response like below.

{
  "id": "4e4fffcb-295b-4b79-cda3-02cc4720f0ba",
  "data": {
    "user": {
      "id": 123,
      "created_at": "2021-05-11T08:51:40.679-04:00"
    }
  },
  "event_id": "07a1cf3fd7cced67a7fd",
  "event_type": "user.created",
  "created_at": "2021-05-11T08:51:40.679-04:00",
  "app": {
    "id": "bf111747-9635-46fb-as23-9b6e45402f47",
    "name": "SaaS Site",
    "created_at": "2021-03-31T21:24:48.376-04:00"
  }
}    

Once that message has been submitted, it will be processed by HostedHooks and routed to the correct subscribers. If there are any deliverabiliy issues, we will retry (with exponential backoffs) for a total of 5 times and then notify you if that still fails.

You can view your deliverability stats in your Provider dashboard.

Ready to start sending Webhooks? Get started for Free