Class: SmsRecipientDemoteHandler
- Inherits:
-
ApplicationJob
- Object
- ActiveJob::Base
- ApplicationJob
- SmsRecipientDemoteHandler
- Includes:
- RailsEventStore::AsyncHandler
- Defined in:
- app/subscribers/sms_recipient_demote_handler.rb
Overview
Demotes a recipient's contact_point sms_status to sms_none when Twilio's
ErrorCode definitively classifies the recipient as not-SMS-capable
(landline, invalid mobile).
Logic Details
Only the recipient-side error allowlist below triggers a demote. Codes
meaning "our sender is unverified / unregistered / region-blocked" (e.g.
30032 Toll-Free Not Verified — the actual cause of the David Grégoire
case on 2026-05-06) are sender-side and have nothing to do with whether the
recipient can receive; demoting on those would silently disable conversations
every time the WY toll-free hit a new region. See
SmsSenderUnverifiedAlertHandler for the sender-side branch.
Iterates ALL matching contact points, not just sms_enabled ones, so a row
already at sms_none (default state, no Twilio confirmation) still gets its
sms_status_source upgraded to twilio_failure_<code> and stamped with a
sms_status_verified_at. Distinguishes "speculatively unverified" from
"carrier-confirmed not SMS-capable."
Constant Summary collapse
- RECIPIENT_NOT_SMS_CODES =
Definitive recipient-side codes — one occurrence is enough to demote.
30006— Landline or unreachable carrier21614—'To'number is not a valid mobile number
%w[30006 21614].freeze
Instance Method Summary collapse
-
#perform(event) ⇒ void
Stamps the failure verdict onto every contact point whose
detailmatches the failed recipient.
Instance Method Details
#perform(event) ⇒ void
This method returns an undefined value.
Stamps the failure verdict onto every contact point whose detail matches
the failed recipient.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'app/subscribers/sms_recipient_demote_handler.rb', line 46 def perform(event) code = event.data[:error_code].to_s return unless RECIPIENT_NOT_SMS_CODES.include?(code) recipient = event.data[:recipient] return if recipient.blank? ContactPoint.dialable.where(detail: recipient).find_each do |cp| cp.update!( sms_status: :sms_none, sms_status_source: "twilio_failure_#{code}", sms_status_verified_at: Time.current ) end end |