Class: ContactPointLineTypeLookupHandler
- Inherits:
-
ApplicationJob
- Object
- ActiveJob::Base
- ApplicationJob
- ContactPointLineTypeLookupHandler
- Includes:
- RailsEventStore::AsyncHandler
- Defined in:
- app/subscribers/contact_point_line_type_lookup_handler.rb
Overview
Hits Twilio Lookup v2 line-type intelligence on phone-change events and
updates contact_points.sms_status from the carrier-reported line type.
Logic Details
Why this is decoupled from contact_point.category: the user's category
choice (PHONE/CELL/FAX) is intent, not ground truth. A phone field
filled in via the customer creation flow is just as likely to be a mobile
as a landline, and a CELL category is just a guess until Twilio confirms.
Category stays as user intent; sms_status is the single SMS-routing
source of truth, with sms_status_source recording why it's set the way
it is.
Skips numbers verified within RECENT_VERIFICATION_WINDOW so a flurry of
detail edits on the same record (or post-merge contact-point churn) doesn't
burn lookups. Also skips PBX seats (extension present) — SMS to a
specific extension is never possible.
Constant Summary collapse
- RECENT_VERIFICATION_WINDOW =
Window during which a previously-verified record is left alone.
90.days
- SMS_CAPABLE_LINE_TYPES =
Twilio v2 line types that map to
sms_enabled. %i[mobile fixed_voip non_fixed_voip personal toll_free uan].freeze
- SMS_INCAPABLE_LINE_TYPES =
Twilio v2 line types that map to
sms_none. %i[landline voicemail pager].freeze
Instance Method Summary collapse
-
#perform(event) ⇒ void
Looks up the contact point's line type via Twilio and stamps the result.
Instance Method Details
#perform(event) ⇒ void
This method returns an undefined value.
Looks up the contact point's line type via Twilio and stamps the result.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'app/subscribers/contact_point_line_type_lookup_handler.rb', line 47 def perform(event) cp = ContactPoint.find_by(id: event.data[:contact_point_id]) return unless cp&.callable? && cp.detail.present? return if cp.extension.present? # PBX seat — never SMS-able to the extension itself return if recently_verified?(cp) line_type = TwilioClient.lookup_line_type(cp.detail) new_status = decide_sms_status(line_type, cp.sms_status) return if new_status.nil? # :unknown / unmapped — leave status alone, no breadcrumb either cp.update!( sms_status: new_status, sms_status_source: 'twilio_lookup', sms_status_verified_at: Time.current ) end |