feat(captain-memory): add SilenceDetectorJob with 10min cron
This commit is contained in:
parent
1646f66a97
commit
833e76856e
@ -101,3 +101,9 @@ landing_hosts_promotion_sync_scheduler_job:
|
||||
cron: '0 * * * *'
|
||||
class: 'LandingHosts::PromotionSyncSchedulerJob'
|
||||
queue: scheduled_jobs
|
||||
|
||||
# every 10 minutes - detects silent conversations for memory extraction
|
||||
captain_contact_memory_silence_detector_job:
|
||||
cron: '*/10 * * * *'
|
||||
class: 'Captain::ContactMemories::SilenceDetectorJob'
|
||||
queue: scheduled_jobs
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
class Captain::ContactMemories::SilenceDetectorJob < ApplicationJob
|
||||
queue_as :scheduled_jobs
|
||||
|
||||
SILENCE_THRESHOLD = 30.minutes
|
||||
|
||||
def perform
|
||||
Account.where("custom_attributes->>'captain_contact_memory_extraction_enabled' = 'true'").find_each do |account|
|
||||
elegible_conversation_ids(account).each do |conv_id|
|
||||
Captain::ContactMemories::ExtractFromConversationJob.perform_later(conv_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def elegible_conversation_ids(account)
|
||||
Conversation
|
||||
.where(account_id: account.id)
|
||||
.joins(:messages)
|
||||
.where.not(id: already_extracted_ids(account))
|
||||
.group('conversations.id')
|
||||
.having('MAX(messages.created_at) < ?', SILENCE_THRESHOLD.ago)
|
||||
.pluck(:id)
|
||||
end
|
||||
|
||||
def already_extracted_ids(account)
|
||||
Captain::ContactMemory
|
||||
.where(account_id: account.id)
|
||||
.where.not(source_conversation_id: nil)
|
||||
.distinct
|
||||
.pluck(:source_conversation_id)
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,52 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Captain::ContactMemories::SilenceDetectorJob do
|
||||
let(:account) { create(:account, custom_attributes: { 'captain_contact_memory_extraction_enabled' => true }) }
|
||||
let(:contact) { create(:contact, account: account) }
|
||||
|
||||
# Widget inboxes auto-generate template messages (pre-chat form, etc.) with current
|
||||
# timestamps when an incoming message is created. To deterministically test "silence",
|
||||
# we update all messages in the conversation to an old created_at via update_all
|
||||
# (bypassing callbacks) after creation.
|
||||
def age_all_messages(conversation, age)
|
||||
conversation.messages.update_all(created_at: age) # rubocop:disable Rails/SkipsModelValidations
|
||||
end
|
||||
|
||||
it 'enqueues extraction for conversations silent > 30 minutes' do
|
||||
conv = create(:conversation, account: account, contact: contact)
|
||||
create(:message, conversation: conv, account: account)
|
||||
age_all_messages(conv, 35.minutes.ago)
|
||||
|
||||
expect { described_class.perform_now }
|
||||
.to have_enqueued_job(Captain::ContactMemories::ExtractFromConversationJob).with(conv.id)
|
||||
end
|
||||
|
||||
it 'ignores conversations with recent activity' do
|
||||
conv = create(:conversation, account: account, contact: contact)
|
||||
create(:message, conversation: conv, account: account)
|
||||
age_all_messages(conv, 5.minutes.ago)
|
||||
|
||||
expect { described_class.perform_now }
|
||||
.not_to have_enqueued_job(Captain::ContactMemories::ExtractFromConversationJob)
|
||||
end
|
||||
|
||||
it 'ignores conversations already extracted' do
|
||||
conv = create(:conversation, account: account, contact: contact)
|
||||
create(:message, conversation: conv, account: account)
|
||||
age_all_messages(conv, 35.minutes.ago)
|
||||
create(:captain_contact_memory, account: account, contact: contact, source_conversation_id: conv.id)
|
||||
|
||||
expect { described_class.perform_now }
|
||||
.not_to have_enqueued_job(Captain::ContactMemories::ExtractFromConversationJob)
|
||||
end
|
||||
|
||||
it 'ignores accounts with flag off' do
|
||||
account.update!(custom_attributes: { 'captain_contact_memory_extraction_enabled' => false })
|
||||
conv = create(:conversation, account: account, contact: contact)
|
||||
create(:message, conversation: conv, account: account)
|
||||
age_all_messages(conv, 35.minutes.ago)
|
||||
|
||||
expect { described_class.perform_now }
|
||||
.not_to have_enqueued_job(Captain::ContactMemories::ExtractFromConversationJob)
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user