bandwidth_tn_options.rb

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