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