feat: include additional information

This commit is contained in:
Shivam Mishra
2026-01-21 17:55:38 +05:30
parent 92449e273c
commit 6325bd667a
2 changed files with 70 additions and 49 deletions
+38 -48
View File
@@ -7,12 +7,9 @@ class ReportingEventListener < BaseListener
ReportingEvent.create!(
name: 'conversation_created',
value: 0,
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
user_id: conversation.assignee_id,
conversation_id: conversation.id,
event_start_time: conversation.created_at,
event_end_time: conversation.created_at
event_end_time: conversation.created_at,
**base_event_attributes(conversation, from_state: nil)
)
end
@@ -23,14 +20,10 @@ class ReportingEventListener < BaseListener
reporting_event = ReportingEvent.new(
name: 'conversation_resolved',
value: time_to_resolve,
value_in_business_hours: business_hours(conversation.inbox, conversation.created_at,
conversation.updated_at),
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
user_id: conversation.assignee_id,
conversation_id: conversation.id,
value_in_business_hours: business_hours(conversation.inbox, conversation.created_at, conversation.updated_at),
event_start_time: conversation.created_at,
event_end_time: conversation.updated_at
event_end_time: conversation.updated_at,
**base_event_attributes(conversation, from_state: 'handling')
)
create_bot_resolved_event(conversation, reporting_event)
@@ -42,20 +35,14 @@ class ReportingEventListener < BaseListener
conversation = message.conversation
first_response_time = message.created_at.to_i - last_non_human_activity(conversation).to_i
reporting_event = ReportingEvent.new(
ReportingEvent.create!(
name: 'first_response',
value: first_response_time,
value_in_business_hours: business_hours(conversation.inbox, last_non_human_activity(conversation),
message.created_at),
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
user_id: message.sender_id,
conversation_id: conversation.id,
value_in_business_hours: business_hours(conversation.inbox, last_non_human_activity(conversation), message.created_at),
event_start_time: last_non_human_activity(conversation),
event_end_time: message.created_at
event_end_time: message.created_at,
**base_event_attributes(conversation, from_state: 'waiting', user_id: message.sender_id)
)
reporting_event.save!
end
def reply_created(event)
@@ -65,21 +52,16 @@ class ReportingEventListener < BaseListener
return if waiting_since.blank?
# When waiting_since is nil, set reply_time to 0
reply_time = message.created_at.to_i - waiting_since.to_i
reporting_event = ReportingEvent.new(
ReportingEvent.create!(
name: 'reply_time',
value: reply_time,
value_in_business_hours: business_hours(conversation.inbox, waiting_since, message.created_at),
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
user_id: conversation.assignee_id,
conversation_id: conversation.id,
event_start_time: waiting_since,
event_end_time: message.created_at
event_end_time: message.created_at,
**base_event_attributes(conversation, from_state: 'waiting')
)
reporting_event.save!
end
def conversation_bot_handoff(event)
@@ -91,18 +73,14 @@ class ReportingEventListener < BaseListener
time_to_handoff = conversation.updated_at.to_i - conversation.created_at.to_i
reporting_event = ReportingEvent.new(
ReportingEvent.create!(
name: 'conversation_bot_handoff',
value: time_to_handoff,
value_in_business_hours: business_hours(conversation.inbox, conversation.created_at, conversation.updated_at),
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
user_id: conversation.assignee_id,
conversation_id: conversation.id,
event_start_time: conversation.created_at,
event_end_time: conversation.updated_at
event_end_time: conversation.updated_at,
**base_event_attributes(conversation, from_state: 'bot_handling')
)
reporting_event.save!
end
def conversation_opened(event)
@@ -114,36 +92,47 @@ class ReportingEventListener < BaseListener
name: 'conversation_resolved'
).order(event_end_time: :desc).first
# For first-time openings, value is 0
# For reopenings, calculate time since resolution
# For first-time openings, value is 0, from_state is nil
# For reopenings, calculate time since resolution, from_state is 'resolved'
if last_resolved_event
time_since_resolved = conversation.updated_at.to_i - last_resolved_event.event_end_time.to_i
business_hours_value = business_hours(conversation.inbox, last_resolved_event.event_end_time, conversation.updated_at)
start_time = last_resolved_event.event_end_time
from_state = 'resolved'
else
time_since_resolved = 0
business_hours_value = 0
start_time = conversation.created_at
from_state = nil
end
create_conversation_opened_event(conversation, time_since_resolved, business_hours_value, start_time)
create_conversation_opened_event(conversation, time_since_resolved, business_hours_value, start_time, from_state)
end
private
def create_conversation_opened_event(conversation, time_since_resolved, business_hours_value, start_time)
reporting_event = ReportingEvent.new(
def base_event_attributes(conversation, from_state:, user_id: nil)
{
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
user_id: user_id || conversation.assignee_id,
conversation_id: conversation.id,
conversation_created_at: conversation.created_at,
team_id: conversation.team_id,
channel_type: conversation.inbox.channel_type,
from_state: from_state
}
end
def create_conversation_opened_event(conversation, time_since_resolved, business_hours_value, start_time, from_state)
ReportingEvent.create!(
name: 'conversation_opened',
value: time_since_resolved,
value_in_business_hours: business_hours_value,
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
user_id: conversation.assignee_id,
conversation_id: conversation.id,
event_start_time: start_time,
event_end_time: conversation.updated_at
event_end_time: conversation.updated_at,
**base_event_attributes(conversation, from_state: from_state)
)
reporting_event.save!
end
def create_bot_resolved_event(conversation, reporting_event)
@@ -153,6 +142,7 @@ class ReportingEventListener < BaseListener
bot_resolved_event = reporting_event.dup
bot_resolved_event.name = 'conversation_bot_resolved'
bot_resolved_event.from_state = 'bot_handling'
bot_resolved_event.save!
end
end
@@ -30,6 +30,9 @@ describe ReportingEventListener do
expect(created_event.user_id).to eq(user.id)
expect(created_event.event_start_time).to be_within(1.second).of(conversation.created_at)
expect(created_event.event_end_time).to be_within(1.second).of(conversation.created_at)
expect(created_event.from_state).to be_nil
expect(created_event.conversation_created_at).to be_within(1.second).of(conversation.created_at)
expect(created_event.channel_type).to eq(inbox.channel_type)
end
context 'when conversation has no assignee' do
@@ -43,6 +46,19 @@ describe ReportingEventListener do
expect(created_event.user_id).to be_nil
end
end
context 'when conversation has team assigned' do
let(:team) { create(:team, account: account) }
let(:team_conversation) { create(:conversation, account: account, inbox: inbox, assignee: user, team: team) }
it 'sets team_id on the event' do
event = Events::Base.new('conversation.created', Time.zone.now, conversation: team_conversation)
listener.conversation_created(event)
created_event = account.reporting_events.find_by(name: 'conversation_created', conversation_id: team_conversation.id)
expect(created_event.team_id).to eq(team.id)
end
end
end
describe '#conversation_resolved' do
@@ -53,6 +69,16 @@ describe ReportingEventListener do
expect(account.reporting_events.where(name: 'conversation_resolved').count).to be 1
end
it 'sets from_state to handling' do
event = Events::Base.new('conversation.resolved', Time.zone.now, conversation: conversation)
listener.conversation_resolved(event)
resolved_event = account.reporting_events.find_by(name: 'conversation_resolved')
expect(resolved_event.from_state).to eq('handling')
expect(resolved_event.conversation_created_at).to be_within(1.second).of(conversation.created_at)
expect(resolved_event.channel_type).to eq(inbox.channel_type)
end
context 'when business hours enabled for inbox' do
let(:created_at) { Time.zone.parse('March 20, 2022 00:00') }
let(:updated_at) { Time.zone.parse('March 26, 2022 23:59') }
@@ -281,6 +307,9 @@ describe ReportingEventListener do
listener.conversation_bot_handoff(event)
expect(account.reporting_events.where(name: 'conversation_bot_handoff').count).to be 1
handoff_event = account.reporting_events.find_by(name: 'conversation_bot_handoff')
expect(handoff_event.from_state).to eq('bot_handling')
# add extra handoff event for the same and ensure it's not created
event = Events::Base.new('conversation.bot_handoff', Time.zone.now, conversation: conversation)
listener.conversation_bot_handoff(event)
@@ -307,7 +336,7 @@ describe ReportingEventListener do
context 'when conversation is opened for the first time' do
let(:new_conversation) { create(:conversation, account: account, inbox: inbox, assignee: user) }
it 'creates conversation_opened event with value 0' do
it 'creates conversation_opened event with value 0 and nil from_state' do
expect(account.reporting_events.where(name: 'conversation_opened').count).to be 0
event = Events::Base.new('conversation.opened', Time.zone.now, conversation: new_conversation)
listener.conversation_opened(event)
@@ -318,6 +347,7 @@ describe ReportingEventListener do
expect(opened_event.value_in_business_hours).to eq 0
expect(opened_event.event_start_time).to be_within(1.second).of(new_conversation.created_at)
expect(opened_event.event_end_time).to be_within(1.second).of(new_conversation.updated_at)
expect(opened_event.from_state).to be_nil
end
end
@@ -367,6 +397,7 @@ describe ReportingEventListener do
expect(reopened_event.inbox_id).to eq(inbox.id)
expect(reopened_event.conversation_id).to eq(reopened_conversation.id)
expect(reopened_event.user_id).to eq(user.id)
expect(reopened_event.from_state).to eq('resolved')
end
context 'when business hours enabled for inbox' do