-
Notifications
You must be signed in to change notification settings - Fork 2
/
github_bot_app.rb
90 lines (72 loc) · 2.59 KB
/
github_bot_app.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
require 'sinatra'
require 'octokit'
require 'dotenv/load'
require 'json'
require 'logger'
require_relative 'github_bot'
require_relative 'github_bot_brain'
require_relative 'alert_manager'
class GithubBotApp < Sinatra::Application
WEBHOOK_SECRET = ENV['GITHUB_WEBHOOK_SECRET']
BRAIN = GithubBotBrain.new
configure :development do
set :logging, Logger::DEBUG
stack = Faraday::RackBuilder.new do |builder|
builder.use Faraday::Request::Retry, exceptions: [Octokit::ServerError]
builder.use Octokit::Middleware::FollowRedirects
builder.use Octokit::Response::RaiseError
builder.use Octokit::Response::FeedParser
builder.response :logger
builder.adapter Faraday.default_adapter
end
Octokit.middleware = stack
end
before '/github' do
get_payload_request(request)
verify_webhook_signature
authenticate_app
authenticate_installation(@payload)
end
post '/github' do
@github_bot.on_event(request.env['HTTP_X_GITHUB_EVENT'], @payload)
200
end
post '/alert-manager' do
get_payload_request(request)
@alert_manager = AlertManager.new
@alert_manager.on_event(@payload)
end
helpers do
# Saves the raw payload and converts the payload to JSON format
def get_payload_request(request)
# request.body is an IO or StringIO object
# Rewind in case someone already read it
request.body.rewind
# The raw text of the body is required for webhook signature verification
@payload_raw = request.body.read
begin
@payload = JSON.parse @payload_raw
rescue => e
fail "Invalid JSON (#{e}): #{@payload_raw}"
end
end
def authenticate_app
@github_bot = GithubBot.new(BRAIN, logger: logger)
end
# Instantiate an Octokit client, authenticated as an installation of a
# GitHub App, to run API operations.
def authenticate_installation(payload)
@github_bot.authenticate_installation(payload['installation']['id'])
end
def verify_webhook_signature
their_signature_header = request.env['HTTP_X_HUB_SIGNATURE'] || 'sha1='
method, their_digest = their_signature_header.split('=')
our_digest = OpenSSL::HMAC.hexdigest(method, WEBHOOK_SECRET, @payload_raw)
halt 401 unless their_digest == our_digest
# The X-GITHUB-EVENT header provides the name of the event.
# The action value indicates the which action triggered the event.
logger.debug "---- received event #{request.env['HTTP_X_GITHUB_EVENT']}"
logger.debug "---- action #{@payload['action']}" unless @payload['action'].nil?
end
end
end