Adds an account-level setting `keep_pending_on_bot_failure` to control whether conversations should move from pending to open when agent bot webhooks fail. Some users experience occasional message drops and don't want conversations to automatically reopen due to transient bot failures. This setting gives accounts control over that behavior. This is a temporary setting which will be removed in future once a proper fix for it is done, so it is not added in the UI.
89 lines
2.1 KiB
Ruby
89 lines
2.1 KiB
Ruby
class Webhooks::Trigger
|
|
SUPPORTED_ERROR_HANDLE_EVENTS = %w[message_created message_updated].freeze
|
|
|
|
def initialize(url, payload, webhook_type)
|
|
@url = url
|
|
@payload = payload
|
|
@webhook_type = webhook_type
|
|
end
|
|
|
|
def self.execute(url, payload, webhook_type)
|
|
new(url, payload, webhook_type).execute
|
|
end
|
|
|
|
def execute
|
|
perform_request
|
|
rescue StandardError => e
|
|
handle_error(e)
|
|
Rails.logger.warn "Exception: Invalid webhook URL #{@url} : #{e.message}"
|
|
end
|
|
|
|
private
|
|
|
|
def perform_request
|
|
RestClient::Request.execute(
|
|
method: :post,
|
|
url: @url,
|
|
payload: @payload.to_json,
|
|
headers: { content_type: :json, accept: :json },
|
|
timeout: webhook_timeout
|
|
)
|
|
end
|
|
|
|
def handle_error(error)
|
|
return unless SUPPORTED_ERROR_HANDLE_EVENTS.include?(@payload[:event])
|
|
return unless message
|
|
|
|
case @webhook_type
|
|
when :agent_bot_webhook
|
|
update_conversation_status(message)
|
|
when :api_inbox_webhook
|
|
update_message_status(error)
|
|
end
|
|
end
|
|
|
|
def update_conversation_status(message)
|
|
conversation = message.conversation
|
|
return unless conversation&.pending?
|
|
return if conversation&.account&.keep_pending_on_bot_failure
|
|
|
|
conversation.open!
|
|
create_agent_bot_error_activity(conversation)
|
|
end
|
|
|
|
def create_agent_bot_error_activity(conversation)
|
|
content = I18n.t('conversations.activity.agent_bot.error_moved_to_open')
|
|
Conversations::ActivityMessageJob.perform_later(conversation, activity_message_params(conversation, content))
|
|
end
|
|
|
|
def activity_message_params(conversation, content)
|
|
{
|
|
account_id: conversation.account_id,
|
|
inbox_id: conversation.inbox_id,
|
|
message_type: :activity,
|
|
content: content
|
|
}
|
|
end
|
|
|
|
def update_message_status(error)
|
|
Messages::StatusUpdateService.new(message, 'failed', error.message).perform
|
|
end
|
|
|
|
def message
|
|
return if message_id.blank?
|
|
|
|
@message ||= Message.find_by(id: message_id)
|
|
end
|
|
|
|
def message_id
|
|
@payload[:id]
|
|
end
|
|
|
|
def webhook_timeout
|
|
raw_timeout = GlobalConfig.get_value('WEBHOOK_TIMEOUT')
|
|
timeout = raw_timeout.presence&.to_i
|
|
|
|
timeout&.positive? ? timeout : 5
|
|
end
|
|
end
|