Octo Events
Octo Events is an application that listens to Github Events via webhooks and expose by an api for later use.
This one was built with Ruby on Rails Framework, version 6.0.3.2 and Ruby version 2.6.5p114.
Get Started
To get it started, there are two main steps. The first is more up to you to set your ngrok host tunel. The second is set properly the application to run.
First of all, let us start by clonning this repository: run in your terminal:
git clone https://github.com/Pauloparakleto/webhookrails.git
If your Operational System is Linux, comment the last gem on Gemfile. If it is a Windows System, uncomment it. Then, run:
bundle
(shortcut for bundle install
)
Let us now leave your cloned Rails application waiting a bit. Let us turn our attention to the external configuration to reach your local host securely.
I. Providing your encrypted local host to be exposed
In oder to receive events from Github and saves them locally on your database, you must read the following docs on ngrok.
(…)
Now you have an encrypted host pointing to your localhost and a token to submit on the creating webhook page.
- On Github, select a repository you want to whatch » Settings » Webhook » click Add webhook button;
- Copy and past to Payload URL field the encrypted response you generated by running on your command line
./ngrok http 3000
(if your rails server listen on port 3000). Note you have both a http and a https for the same host given. Considering your environment as development which doesn’t force https, you must choosehttps//*.io
plus the following to that host inside the field:/webhook
. Your final Payload URL will be ashttps//*.io/webhook
; - The Content type must be
application/json
since we are creating an API only system; - Secret field is where you must past the token given by ngrok. It needs to be present in your ./ngrok token according to ngrok you already read;
- Choose Let me select individual events and select just Issues.
- Press Creat webhook button.
Now this Github repository knows where the host is to send post request.
Your system is not listenning to localhost yet since you have not run rails server
. But wait the following steps to do so.
Note: you can check the official instructions here:
- Webhooks Overview: https://developer.github.com/webhooks/
- Creating Webhooks : https://developer.github.com/webhooks/creating/
II. Configuring your Rails
Rails need to know the hosts it will be listenning in on.
- Go to your
config/enviroment/development.rb
. Change theconfig.hosts = "localhost"
toconfig.hosts = ["localhost", "3xampl3g1v3n.ngrok.io"]
. This is so because Rails need both hosts, the localhost to local get requests to the database. And the encrypted host to receive post request from github. Note “3xampl3g1v3n.ngrok.io” it is just an *example given”. You must past the encrypted host provided by ngrok on your terminal.
Ngrok will provide always a new encrypted host for every time you run ./ngrok http port-number
. So you need to update your webhook on github and provide another “3xampl3g1v3n.ngrok.io” to config.hosts = ["localhost", "another3xampl3g1v3n.ngrok.io"]
- Database settings for postgresql: on
database.yml
, you must have something like this:
default: &default
adapter: postgresql
encoding: unicode
username: postgres
password: yourpassword
host: localhost
After this, run on your terminal:
rails db:create
, then:
rails db:migrate
Now you have two tables, the first one to enumerate issues id; the second one to register events (opened, closed, reopened actions).
The relationship between models issue and event is a has_many belongs_to, in other word, issue has many events, while events belongs just to one issue.
The Events endpoint will expose the persist the events by an api that will filter by issue number
Request examples:
List all issues found without show its relation with events.
GET /issues/
GET /issue/
Both single and plural mode will point to the same index controller.
Response:
200 OK
[{"id":49,"created_at":"2020-08-03T06:07:13.265Z","updated_at":"2020-08-03T06:07:13.265Z"},{"id":1,"created_at":"2020-08-03T19:47:05.717Z","updated_at":"2020-08-03T19:47:05.717Z"},{"id":52,"created_at":"2020-08-03T23:44:10.100Z","updated_at":"2020-08-03T23:44:10.100Z"}]
Show a specific issue (without any events relationship):
GET /issue/1
GET /issues/1
Both single and plural mode will find the show action.
Response:
200 OK
{"id":1,"created_at":"2020-08-03T19:47:05.717Z","updated_at":"2020-08-03T19:47:05.717Z"}
Show all events related to a issue:
GET /issue/1/event
GET /issue/1/events
GET /issues/1/event
GET /issues/1/events
Response:
200 OK
[{"id":1,"issue_id":49,"name":null,"created_at":"2020-08-03T06:07:59.381Z","updated_at":"2020-08-03T06:07:59.381Z"},{"id":7,"issue_id":49,"name":"reopened","created_at":"2020-08-03T06:09:34.872Z","updated_at":"2020-08-03T06:09:34.872Z"},{"id":8,"issue_id":49,"name":"closed","created_at":"2020-08-03T06:10:52.630Z","updated_at":"2020-08-03T06:10:52.630Z"},{"id":9,"issue_id":49,"name":"reopened","created_at":"2020-08-03T06:11:40.990Z","updated_at":"2020-08-03T06:11:40.990Z"},{"id":10,"issue_id":1,"name":"opened","created_at":"2020-08-03T19:49:28.591Z","updated_at":"2020-08-03T19:49:28.591Z"},{"id":11,"issue_id":1,"name":"closed","created_at":"2020-08-03T19:50:43.830Z","updated_at":"2020-08-03T19:50:43.830Z"},{"id":12,"issue_id":52,"name":"opened","created_at":"2020-08-03T23:44:10.465Z","updated_at":"2020-08-03T23:44:10.465Z"},{"id":13,"issue_id":52,"name":"closed","created_at":"2020-08-03T23:51:49.260Z","updated_at":"2020-08-03T23:51:49.260Z"}]
Show a specific event related to a specific issue:
GET /issue/1/event/1
GET /issue/1/events/1
GET /issues/1/event/1
GET /issues/1/events/1
Response:
200 OK
[{"id":7,"issue_id":49,"name":"reopened","created_at":"2020-08-03T06:09:34.872Z","updated_at":"2020-08-03T06:09:34.872Z"}]
Now you are ready to check it out, have fun!