feat: add csat to account seeder

This commit is contained in:
Shivam Mishra
2025-06-02 12:43:07 +05:30
parent 4061f99114
commit 6a07efb461
4 changed files with 184 additions and 4 deletions
+14
View File
@@ -25,6 +25,7 @@ class Seeders::AccountSeeder
seed_canned_responses
seed_inboxes
seed_contacts
seed_csat_responses
end
def set_up_account
@@ -126,11 +127,20 @@ class Seeders::AccountSeeder
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:)
@@ -155,4 +165,8 @@ class Seeders::AccountSeeder
def seed_inboxes
Seeders::InboxSeeder.new(account: @account, company_data: @account_data[:company]).perform!
end
def seed_csat_responses
Seeders::CsatSeeder.new(account: @account).perform!
end
end
+88
View File
@@ -0,0 +1,88 @@
## Class to generate sample CSAT survey responses for a chatwoot test @Account.
############################################################
### Usage #####
#
# # Seed an account with CSAT responses
# Seeders::CsatSeeder.new(account: Account.find(1)).perform!
#
#
############################################################
class Seeders::CsatSeeder
def initialize(account:)
raise 'CSAT Seeding is not allowed in production.' unless ENV.fetch('ENABLE_ACCOUNT_SEEDING', !Rails.env.production?)
@account = account
end
def perform!
seed_csat_responses
end
private
def seed_csat_responses
resolved_conversations = @account.conversations.where(status: :resolved)
csat_enabled_inboxes = @account.inboxes.where(csat_survey_enabled: true)
return if resolved_conversations.empty? || csat_enabled_inboxes.empty?
# Create CSAT responses for resolved conversations in CSAT-enabled inboxes
resolved_conversations.joins(:inbox).where(inbox: csat_enabled_inboxes).find_each do |conversation|
# Only create CSAT for about 70% of resolved conversations to simulate real-world scenarios
next if rand > 0.7
# Get the last outgoing message to attach CSAT to
last_outgoing_message = conversation.messages.where(message_type: :outgoing).last
next unless last_outgoing_message
# Create CSAT survey response with varied ratings and feedback
create_csat_response(conversation, last_outgoing_message)
end
end
def create_csat_response(conversation, message)
# Generate realistic rating distribution (more positive ratings)
rating = case rand
when 0.0..0.05 then 1 # 5%
when 0.05..0.15 then 2 # 10%
when 0.15..0.35 then 3 # 20%
when 0.35..0.65 then 4 # 30%
else 5 # 35%
end
feedback_messages = [
'Great service, very helpful!',
'Quick response and resolved my issue',
'Professional and courteous support',
'Could be faster but overall good',
'Satisfied with the resolution',
'Excellent customer service',
'Very knowledgeable agent',
'Resolved quickly, thank you!',
'Good experience overall',
'Agent was very patient and helpful',
'Really appreciate the help',
'Fast and efficient service',
'Agent went above and beyond',
'Clear explanations provided',
'Issue resolved on first contact',
'', # Some responses have no feedback
'',
''
]
CsatSurveyResponse.create!(
account: @account,
conversation: conversation,
contact: conversation.contact,
message: message,
assigned_agent: conversation.assignee,
rating: rating,
feedback_message: feedback_messages.sample,
created_at: message.created_at + rand(5..30).minutes
)
rescue StandardError => e
Rails.logger.debug { "Failed to create CSAT response: #{e.message}" }
end
end
+30 -3
View File
@@ -30,13 +30,31 @@ class Seeders::InboxSeeder
def seed_website_inbox
channel = Channel::WebWidget.create!(account: @account, website_url: "https://#{@company_data['domain']}")
Inbox.create!(channel: channel, account: @account, name: "#{@company_data['name']} Website")
Inbox.create!(
channel: channel,
account: @account,
name: "#{@company_data['name']} Website",
csat_survey_enabled: true,
csat_config: {
'display_type' => 'emoji',
'message' => 'How would you rate your experience?'
}
)
end
def seed_facebook_inbox
channel = Channel::FacebookPage.create!(account: @account, user_access_token: SecureRandom.hex, page_access_token: SecureRandom.hex,
page_id: SecureRandom.hex)
Inbox.create!(channel: channel, account: @account, name: "#{@company_data['name']} Facebook")
Inbox.create!(
channel: channel,
account: @account,
name: "#{@company_data['name']} Facebook",
csat_survey_enabled: true,
csat_config: {
'display_type' => 'star',
'message' => 'Please rate your support experience'
}
)
end
def seed_twitter_inbox
@@ -71,7 +89,16 @@ class Seeders::InboxSeeder
def seed_email_inbox
channel = Channel::Email.create!(account: @account, email: "test#{SecureRandom.hex}@#{@company_data['domain']}",
forward_to_email: "test_fwd#{SecureRandom.hex}@#{@company_data['domain']}")
Inbox.create!(channel: channel, account: @account, name: "#{@company_data['name']} Email")
Inbox.create!(
channel: channel,
account: @account,
name: "#{@company_data['name']} Email",
csat_survey_enabled: true,
csat_config: {
'display_type' => 'emoji',
'message' => 'How was your support experience today?'
}
)
end
def seed_api_inbox
+52 -1
View File
@@ -477,4 +477,55 @@ contacts:
- message_type: outgoing
sender: michael_scott@paperlayer.test
content: How may i help you ?
sender: michael_scott@paperlayer.test
- name: "Robert Maxwell"
email: "rmaxwell@example.test"
gender: 'male'
conversations:
- channel: Channel::WebWidget
assignee: karn@paperlayer.test
messages:
- message_type: incoming
content: "Hi, I need help with my account settings."
- message_type: outgoing
sender: karn@paperlayer.test
content: "I'd be happy to help you with your account settings. What specifically would you like to change?"
- message_type: incoming
content: "I want to update my billing information."
- message_type: outgoing
sender: karn@paperlayer.test
content: "Perfect! I've sent you a secure link to update your billing information. Please check your email."
- name: "Sarah Johnson"
email: "sjohnson@demo.test"
gender: 'female'
conversations:
- channel: Channel::FacebookPage
assignee: danny@paperlayer.test
messages:
- message_type: incoming
content: "Hello, I'm having trouble with the mobile app."
- message_type: outgoing
sender: danny@paperlayer.test
content: "Sorry to hear that! Can you tell me what specific issue you're experiencing?"
- message_type: incoming
content: "The app keeps crashing when I try to upload a document."
- message_type: outgoing
sender: danny@paperlayer.test
content: "I understand how frustrating that must be. Let me help you troubleshoot this issue right away."
- name: "David Chen"
email: "dchen@sample.test"
gender: 'male'
conversations:
- channel: Channel::Email
source_id: "dchen@sample.test"
assignee: ben@paperlayer.test
messages:
- message_type: incoming
content: "I need assistance with integrating your API."
- message_type: outgoing
sender: ben@paperlayer.test
content: "I'll be happy to help with the API integration. What programming language are you using?"
- message_type: incoming
content: "We're using Python for our backend."
- message_type: outgoing
sender: ben@paperlayer.test
content: "Great! I'll send you our Python SDK documentation and some sample code to get you started."