customer_fwd.rb

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