- Products
- Solutions Use casesBy industry
- Developers
- Resources Connect
- Pricing
Being able to create and read webhooks is critical, as it ensures that our applications won’t waste time on unnecessary server requests. With Ruby, we can delve into exploring Google webhooks.
On this blog post, we’re going to learn how to create and read Google webhooks using Ruby.
Webhooks are notifications triggered by specific events, such as receiving an email, opening a link within an email, creating or deleting an event, and more. They are crucial because they automatically inform our applications of significant occurrences, eliminating the need for periodic information retrieval at set intervals.
A webhook is initiated by the server and sent to your application without the need for your application to explicitly request it. Instead of making multiple requests, your application can simply wait until it receives a webhook. This not only enhances application efficiency but also accelerates processing speed.
In scenarios such as sending an email or creating an event, it is crucial to determine whether the message was opened, if there was a click within the message, or if an event was modified or deleted. Access to this information is instrumental in making informed decisions.
We can use Google Pub/Sub to sync Gmail messages between Google and Nylas in real time. While not mandatory, this approach is highly recommended.
As we aim to create a Ruby web application, our best choice is Sinatra, one of the most popular micro-frameworks in the Ruby world. We may need to install additional gems.
$ gem install sinatra $ gem install sinatra-contrib $ gem install bundler:2.1.2 #We need this specific version
Once installed, we’re ready to go:
Contrary to common belief, before creating a webhook, it’s essential to have the ability to read it. This may seem counterintuitive, but it is practical. When initiating the creation of a webhook, Nylas verifies the existence of a valid account and the legitimacy of the creation request. Without this verification, anyone could create webhooks indiscriminately.
We’re going to use Ruby to create the google webhooks application and deploy it to Koyeb.
Therefore, the initial step is to create the reading application.
Create a folder named ruby_read_webhooks
, and inside it, create a file named app.rb
:
# frozen_string_literal: true # Load gems require 'nylas' require 'sinatra' require 'sinatra/config_file' webhook = Data.define(:id, :date, :title, :description, :participants, :status) webhooks = [] get '/webhooks' do params['challenge'].to_s if params.include? 'challenge' end post '/webhooks' do # We need to verify that the signature comes from Nylas is_genuine = verify_signature(request.body.read, ENV['CLIENT_SECRET'], request.env['HTTP_X_NYLAS_SIGNATURE']) unless is_genuine status 401 'Signature verification failed!' end # Initialize Nylas client nylas = Nylas::Client.new( api_key: ENV['V3_TOKEN'] ) # Query parameters query_params = { calendar_id: ENV['CALENDAR_ID'] } # We read the webhook information and store it on the data class request.body.rewind model = JSON.parse(request.body.read) event, _request_id = nylas.events.find(identifier: ENV['CALENDAR_ID'], object_id: model['data']['object']['id'], query_params: query_params) participants = '' event[:participants].each do |elem| participants += "#{elem[:email]}; " end hook = webhook.new(event[:id], event[:date], event[:title], event[:description], participants, event[:status]) webhooks.append(hook) status 200 'Webhook received' end get '/' do puts webhooks erb :main, locals: { webhooks: webhooks } end # We generate a signature with our client secret and compare it with the one from Nylas def verify_signature(message, key, signature) digest = OpenSSL::Digest.new('sha256') digest = OpenSSL::HMAC.hexdigest(digest, key, message) secure_compare(digest, signature) end # We compare the keys to see if they are the same def secure_compare(a_key, b_key) return false if a_key.empty? || b_key.empty? || a_key.bytesize != b_key.bytesize l = a_key.unpack "C#{a_key.bytesize}" res = 0 b_key.each_byte { |byte| res |= byte ^ l.shift } res.zero? end
We need a template to display the webhooks. Create a views
folder, and inside it, create a file named main.erb
:
<style> .webhook { padding: 10px; margin: 5px; background-color: #f3f3f3 } .h1 { text-align: center; } </style> <title>Nylas Webhooks</title> <h1 class='h1'>Webhooks</h1> <% webhooks.each do |item| %> <div class='webhook'> <p><b>Id:</b> <%= item.id %> | <b>Date:</b> <%= item.date %> | <b>Title:</b> <%= item.title %> | <b>Description:</b> <%= item.description %> | <b>Participants:</b> <%= item.participants %> | <b>Status:</b> <%= item.status %></p> </div> <% end %>
Everything is prepared, but the application must be deployed to be accessible from the outside.
In the past, Heroku would have been a suitable choice; however, its free tier is no longer available. Therefore, it’s time to explore better alternatives.
One such alternative is Koyeb, which requires a card for verifying a newly created account—this can be either a debit or credit card.
Firstly, we should upload our source code to GitHub, place it in a project named ruby-read-webhooks (or your chosen name), and include two essential files: Gemfile and Procfile.
This is Gemfile:
# frozen_string_literal: true source "https://rubygems.org" ruby "3.2.2" gem 'nylas', '6.0.0.beta.1' gem "sinatra", '3.1.0' gem "sinatra-contrib", "3.1.0" gem "rack", '2.2.8' gem "puma", '6.3.1'
In order to generate a Gemfile.lock file, we need to do the following:
$ bundle _2.1.2_ install
If we’re using a Mac, we need to do this instead:
$ bundle _2.1.2_ lock --add-platform x86_64-linux
And this is the Procfile
:
web: bundle exec ruby app.rb
We will also need a folder called config
, with a file named puma.rb
inside, containing the following code:
workers Integer(ENV['WEB_CONCURRENCY'] || 2) threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5) threads threads_count, threads_count
Your folder structure should look like this:
Now, we need to move on to Koyeb. When we log in, we will be presented with this screen:
Here we need to press Create App + and then choose Github.
We need to select our repository and then simply continue with the next screen:
Let’s choose our builder (how our code is going to be compiled) and the service type, which in this case is going to be a Web Service.
We need to choose the free instance, then select a region that is closer to our geographical location, and then click on Advanced:
We’re going to create some environment variables. Port comes by default, so we need to add the rest:
CLIENT_SECRET should be left empty (or set to another value) for now, as we will update it later.Once we’re finished, we should press Deploy. Koyeb will start deploying our application, and this might take a couple of minutes.
Our application will be deployed, and we should be able to access it once it’s ready.
After launching the application, grab the URL and open it in a web browser. It will be empty, as we have yet to define any webhooks.
Now that our Read Webhooks application is up and running, it’s time to create the Webhooks application.
Create a new file and name it Webhooks_V3.rb:
# frozen_string_literal: true # Load gems require 'dotenv/load' require 'nylas' # Initialize Nylas client nylas = Nylas::Client.new( api_key: ENV['V3_TOKEN'] ) # Identifier # Request Body request_body = { trigger_types: [Nylas::WebhookTrigger::EVENT_CREATED], webhook_url: '<YOUR_WEBHOOK_URL>/webhook', description: 'My first webhook', notification_email_address: ENV['GRANT_ID'] } webhooks, = nylas.webhooks.create(request_body: request_body) puts webhooks
In the terminal window, enter this command:
$ ruby Webhooks_V3.rb
Copy the value of the webhook_secret variable, as we need it to update our webhook service.
With the webhook_secret
value, update the CLIENT_SECRET
environment variable. The deployment step will be launched automatically.
Each time a new event is created, our application will be able to display it.
Utilizing Ruby, Sinatra and Koyeb and Bruno to create and read Google webhooks was a great experience.
Do you have any comments or feedback? Please use our forums 😎
Here’s the repo for Read Ruby Webhooks and Create Ruby Webhooks.
Don’t miss the action, join our LiveStream Coding with Nylas!
Blag aka Alvaro Tejada Galindo is a Senior Developer Advocate at Nylas. He loves learning about programming and sharing knowledge with the community. When he’s not coding, he’s spending time with his wife, daughter and son. He loves Punk Music and reading all sorts of books.