customer_fwd.rb

 1# frozen_string_literal: true
 2
 3require "value_semantics/monkey_patched"
 4require "uri"
 5
 6class CustomerFwd
 7	def self.for(uri:, timeout:)
 8		timeout = Timeout.new(timeout)
 9		return None.new(uri: uri, timeout: timeout) if !uri || timeout.zero?
10
11		if uri =~ /\Asip:(.*)@sip.cheogram.com\Z/
12			uri = "xmpp:#{$1.gsub(/%([0-9A-F]{2})/i) { $1.to_i(16).chr }}"
13		end
14		URIS.fetch(uri.split(":", 2).first.to_sym) {
15			raise "Unknown forward URI: #{uri}"
16		}.new(uri: uri, timeout: timeout)
17	end
18
19	class Timeout
20		def self.new(s)
21			s.is_a?(self) ? s : super
22		end
23
24		def initialize(s)
25			@timeout = s.nil? || s.to_i.negative? ? 300 : s.to_i
26		end
27
28		def zero?
29			@timeout.zero?
30		end
31
32		def to_i
33			@timeout
34		end
35	end
36
37	value_semantics do
38		uri Either(String, NilClass)
39		def_attr :timeout, Timeout, coerce: Timeout.method(:new)
40	end
41
42	def with(new_attrs)
43		CustomerFwd.for(to_h.merge(new_attrs))
44	end
45
46	def create_call(account)
47		request = Bandwidth::ApiCreateCallRequest.new.tap { |cc|
48			cc.to = to
49			cc.call_timeout = timeout.to_i
50			yield cc if block_given?
51		}
52		BANDWIDTH_VOICE.create_call(account, body: request).data.call_id
53	end
54
55	def v2_sip?
56		false
57	end
58
59	class Tel < CustomerFwd
60		def to
61			uri.sub(/^tel:/, "")
62		end
63	end
64
65	class SIP < CustomerFwd
66		def v2_sip?
67			uri.end_with?(CONFIG[:sip][:realm])
68		end
69
70		def to
71			uri
72		end
73	end
74
75	class XMPP < CustomerFwd
76		def to
77			jid = uri.sub(/^xmpp:/, "")
78			"sip:#{ERB::Util.url_encode(jid)}@sip.cheogram.com"
79		end
80	end
81
82	class None < CustomerFwd
83		def create_call; end
84
85		def to; end
86	end
87
88	URIS = {
89		tel: Tel,
90		sip: SIP,
91		xmpp: XMPP
92	}.freeze
93end