class Twilio::DeliveryStatusService pattr_initialize [:params!] # Reference: https://www.twilio.com/docs/messaging/api/message-resource#message-status-values def perform return if twilio_channel.blank? return unless supported_status? process_statuses if message.present? end private def process_statuses @message.status = status @message.external_error = external_error if error_occurred? @message.save! end def supported_status? %w[sent delivered read failed undelivered].include?(params[:MessageStatus]) end def status params[:MessageStatus] == 'undelivered' ? 'failed' : params[:MessageStatus] end def external_error return nil unless error_occurred? error_message = params[:ErrorMessage].presence error_code = params[:ErrorCode] if error_message.present? "#{error_code} - #{error_message}" elsif error_code.present? I18n.t('conversations.messages.delivery_status.error_code', error_code: error_code) end end def error_occurred? params[:ErrorCode].present? && %w[failed undelivered].include?(params[:MessageStatus]) end def twilio_channel @twilio_channel ||= if params[:MessagingServiceSid].present? ::Channel::TwilioSms.find_by(messaging_service_sid: params[:MessagingServiceSid]) elsif params[:AccountSid].present? && params[:From].present? ::Channel::TwilioSms.find_by(account_sid: params[:AccountSid], phone_number: params[:From]) end log_channel_not_found if @twilio_channel.blank? @twilio_channel end def message return unless params[:MessageSid] @message ||= twilio_channel.inbox.messages.find_by(source_id: params[:MessageSid]) end def log_channel_not_found Rails.logger.warn( '[TWILIO] Delivery status channel lookup failed ' \ "account_sid=#{params[:AccountSid]} " \ "from=#{params[:From]} " \ "messaging_service_sid=#{params[:MessagingServiceSid]} " \ "message_sid=#{params[:MessageSid]}" ) end end