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? || s.to_i > 300 ? 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
 36		def to_s
 37			to_i.to_s
 38		end
 39	end
 40
 41	value_semantics do
 42		uri Either(String, NilClass)
 43		def_attr :timeout, Timeout, coerce: Timeout.method(:new)
 44	end
 45
 46	def with(new_attrs)
 47		CustomerFwd.for(to_h.merge(new_attrs))
 48	end
 49
 50	def create_call(account)
 51		request = Bandwidth::ApiCreateCallRequest.new.tap { |cc|
 52			cc.to = to
 53			cc.call_timeout = timeout.to_i
 54			yield cc if block_given?
 55		}
 56		BANDWIDTH_VOICE.create_call(account, body: request).data.call_id
 57	end
 58
 59	def v2_safe?
 60		false
 61	end
 62
 63	class Tel < CustomerFwd
 64		def v2_safe?
 65			true
 66		end
 67
 68		def initialize(values)
 69			super
 70			raise "Bad tel format: #{uri}" unless uri.match?(/\Atel:\+1\d{10}\Z/)
 71		end
 72
 73		def to
 74			uri.sub(/^tel:/, "")
 75		end
 76	end
 77
 78	class SIP < CustomerFwd
 79		def v2_safe?
 80			uri.end_with?(CONFIG[:sip][:realm])
 81		end
 82
 83		def to
 84			uri
 85		end
 86	end
 87
 88	class XMPP < CustomerFwd
 89		def v2_safe?
 90			true
 91		end
 92
 93		def to
 94			jid = uri.sub(/^xmpp:/, "")
 95			"sip:#{ERB::Util.url_encode(jid)}@sip.cheogram.com"
 96		end
 97	end
 98
 99	class None < CustomerFwd
100		def create_call(*); end
101
102		def to; end
103	end
104
105	URIS = {
106		tel: Tel,
107		sip: SIP,
108		xmpp: XMPP
109	}.freeze
110end