A forms/lnp.rb => forms/lnp.rb +83 -0
@@ 0,0 1,83 @@
+form!
+title "Bring your own number to JMP"
+instructions <<~I
+ To confirm, you'd like to transfer in a number to your JMP account (your current JMP number will be replaced by the number you are transferring in).
+
+ Once you've submitted the details for the number you'd like to bring to JMP, we will begin the transfer process. This normally takes 1-2 weeks during which both your existing number and your current JMP number will continue to work as they do now.
+
+ Within a day or two of submitting this form, we will know which date the transfer will take place, and we will message your current JMP number with this information. Note that there is normally a period of 15-45 minutes at the time of transfer where incoming calls and messages will not be delivered to the number you are transferring in. After that time, all calls and messages will be handled by your JMP account, and your current JMP number will no longer receive calls or messages.
+
+ If this all seems fine to you, then please enter the information for the number you'd like to transfer into JMP:
+I
+
+field(
+ var: "BillingTelephoneNumber",
+ required: true,
+ type: "text-single",
+ label: "Phone number"
+)
+
+field(
+ var: "Subscriber[FirstName]",
+ required: true,
+ type: "text-single",
+ label: "Billing first name"
+)
+
+field(
+ var: "Subscriber[LastName]",
+ required: true,
+ type: "text-single",
+ label: "Billing last name"
+)
+
+field(
+ var: "Subscriber[ServiceAddress][HouseNumber]",
+ required: true,
+ type: "text-single",
+ label: "Billing street number"
+)
+
+field(
+ var: "Subscriber[ServiceAddress][StreetName]",
+ required: true,
+ type: "text-single",
+ label: "Billing street name"
+)
+
+field(
+ var: "Subscriber[ServiceAddress][City]",
+ required: true,
+ type: "text-single",
+ label: "Billing city"
+)
+
+field(
+ var: "Subscriber[ServiceAddress][StateCode]",
+ required: true,
+ type: "text-single",
+ label: "Billing state or province"
+)
+
+field(
+ var: "Subscriber[ServiceAddress][Zip]",
+ required: true,
+ type: "text-single",
+ label: "Billing zip or postal code"
+)
+
+field(
+ var: "WirelessInfo[AccountNumber]",
+ required: false,
+ type: "text-single",
+ label: "Account number",
+ description: "required unless carrier is VoIP"
+)
+
+field(
+ var: "WirelessInfo[PinNumber]",
+ required: false,
+ type: "text-single",
+ label: "Account PIN",
+ description: "required unless your carrier has none"
+)
A lib/form_to_h.rb => lib/form_to_h.rb +21 -0
@@ 0,0 1,21 @@
+# frozen_string_literal: true
+
+require "blather"
+require "rack"
+
+module FormToH
+ refine Blather::Stanza::X do
+ def to_h
+ params = Rack::Utils.default_query_parser.make_params
+ fields.each do |field|
+ Rack::Utils.default_query_parser.normalize_params(
+ params,
+ field.var,
+ field.value,
+ 32
+ )
+ end
+ params.to_h
+ end
+ end
+end
A lib/port_in_order.rb => lib/port_in_order.rb +29 -0
@@ 0,0 1,29 @@
+# frozen_string_literal: true
+
+class PortInOrder
+ def initialize(params)
+ @params = params
+ @params["SiteId"] = CONFIG[:bandwidth_site]
+ @params["PeerId"] = CONFIG[:bandwidth_peer]
+ @params["ProcessingStatus"] = "DRAFT"
+ @params["Subscriber"]["SubscriberType"] ||= "RESIDENTIAL"
+ end
+
+ def loa_authorizing_person
+ "%s %s" % [
+ @params.dig("Subscriber", "FirstName"),
+ @params.dig("Subscriber", "LastName")
+ ]
+ end
+
+ def to_h
+ @params.dup.tap do |h|
+ h["LoaAuthorizingPerson"] = loa_authorizing_person
+ h["BillingTelephoneNumber"].gsub!(/[^\d]/, "")
+ h["BillingTelephoneNumber"].gsub!(/\A1(\d{10})\Z/) { $1 }
+ h["ListOfPhoneNumbers"] = {
+ "PhoneNumber" => params["BillingTelephoneNumber"]
+ }
+ end
+ end
+end
M sgx_jmp.rb => sgx_jmp.rb +65 -30
@@ 79,7 79,9 @@ require_relative "lib/customer_repo"
require_relative "lib/electrum"
require_relative "lib/expiring_lock"
require_relative "lib/em"
+require_relative "lib/form_to_h"
require_relative "lib/low_balance"
+require_relative "lib/port_in_order"
require_relative "lib/payment_methods"
require_relative "lib/paypal_done"
require_relative "lib/registration"
@@ 537,36 539,6 @@ Command.new(
end
}.register(self).then(&CommandList.method(:register))
-command :execute?, node: "web-register" do |iq|
- StatsD.increment("command", tags: ["node:#{iq.node}"])
-
- sentry_hub = new_sentry_hub(iq, name: iq.node)
-
- begin
- jid = iq.form.field("jid")&.value.to_s.strip
- tel = iq.form.field("tel")&.value.to_s.strip
- sentry_hub.current_scope.set_user(jid: jid, tel: tel)
- if iq.from.stripped != CONFIG[:web_register][:from]
- BLATHER << iq.as_error("forbidden", :auth)
- elsif jid == "" || tel !~ /\A\+\d+\Z/
- reply_with_note(iq, "Invalid JID or telephone number.", type: :error)
- else
- IQ_MANAGER.write(Blather::Stanza::Iq::Command.new.tap { |cmd|
- cmd.to = CONFIG[:web_register][:to]
- cmd.node = "push-register"
- cmd.form.fields = [var: "to", value: jid]
- cmd.form.type = "submit"
- }).then { |result|
- TEL_SELECTIONS.set(result.form.field("from")&.value.to_s.strip, tel)
- }.then {
- BLATHER << iq.reply.tap { |reply| reply.status = :completed }
- }.catch { |e| panic(e, sentry_hub) }
- end
- rescue StandardError => e
- sentry_hub.capture_exception(e)
- end
-end
-
Command.new(
"info",
"Show Account Info",
@@ 637,6 609,69 @@ Command.new(
end
}.register(self).then(&CommandList.method(:register))
+Command.new(
+ "lnp",
+ "Port in your number from another carrier",
+ list_for: ->(**) { true }
+) {
+ using FormToH
+
+ EMPromise.all([
+ Command.customer,
+ Command.reply do |reply|
+ reply.allowed_actions = [:next]
+ reply.command << FormTemplate.render("lnp")
+ end
+ ]).then do |(customer, iq)|
+ order = PortInOrder.new(iq.form.to_h.slice(
+ "BillingTelephoneNumber", "Subscriber", "WirelessInfo"
+ ).merge("CustomerOrderId" => customer.customer_id))
+ order_id = BandwidthIris::PortIn.create(order.to_h)[:order_id]
+ url = "https://dashboard.bandwidth.com/portal/r/a/" \
+ "#{CONFIG[:creds][:account]}/orders/portIn/#{order_id}"
+ BLATHER.join(CONFIG[:notify_admin], "sgx-jmp")
+ BLATHER.say(
+ CONFIG[:notify_admin],
+ "New port-in request for #{customer.customer_id}: #{url}",
+ :groupchat
+ )
+ Command.finish(
+ "Your port-in request has been accepted, " \
+ "support will contact you with next steps"
+ )
+ end
+}.register(self).then(&CommandList.method(:register))
+
+command :execute?, node: "web-register" do |iq|
+ StatsD.increment("command", tags: ["node:#{iq.node}"])
+
+ sentry_hub = new_sentry_hub(iq, name: iq.node)
+
+ begin
+ jid = iq.form.field("jid")&.value.to_s.strip
+ tel = iq.form.field("tel")&.value.to_s.strip
+ sentry_hub.current_scope.set_user(jid: jid, tel: tel)
+ if iq.from.stripped != CONFIG[:web_register][:from]
+ BLATHER << iq.as_error("forbidden", :auth)
+ elsif jid == "" || tel !~ /\A\+\d+\Z/
+ reply_with_note(iq, "Invalid JID or telephone number.", type: :error)
+ else
+ IQ_MANAGER.write(Blather::Stanza::Iq::Command.new.tap { |cmd|
+ cmd.to = CONFIG[:web_register][:to]
+ cmd.node = "push-register"
+ cmd.form.fields = [var: "to", value: jid]
+ cmd.form.type = "submit"
+ }).then { |result|
+ TEL_SELECTIONS.set(result.form.field("from")&.value.to_s.strip, tel)
+ }.then {
+ BLATHER << iq.reply.tap { |reply| reply.status = :completed }
+ }.catch { |e| panic(e, sentry_hub) }
+ end
+ rescue StandardError => e
+ sentry_hub.capture_exception(e)
+ end
+end
+
command sessionid: /./ do |iq|
COMMAND_MANAGER.fulfill(iq)
end