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