Add first_reply_created event in conversation (#4576)
This commit is contained in:
parent
20565d09c0
commit
8538660bbd
6 changed files with 117 additions and 22 deletions
|
@ -0,0 +1,17 @@
|
||||||
|
# Delete migration and spec after 2 consecutive releases.
|
||||||
|
class Migration::ConversationsFirstReplySchedulerJob < ApplicationJob
|
||||||
|
queue_as :scheduled_jobs
|
||||||
|
|
||||||
|
def perform(account)
|
||||||
|
account.conversations.each do |conversation|
|
||||||
|
# rubocop:disable Rails/SkipsModelValidations
|
||||||
|
if conversation.messages.outgoing.where("(additional_attributes->'campaign_id') is null").count.positive?
|
||||||
|
conversation.update_columns(first_reply_created_at: conversation.messages.outgoing.where("(additional_attributes->'campaign_id') is null")
|
||||||
|
.first.created_at)
|
||||||
|
else
|
||||||
|
conversation.update_columns(first_reply_created_at: nil)
|
||||||
|
end
|
||||||
|
# rubocop:enable Rails/SkipsModelValidations
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -36,6 +36,9 @@ class ReportingEventListener < BaseListener
|
||||||
event_start_time: conversation.created_at,
|
event_start_time: conversation.created_at,
|
||||||
event_end_time: message.created_at
|
event_end_time: message.created_at
|
||||||
)
|
)
|
||||||
|
# rubocop:disable Rails/SkipsModelValidations
|
||||||
|
conversation.update_columns(first_reply_created_at: message.created_at)
|
||||||
|
# rubocop:enable Rails/SkipsModelValidations
|
||||||
reporting_event.save
|
reporting_event.save
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
# assignee_last_seen_at :datetime
|
# assignee_last_seen_at :datetime
|
||||||
# contact_last_seen_at :datetime
|
# contact_last_seen_at :datetime
|
||||||
# custom_attributes :jsonb
|
# custom_attributes :jsonb
|
||||||
|
# first_reply_created_at :datetime
|
||||||
# identifier :string
|
# identifier :string
|
||||||
# last_activity_at :datetime not null
|
# last_activity_at :datetime not null
|
||||||
# snoozed_until :datetime
|
# snoozed_until :datetime
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
# index_conversations_on_assignee_id_and_account_id (assignee_id,account_id)
|
# index_conversations_on_assignee_id_and_account_id (assignee_id,account_id)
|
||||||
# index_conversations_on_campaign_id (campaign_id)
|
# index_conversations_on_campaign_id (campaign_id)
|
||||||
# index_conversations_on_contact_inbox_id (contact_inbox_id)
|
# index_conversations_on_contact_inbox_id (contact_inbox_id)
|
||||||
|
# index_conversations_on_first_reply_created_at (first_reply_created_at)
|
||||||
# index_conversations_on_last_activity_at (last_activity_at)
|
# index_conversations_on_last_activity_at (last_activity_at)
|
||||||
# index_conversations_on_status_and_account_id (status,account_id)
|
# index_conversations_on_status_and_account_id (status,account_id)
|
||||||
# index_conversations_on_team_id (team_id)
|
# index_conversations_on_team_id (team_id)
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
class AddFirstReplyActivityAtToConversation < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_column :conversations, :first_reply_created_at, :datetime
|
||||||
|
add_index :conversations, :first_reply_created_at
|
||||||
|
|
||||||
|
# rubocop:disable Rails/SkipsModelValidations
|
||||||
|
::Conversation.update_all(first_reply_created_at: Time.now.utc)
|
||||||
|
# rubocop:enable Rails/SkipsModelValidations
|
||||||
|
|
||||||
|
backfill_first_reply_activity_at_to_conversations
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def backfill_first_reply_activity_at_to_conversations
|
||||||
|
::Account.find_in_batches do |account_batch|
|
||||||
|
Rails.logger.info "Migrated till #{account_batch.first.id}\n"
|
||||||
|
account_batch.each do |account|
|
||||||
|
Migration::ConversationsFirstReplySchedulerJob.perform_later(account)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2022_05_11_072655) do
|
ActiveRecord::Schema.define(version: 2022_05_13_145010) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_stat_statements"
|
enable_extension "pg_stat_statements"
|
||||||
|
@ -385,11 +385,13 @@ ActiveRecord::Schema.define(version: 2022_05_11_072655) do
|
||||||
t.datetime "snoozed_until"
|
t.datetime "snoozed_until"
|
||||||
t.jsonb "custom_attributes", default: {}
|
t.jsonb "custom_attributes", default: {}
|
||||||
t.datetime "assignee_last_seen_at"
|
t.datetime "assignee_last_seen_at"
|
||||||
|
t.datetime "first_reply_created_at"
|
||||||
t.index ["account_id", "display_id"], name: "index_conversations_on_account_id_and_display_id", unique: true
|
t.index ["account_id", "display_id"], name: "index_conversations_on_account_id_and_display_id", unique: true
|
||||||
t.index ["account_id"], name: "index_conversations_on_account_id"
|
t.index ["account_id"], name: "index_conversations_on_account_id"
|
||||||
t.index ["assignee_id", "account_id"], name: "index_conversations_on_assignee_id_and_account_id"
|
t.index ["assignee_id", "account_id"], name: "index_conversations_on_assignee_id_and_account_id"
|
||||||
t.index ["campaign_id"], name: "index_conversations_on_campaign_id"
|
t.index ["campaign_id"], name: "index_conversations_on_campaign_id"
|
||||||
t.index ["contact_inbox_id"], name: "index_conversations_on_contact_inbox_id"
|
t.index ["contact_inbox_id"], name: "index_conversations_on_contact_inbox_id"
|
||||||
|
t.index ["first_reply_created_at"], name: "index_conversations_on_first_reply_created_at"
|
||||||
t.index ["last_activity_at"], name: "index_conversations_on_last_activity_at"
|
t.index ["last_activity_at"], name: "index_conversations_on_last_activity_at"
|
||||||
t.index ["status", "account_id"], name: "index_conversations_on_status_and_account_id"
|
t.index ["status", "account_id"], name: "index_conversations_on_status_and_account_id"
|
||||||
t.index ["team_id"], name: "index_conversations_on_team_id"
|
t.index ["team_id"], name: "index_conversations_on_team_id"
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Migration::ConversationsFirstReplySchedulerJob, type: :job do
|
||||||
|
subject(:job) { described_class.perform_later }
|
||||||
|
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:inbox) { create(:inbox, account: account) }
|
||||||
|
let!(:user) { create(:user, account: account) }
|
||||||
|
|
||||||
|
it 'enqueues the job' do
|
||||||
|
expect { job }.to have_enqueued_job(described_class)
|
||||||
|
.on_queue('scheduled_jobs')
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there is an outgoing message in conversation' do
|
||||||
|
let!(:conversation) { create(:conversation, account: account, inbox: inbox, assignee: user) }
|
||||||
|
let!(:message) do
|
||||||
|
create(:message, content: 'Hi', message_type: 'outgoing', account: account, inbox: inbox,
|
||||||
|
conversation: conversation)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates the conversation first reply with the first outgoing message created time' do
|
||||||
|
create(:message, content: 'Hello', message_type: 'outgoing', account: account, inbox: inbox,
|
||||||
|
conversation: conversation)
|
||||||
|
|
||||||
|
described_class.perform_now(account)
|
||||||
|
conversation.reload
|
||||||
|
|
||||||
|
expect(conversation.messages.count).to eq 2
|
||||||
|
expect(conversation.first_reply_created_at.to_i).to eq message.created_at.to_i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there is no outgoing message in conversation' do
|
||||||
|
let!(:conversation) { create(:conversation, account: account, inbox: inbox, assignee: user) }
|
||||||
|
|
||||||
|
it 'updates the conversation first reply with nil' do
|
||||||
|
create(:message, content: 'Hello', message_type: 'incoming', account: account, inbox: inbox,
|
||||||
|
conversation: conversation)
|
||||||
|
|
||||||
|
described_class.perform_now(account)
|
||||||
|
conversation.reload
|
||||||
|
|
||||||
|
expect(conversation.messages.count).to eq 1
|
||||||
|
expect(conversation.first_reply_created_at).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue