mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 03:57:52 +00:00

# Changelog When an agent bot webhook fails, we now flip any pending conversation back to an open state so a human agent can pick it up immediately. There will be an clear activity message giving the team clear visibility into what went wrong. This keeps customers from getting stuck in limbo when their connected bot goes offline. # Testing instructions 1. Initial setup: Create an agent bot with a working webhook URL and connect it to a test inbox. Send a message from a contact (e.g., via the widget) so a conversation is created; it should enter the Pending state while the bot handles the reply. 2. Introduce failure: Edit that agent bot and swap the webhook URL for a dummy endpoint that will fail. Have the same contact send another message in the existing conversation. Because the webhook call now fails, the conversation should flip from Pending back to Open, making it visible to agents. Also verify the activity message 3. New conversation check: With the dummy URL still in place, start a brand-new conversation from a contact. When the bot tries (and fails) to respond, confirm that the conversation appears immediately as Open rather than remaining Pending. Also the activity message is visible 4. Subsequent messages in open conversations will show no change --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
77 lines
1.8 KiB
Ruby
77 lines
1.8 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: 5
|
|
)
|
|
end
|
|
|
|
def handle_error(error)
|
|
return unless SUPPORTED_ERROR_HANDLE_EVENTS.include?(@payload[:event])
|
|
return unless message
|
|
|
|
case @webhook_type
|
|
when :agent_bot_webhook
|
|
conversation = message.conversation
|
|
return unless conversation&.pending?
|
|
|
|
conversation.open!
|
|
create_agent_bot_error_activity(conversation)
|
|
when :api_inbox_webhook
|
|
update_message_status(error)
|
|
end
|
|
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
|
|
end
|