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