feat: API Endpoints to update message status (#11387)
- Added an api endpoint for update message status ( available only for api inboxes ) - Moved message status management to a service. - Handles case where read status arrive before delivered fixes: #10314 , #9962
This commit is contained in:
@@ -16,7 +16,7 @@ class Facebook::SendOnFacebookService < Base::SendOnChannelService
|
||||
rescue Facebook::Messenger::FacebookError => e
|
||||
# TODO : handle specific errors or else page will get disconnected
|
||||
handle_facebook_error(e)
|
||||
message.update!(status: :failed, external_error: e.message)
|
||||
Messages::StatusUpdateService.new(message, 'failed', e.message).perform
|
||||
end
|
||||
|
||||
def send_message_to_facebook(delivery_params)
|
||||
@@ -24,7 +24,7 @@ class Facebook::SendOnFacebookService < Base::SendOnChannelService
|
||||
return if parsed_result.nil?
|
||||
|
||||
if parsed_result['error'].present?
|
||||
message.update!(status: :failed, external_error: external_error(parsed_result))
|
||||
Messages::StatusUpdateService.new(message, 'failed', external_error(parsed_result)).perform
|
||||
Rails.logger.info "Facebook::SendOnFacebookService: Error sending message to Facebook : Page - #{channel.page_id} : #{parsed_result}"
|
||||
end
|
||||
|
||||
@@ -35,11 +35,11 @@ class Facebook::SendOnFacebookService < Base::SendOnChannelService
|
||||
result = Facebook::Messenger::Bot.deliver(delivery_params, page_id: channel.page_id)
|
||||
JSON.parse(result)
|
||||
rescue JSON::ParserError
|
||||
message.update!(status: :failed, external_error: 'Facebook was unable to process this request')
|
||||
Messages::StatusUpdateService.new(message, 'failed', 'Facebook was unable to process this request').perform
|
||||
Rails.logger.error "Facebook::SendOnFacebookService: Error parsing JSON response from Facebook : Page - #{channel.page_id} : #{result}"
|
||||
nil
|
||||
rescue Net::OpenTimeout
|
||||
message.update!(status: :failed, external_error: 'Request timed out, please try again later')
|
||||
Messages::StatusUpdateService.new(message, 'failed', 'Request timed out, please try again later').perform
|
||||
Rails.logger.error "Facebook::SendOnFacebookService: Timeout error sending message to Facebook : Page - #{channel.page_id}"
|
||||
nil
|
||||
end
|
||||
|
||||
@@ -61,7 +61,7 @@ class Instagram::BaseSendService < Base::SendOnChannelService
|
||||
else
|
||||
external_error = external_error(parsed_response)
|
||||
Rails.logger.error("Instagram response: #{external_error} : #{message_content}")
|
||||
message.update!(status: :failed, external_error: external_error)
|
||||
Messages::StatusUpdateService.new(message, 'failed', external_error).perform
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,10 +14,10 @@ class Line::SendOnLineService < Base::SendOnChannelService
|
||||
|
||||
if response.code == '200'
|
||||
# If the request is successful, update the message status to delivered
|
||||
message.update!(status: :delivered)
|
||||
Messages::StatusUpdateService.new(message, 'delivered').perform
|
||||
else
|
||||
# If the request is not successful, update the message status to failed and save the external error
|
||||
message.update!(status: :failed, external_error: external_error(parsed_json))
|
||||
Messages::StatusUpdateService.new(message, 'failed', external_error(parsed_json)).perform
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
34
app/services/messages/status_update_service.rb
Normal file
34
app/services/messages/status_update_service.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
class Messages::StatusUpdateService
|
||||
attr_reader :message, :status, :external_error
|
||||
|
||||
def initialize(message, status, external_error = nil)
|
||||
@message = message
|
||||
@status = status
|
||||
@external_error = external_error
|
||||
end
|
||||
|
||||
def perform
|
||||
return false unless valid_status_transition?
|
||||
|
||||
update_message_status
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_message_status
|
||||
# Update status and set external_error only when failed
|
||||
message.update!(
|
||||
status: status,
|
||||
external_error: (status == 'failed' ? external_error : nil)
|
||||
)
|
||||
end
|
||||
|
||||
def valid_status_transition?
|
||||
return false unless Message.statuses.key?(status)
|
||||
|
||||
# Don't allow changing from 'read' to 'delivered'
|
||||
return false if message.read? && status == 'delivered'
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
@@ -9,7 +9,7 @@ class Twilio::SendOnTwilioService < Base::SendOnChannelService
|
||||
begin
|
||||
twilio_message = channel.send_message(**message_params)
|
||||
rescue Twilio::REST::TwilioError, Twilio::REST::RestError => e
|
||||
message.update!(status: :failed, external_error: e.message)
|
||||
Messages::StatusUpdateService.new(message, 'failed', e.message).perform
|
||||
end
|
||||
message.update!(source_id: twilio_message.sid) if twilio_message
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user