From 5d2ab0e017e7def1969b22bf1a58b31fdfe964d6 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 2 Jun 2025 12:49:03 +0530 Subject: [PATCH] feat: separate csat seeder --- lib/seeders/account_seeder.rb | 43 +------------- lib/seeders/conversation_seeder.rb | 94 ++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 41 deletions(-) create mode 100644 lib/seeders/conversation_seeder.rb diff --git a/lib/seeders/account_seeder.rb b/lib/seeders/account_seeder.rb index e7fa2d126..1339d4faa 100644 --- a/lib/seeders/account_seeder.rb +++ b/lib/seeders/account_seeder.rb @@ -117,49 +117,10 @@ class Seeders::AccountSeeder contact.update!(contact_data.slice('name', 'email')) Avatar::AvatarFromUrlJob.perform_later(contact, "https://xsgames.co/randomusers/avatar.php?g=#{contact_data['gender']}") end - contact_data['conversations'].each do |conversation_data| - inbox = @account.inboxes.find_by(channel_type: conversation_data['channel']) - contact_inbox = inbox.contact_inboxes.create_or_find_by!(contact: contact, source_id: (conversation_data['source_id'] || SecureRandom.hex)) - create_conversation(contact_inbox: contact_inbox, conversation_data: conversation_data) - end end - end - def create_conversation(contact_inbox:, conversation_data:) - assignee = User.from_email(conversation_data['assignee']) if conversation_data['assignee'].present? - - # Assign random agent if no assignee specified and inbox has CSAT enabled - assignee = @account.agents.sample if assignee.nil? && contact_inbox.inbox.csat_survey_enabled - - conversation = contact_inbox.conversations.create!(account: contact_inbox.inbox.account, contact: contact_inbox.contact, - inbox: contact_inbox.inbox, assignee: assignee) - create_messages(conversation: conversation, messages: conversation_data['messages']) - conversation.update_labels(conversation_data[:labels]) if conversation_data[:labels].present? - conversation.update!(priority: conversation_data[:priority]) if conversation_data[:priority].present? - - # Resolve some conversations (about 60%) that have assignees to generate CSAT data - return unless assignee.present? && rand > 0.4 - - conversation.update!(status: :resolved) - end - - def create_messages(conversation:, messages:) - messages.each do |message_data| - sender = find_message_sender(conversation, message_data) - conversation.messages.create!( - message_data.slice('content', 'message_type').merge( - account: conversation.inbox.account, sender: sender, inbox: conversation.inbox - ) - ) - end - end - - def find_message_sender(conversation, message_data) - if message_data['message_type'] == 'incoming' - conversation.contact - elsif message_data['sender'].present? - User.from_email(message_data['sender']) - end + # Create conversations after all contacts are created + Seeders::ConversationSeeder.new(account: @account, contact_data: @account_data['contacts']).perform! end def seed_inboxes diff --git a/lib/seeders/conversation_seeder.rb b/lib/seeders/conversation_seeder.rb new file mode 100644 index 000000000..1db37cb6d --- /dev/null +++ b/lib/seeders/conversation_seeder.rb @@ -0,0 +1,94 @@ +## Class to generate sample conversations for a chatwoot test @Account. +############################################################ +### Usage ##### +# +# # Seed an account with conversations +# Seeders::ConversationSeeder.new(account: Account.find(1), contact_data: []).perform! +# +# +############################################################ + +class Seeders::ConversationSeeder + def initialize(account:, contact_data:) + raise 'Conversation Seeding is not allowed in production.' unless ENV.fetch('ENABLE_ACCOUNT_SEEDING', !Rails.env.production?) + + @account = account + @contact_data = contact_data + end + + def perform! + seed_conversations + end + + private + + def seed_conversations + @contact_data.each do |contact_data| + contact = @account.contacts.find_by(email: contact_data['email']) + next unless contact + + contact_data['conversations'].each do |conversation_data| + inbox = @account.inboxes.find_by(channel_type: conversation_data['channel']) + contact_inbox = inbox.contact_inboxes.create_or_find_by!( + contact: contact, + source_id: (conversation_data['source_id'] || SecureRandom.hex) + ) + create_conversation(contact_inbox: contact_inbox, conversation_data: conversation_data) + end + end + end + + def create_conversation(contact_inbox:, conversation_data:) + assignee = determine_assignee(conversation_data, contact_inbox.inbox) + conversation = build_conversation(contact_inbox, assignee) + + create_messages(conversation: conversation, messages: conversation_data['messages']) + apply_conversation_attributes(conversation, conversation_data) + resolve_conversation_if_needed(conversation, assignee) + end + + def determine_assignee(conversation_data, inbox) + assignee = User.from_email(conversation_data['assignee']) if conversation_data['assignee'].present? + assignee ||= @account.agents.sample if inbox.csat_survey_enabled + assignee + end + + def build_conversation(contact_inbox, assignee) + contact_inbox.conversations.create!( + account: contact_inbox.inbox.account, + contact: contact_inbox.contact, + inbox: contact_inbox.inbox, + assignee: assignee + ) + end + + def apply_conversation_attributes(conversation, conversation_data) + conversation.update_labels(conversation_data[:labels]) if conversation_data[:labels].present? + conversation.update!(priority: conversation_data[:priority]) if conversation_data[:priority].present? + end + + def resolve_conversation_if_needed(conversation, assignee) + return unless assignee.present? && rand > 0.4 + + conversation.update!(status: :resolved) + end + + def create_messages(conversation:, messages:) + messages.each do |message_data| + sender = find_message_sender(conversation, message_data) + conversation.messages.create!( + message_data.slice('content', 'message_type').merge( + account: conversation.inbox.account, sender: sender, inbox: conversation.inbox + ) + ) + end + end + + def find_message_sender(conversation, message_data) + if message_data['message_type'] == 'incoming' + conversation.contact + elsif message_data['sender'].present? + User.from_email(message_data['sender']) + end + end +end \ No newline at end of file