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