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