web.rb

 1# frozen_string_literal: true
 2
 3require "roda"
 4require "thin"
 5require "sentry-ruby"
 6
 7require_relative "lib/cdr"
 8require_relative "lib/roda_em_promise"
 9require_relative "lib/rack_fiber"
10
11class Web < Roda
12	use Rack::Fiber # Must go first!
13	use Sentry::Rack::CaptureExceptions
14	plugin :json_parser
15	plugin :render, engine: "slim"
16	plugin RodaEMPromise # Must go last!
17
18	class << self
19		attr_reader :customer_repo, :log
20	end
21
22	def customer_repo
23		Web.customer_repo
24	end
25
26	def log
27		Web.log
28	end
29
30	def params
31		request.params
32	end
33
34	def self.run(log, customer_repo)
35		plugin :common_logger, log, method: :info
36		@log = log
37		@customer_repo = customer_repo
38		Thin::Logging.logger = log
39		Thin::Server.start(
40			"::1",
41			ENV.fetch("PORT", 8080),
42			freeze.app,
43			signals: false
44		)
45	end
46
47	route do |r|
48		r.on "outbound" do
49			r.on "calls" do
50				r.post "status" do
51					loggable = params.dup.tap { |p| p.delete("to") }
52					log.info "#{params['eventType']} #{params['callId']}", loggable
53					if params["eventType"] == "disconnect"
54						CDR.for_disconnect(params).save.catch do |e|
55							log.error("Error raised during /outbound/calls/status", e, loggable)
56							Sentry.capture_exception(e)
57						end
58					end
59					"OK"
60				end
61
62				r.post do
63					customer_id = params["from"].sub(/^\+/, "")
64					customer_repo.find(customer_id).then(:registered?).then do |reg|
65						render :forward, locals: {
66							from: reg.phone,
67							to: params["to"]
68						}
69					end
70				end
71			end
72		end
73	end
74end