bandwidth_tn_options.rb

  1# frozen_string_literal: true
  2
  3require "em_promise"
  4require "ruby-bandwidth-iris"
  5Faraday.default_adapter = :em_synchrony
  6
  7class BandwidthTNOptions
  8	def self.tn_eligible_for_port_out_pin?(creds)
  9		user_id, token, secret, tel = creds
 10		tel_local = tel.sub(/^\+1/, '')
 11		client = BandwidthIris::Client.new(
 12			account_id: user_id,
 13			username: token,
 14			password: secret
 15		)
 16		EMPromise.resolve(nil).then do
 17			begin
 18				tn = BandwidthIris::Tn.get(client, tel_local)
 19			rescue BandwidthIris::Errors::GenericError => e
 20				raise e unless e.http_status == 404
 21
 22				next false
 23			end
 24			details = tn.get_details()
 25			details[:tier] == 0.0 && details[:on_net_vendor] == true
 26		end
 27	end
 28
 29	def self.set_port_out_pin(creds, pin)
 30		tn_eligible_for_port_out_pin?(creds).then do |eligible|
 31			unless eligible
 32				raise "TN not eligible for port-out PIN"
 33			end
 34
 35			user_id, token, secret, tel = creds
 36			tel_local = tel.sub(/^\+1/, '')
 37
 38			client = BandwidthIris::Client.new(
 39				account_id: user_id,
 40				username: token,
 41				password: secret
 42			)
 43
 44
 45			data = {
 46				tn_option_groups: {
 47					tn_option_group: [
 48						{
 49							port_out_passcode: pin,
 50							telephone_numbers: {
 51								telephone_number: [tel]
 52							}
 53						}
 54					]
 55				}
 56			}
 57
 58			order = BandwidthIris::TnOptions.create_tn_option_order(client, data)
 59			order_id = order[:order_id]
 60
 61			unless order_id
 62				raise "Missing OrderId in create response"
 63			end
 64
 65			poll_order(order_id, client)
 66		end
 67	end
 68
 69	def self.poll_order(order_id, client, attempt=1, max_attempts=30)
 70		if attempt > max_attempts
 71			return EMPromise.reject(RuntimeError.new(
 72				"TnOptions polling timeout after #{max_attempts} attempts"
 73			))
 74		end
 75
 76		EMPromise.resolve(nil).then do
 77			order = BandwidthIris::TnOptions.get_tn_option_order(client, order_id)
 78
 79			error_list = order[:error_list]
 80			if error_list&.any?
 81				errors = [error_list].flatten
 82				msgs = errors.map { |e| e.to_s }.reject(&:empty?).join('; ')
 83				raise "Dashboard tnOptions errors: #{msgs}"
 84			end
 85
 86			warnings = order[:warnings]
 87			if warnings&.any?
 88				warns = [warnings].flatten
 89				descs = warns.map { |w| w.to_s }.reject(&:empty?).join('; ')
 90				raise "Dashboard tnOptions warnings: #{descs}"
 91			end
 92
 93			status = order[:order_status] || order[:processing_status]
 94
 95			case status&.to_s&.upcase
 96			when 'COMPLETE', 'PARTIAL'
 97				true
 98			when 'FAILED'
 99				raise "TnOptions order failed with status: #{status}"
100			when 'RECEIVED', 'PROCESSING'
101				EMPromise.new { |resolve, reject|
102					EM.add_timer(2) do
103						poll_order(order_id, client, attempt + 1, max_attempts)
104							.then { |result| resolve.call(result) }
105							.catch { |error| reject.call(error) }
106					end
107				}
108			else
109				raise "Unexpected poll status: #{status.inspect}"
110			end
111		end
112	end
113end