fix: bots included in time to response metrics (#6409)

* feat: ignore bots in avg_first_response_time

* feat: ignore bots in avg_first_response count

* feat: add bot handoff event

* feat: add handoff event listener and reporting event

* fix: ignore agent bot in first response

* refactor: calculate first_response with last handoff

* refactor: method defn order

* test: new reporting events

* feat: Revert "feat: ignore bots in avg_first_response count"

This reverts commit de1977c219a2e7a9180dd02272244fe3b3f7ce89.

* feat: Revert "feat: ignore bots in avg_first_response_time"

This reverts commit bb9171945d5e3b2f6015f4f96dd1b76b3efb6987.

* fix: business hour calculation for first_reply

* fix: event_start_time for first_response

* feat: add migration to recompute first_responses

* refactor: separate mute helpers for conversation

* refactor: rename migration

* refactor: migration script

* fix: migration typo

* fix: typo in query

* feat: update schema.rb

* Revert "feat: update schema.rb"

This reverts commit 353ef355f2d956dd219907bb66982dc90ca5d896.

* feat: update schema

* refactor: update events as a batch job

* fix: ignore the event if value is negative

* feat: don't create a new hand-off if it's already present

* refactor: break the action into smaller chunks

* refactor: update reporting listener spec

Handle the case to ensure extra bot handoffs are not created for a give conversation

* fix: import error

---------

Co-authored-by: Vishnu Narayanan <vishnu@chatwoot.com>
This commit is contained in:
Shivam Mishra
2023-02-25 09:48:48 +05:30
committed by GitHub
parent 92d0398744
commit 06ffaa90fc
11 changed files with 200 additions and 28 deletions

View File

@@ -0,0 +1,61 @@
# Delete migration and spec after 2 consecutive releases.
class Migration::UpdateFirstResponseTimeInReportingEventsJob < ApplicationJob
include ReportingEventHelper
queue_as :scheduled_jobs
def perform(account)
account.reporting_events.where(name: 'first_response', user_id: nil).each do |event|
conversation = event.conversation
next if conversation.nil?
update_event_data(event, conversation)
end
end
def update_event_data(event, conversation)
last_bot_reply = conversation.messages.where(sender_type: 'AgentBot').order(created_at: :asc).last
first_human_reply = conversation.messages.where(sender_type: 'User').order(created_at: :asc).first
# accomodate for campaign if required
# new_value = difference between the first_human_reply and the first_bot_reply if it exists or first_human_reply and created at
#
# conversation bot conversation
# start handoff resolved
# | | |
# |____|___|_________|____|_______|_____|________|
# bot reply ^ ^ human reply
# | |
# | |
# last_bot_reply first_human_reply
#
#
# bot handoff happens at the last_bot_reply created time
# the response time is the time between last bot reply created and the first human reply created
return if last_bot_reply.blank? || first_human_reply.blank?
return if last_bot_reply.created_at.to_i >= first_human_reply.created_at.to_i
# this means a bot replied existed, so we need to update the event_start_time
update_event_details(event, last_bot_reply, first_human_reply, conversation.inbox)
end
def update_event_details(event, last_bot_reply, first_human_reply, inbox)
# rubocop:disable Rails/SkipsModelValidations
event.update_columns(event_start_time: last_bot_reply.created_at,
event_end_time: first_human_reply.created_at,
value: calculate_event_value(last_bot_reply, first_human_reply),
value_in_business_hours: calculate_event_value_in_business_hours(inbox, last_bot_reply,
first_human_reply),
user_id: first_human_reply.sender_id)
# rubocop:enable Rails/SkipsModelValidations
end
def calculate_event_value(last_bot_reply, first_human_reply)
first_human_reply.created_at.to_i - last_bot_reply.created_at.to_i
end
def calculate_event_value_in_business_hours(inbox, last_bot_reply, first_human_reply)
business_hours(inbox, last_bot_reply.created_at, first_human_reply.created_at)
end
end