feat: Ability to seed Demo Accounts (#5352)

Introduces the ability to seed sample data into accounts in development and staging.

fixes: #3429
This commit is contained in:
Sojan Jose
2022-09-01 00:31:43 +05:30
committed by GitHub
parent ebea5428bc
commit c8d01a84ce
13 changed files with 593 additions and 76 deletions

View File

@@ -1,89 +1,105 @@
## Class to generate sample data for a chatwoot test Account.
## Class to generate sample data for a chatwoot test @Account.
############################################################
### Usage #####
#
# # Seed an account with all data types in this class
# Seeders::AccountSeeder.new(account: account).seed!
# Seeders::AccountSeeder.new(account: @Account.find(1)).perform!
#
# # When you want to seed only a specific type of data
# Seeders::AccountSeeder.new(account: account).seed_canned_responses
# # Seed specific number of objects
# Seeders::AccountSeeder.new(account: account).seed_canned_responses(count: 10)
#
############################################################
class Seeders::AccountSeeder
pattr_initialize [:account!]
def initialize(account:)
raise 'Account Seeding is not allowed in production.' if Rails.env.production?
def seed!
@account_data = HashWithIndifferentAccess.new(YAML.safe_load(File.read(Rails.root.join('lib/seeders/seed_data.yml'))))
@account = account
end
def perform!
set_up_account
seed_teams
set_up_users
seed_labels
seed_canned_responses
seed_inboxes
seed_contacts
end
def set_up_account
@account.teams.destroy_all
@account.conversations.destroy_all
@account.labels.destroy_all
@account.inboxes.destroy_all
@account.contacts.destroy_all
end
def seed_teams
@account_data['teams'].each do |team_name|
@account.teams.create!(name: team_name)
end
end
def seed_labels
@account_data['labels'].each do |label|
@account.labels.create!(label)
end
end
def set_up_users
@account_data['users'].each do |user|
user_record = User.create_with(name: user['name'], password: 'Password1!.').find_or_create_by!(email: (user['email']).to_s)
user_record.skip_confirmation!
user_record.save!
Avatar::AvatarFromUrlJob.perform_later(user_record, "https://xsgames.co/randomusers/avatar.php?g=#{user['gender']}")
AccountUser.create_with(role: (user['role'] || 'agent')).find_or_create_by!(account_id: @account.id, user_id: user_record.id)
next if user['team'].blank?
add_user_to_teams(user: user_record, teams: user['team'])
end
end
def add_user_to_teams(user:, teams:)
teams.each do |team|
team_record = @account.teams.where('name LIKE ?', "%#{team.downcase}%").first if team.present?
TeamMember.find_or_create_by!(team_id: team_record.id, user_id: user.id) unless team_record.nil?
end
end
def seed_canned_responses(count: 50)
count.times do
account.canned_responses.create(content: Faker::Quote.fortune_cookie, short_code: Faker::Alphanumeric.alpha(number: 10))
@account.canned_responses.create(content: Faker::Quote.fortune_cookie, short_code: Faker::Alphanumeric.alpha(number: 10))
end
end
def seed_contacts
@account_data['contacts'].each do |contact_data|
contact = @account.contacts.create!(contact_data.slice('name', 'email'))
Avatar::AvatarFromUrlJob.perform_later(contact, "https://xsgames.co/randomusers/avatar.php?g=#{contact_data['gender']}")
contact_data['conversations'].each do |conversation_data|
inbox = @account.inboxes.find_by(channel_type: conversation_data['channel'])
contact_inbox = inbox.contact_inboxes.create!(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.find_by(email: conversation_data['assignee']) if conversation_data['assignee'].present?
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'])
end
def create_messages(conversation:, messages:)
messages.each do |message_data|
sender = User.find_by(email: message_data['sender']) if message_data['sender'].present?
conversation.messages.create!(message_data.slice('content', 'message_type').merge(account: conversation.inbox.account, sender: sender,
inbox: conversation.inbox))
end
end
def seed_inboxes
seed_website_inbox
seed_facebook_inbox
seed_twitter_inbox
seed_whatsapp_inbox
seed_sms_inbox
seed_email_inbox
seed_api_inbox
seed_telegram_inbox
seed_line_inbox
end
def seed_website_inbox
channel = Channel::WebWidget.create!(account: account, website_url: 'https://acme.inc')
Inbox.create!(channel: channel, account: account, name: 'Acme Website')
end
def seed_facebook_inbox
channel = Channel::FacebookPage.create!(account: account, user_access_token: 'test', page_access_token: 'test', page_id: 'test')
Inbox.create!(channel: channel, account: account, name: 'Acme Facebook')
end
def seed_twitter_inbox
channel = Channel::TwitterProfile.create!(account: account, twitter_access_token: 'test', twitter_access_token_secret: 'test', profile_id: '123')
Inbox.create!(channel: channel, account: account, name: 'Acme Twitter')
end
def seed_whatsapp_inbox
channel = Channel::Whatsapp.create!(account: account, phone_number: '+123456789')
Inbox.create!(channel: channel, account: account, name: 'Acme Whatsapp')
end
def seed_sms_inbox
channel = Channel::Sms.create!(account: account, phone_number: '+123456789')
Inbox.create!(channel: channel, account: account, name: 'Acme SMS')
end
def seed_email_inbox
channel = Channel::Email.create!(account: account, email: 'test@acme.inc', forward_to_email: 'test_fwd@acme.inc')
Inbox.create!(channel: channel, account: account, name: 'Acme Email')
end
def seed_api_inbox
channel = Channel::Api.create!(account: account)
Inbox.create!(channel: channel, account: account, name: 'Acme API')
end
def seed_telegram_inbox
# rubocop:disable Rails/SkipsModelValidations
Channel::Telegram.insert({ account_id: account.id, bot_name: 'Acme', bot_token: 'test', created_at: Time.now.utc, updated_at: Time.now.utc },
returning: %w[id])
channel = Channel::Telegram.find_by(bot_token: 'test')
Inbox.create!(channel: channel, account: account, name: 'Acme Telegram')
# rubocop:enable Rails/SkipsModelValidations
end
def seed_line_inbox
channel = Channel::Line.create!(account: account, line_channel_id: 'test', line_channel_secret: 'test', line_channel_token: 'test')
Inbox.create!(channel: channel, account: account, name: 'Acme Line')
Seeders::InboxSeeder.new(account: @account, company_data: @account_data[:company]).perform!
end
end

105
lib/seeders/inbox_seeder.rb Normal file
View File

@@ -0,0 +1,105 @@
## Class to generate sample inboxes for a chatwoot test @Account.
############################################################
### Usage #####
#
# # Seed an account with all data types in this class
# Seeders::InboxSeeder.new(account: @Account.find(1), company_data: {name: 'PaperLayer', doamin: 'paperlayer.test'}).perform!
#
#
############################################################
class Seeders::InboxSeeder
def initialize(account:, company_data:)
raise 'Inbox Seeding is not allowed in production.' if Rails.env.production?
@account = account
@company_data = company_data
end
def perform!
seed_website_inbox
seed_facebook_inbox
seed_twitter_inbox
seed_whatsapp_inbox
seed_sms_inbox
seed_email_inbox
seed_api_inbox
seed_telegram_inbox
seed_line_inbox
end
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")
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")
end
def seed_twitter_inbox
channel = Channel::TwitterProfile.create!(account: @account, twitter_access_token: SecureRandom.hex,
twitter_access_token_secret: SecureRandom.hex, profile_id: '123')
Inbox.create!(channel: channel, account: @account, name: "#{@company_data['name']} Twitter")
end
def seed_whatsapp_inbox
# rubocop:disable Rails/SkipsModelValidations
Channel::Whatsapp.insert(
{
account_id: @account.id,
phone_number: Faker::PhoneNumber.cell_phone_in_e164,
created_at: Time.now.utc,
updated_at: Time.now.utc
},
returning: %w[id]
)
# rubocop:enable Rails/SkipsModelValidations
channel = Channel::Whatsapp.find_by(account_id: @account.id)
Inbox.create!(channel: channel, account: @account, name: "#{@company_data['name']} Whatsapp")
end
def seed_sms_inbox
channel = Channel::Sms.create!(account: @account, phone_number: Faker::PhoneNumber.cell_phone_in_e164)
Inbox.create!(channel: channel, account: @account, name: "#{@company_data['name']} Mobile")
end
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")
end
def seed_api_inbox
channel = Channel::Api.create!(account: @account)
Inbox.create!(channel: channel, account: @account, name: "#{@company_data['name']} API")
end
def seed_telegram_inbox
# rubocop:disable Rails/SkipsModelValidations
bot_token = SecureRandom.hex
Channel::Telegram.insert(
{
account_id: @account.id,
bot_name: (@company_data['name']).to_s,
bot_token: bot_token,
created_at: Time.now.utc,
updated_at: Time.now.utc
},
returning: %w[id]
)
channel = Channel::Telegram.find_by(bot_token: bot_token)
Inbox.create!(channel: channel, account: @account, name: "#{@company_data['name']} Telegram")
# rubocop:enable Rails/SkipsModelValidations
end
def seed_line_inbox
channel = Channel::Line.create!(account: @account, line_channel_id: SecureRandom.hex, line_channel_secret: SecureRandom.hex,
line_channel_token: SecureRandom.hex)
Inbox.create!(channel: channel, account: @account, name: "#{@company_data['name']} Line")
end
end

367
lib/seeders/seed_data.yml Normal file
View File

@@ -0,0 +1,367 @@
company:
name: 'PaperLayer'
domain: 'paperlayer.test'
users:
- name: 'Michael Scott'
gender: male
email: 'michale@paperlayer.test'
team:
- 'sales'
- 'management'
- 'administration'
- 'warehouse'
role: 'administrator'
- name: 'David Wallace'
gender: male
email: 'david@paperlayer.test'
team:
- 'Management'
- name: 'Deangelo Vickers'
gender: male
email: 'deangelo@paperlayer.test'
team:
- 'Management'
- name: 'Jo Bennett'
gender: female
email: 'jo@paperlayer.test'
team:
- 'Management'
- name: 'Josh Porter'
gender: male
email: 'josh@paperlayer.test'
team:
- 'Management'
- name: 'Charles Miner'
gender: male
email: 'charles@paperlayer.test'
team:
- 'Management'
- name: 'Ed Truck'
gender: male
email: 'ed@paperlayer.test'
team:
- 'Management'
- name: 'Dan Gore'
gender: male
email: 'dan@paperlayer.test'
team:
- 'Management'
- name: 'Craig D'
gender: male
email: 'craig@paperlayer.test'
team:
- 'Management'
- name: 'Troy Underbridge'
gender: male
email: 'troy@paperlayer.test'
team:
- 'Management'
- name: 'Karen Filippelli'
gender: female
email: 'karn@paperlayer.test'
team:
- 'Sales'
- name: 'Danny Cordray'
gender: female
email: 'danny@paperlayer.test'
team:
- 'Sales'
- name: 'Ben Nugent'
gender: male
email: 'ben@paperlayer.test'
team:
- 'Sales'
- name: 'Todd Packer'
gender: male
email: 'todd@paperlayer.test'
team:
- 'Sales'
- name: 'Cathy Simms'
gender: female
email: 'cathy@paperlayer.test'
team:
- 'Administration'
- name: 'Hunter Jo'
gender: male
email: 'hunter@paperlayer.test'
team:
- 'Administration'
- name: 'Rolando Silva'
gender: male
email: 'rolando@paperlayer.test'
team:
- 'Administration'
- name: 'Stephanie Wilson'
gender: female
email: 'stephanie@paperlayer.test'
team:
- 'Administration'
- name: 'Jordan Garfield'
gender: male
email: 'jorodan@paperlayer.test'
team:
- 'Administration'
- name: 'Ronni Carlo'
gender: male
email: 'ronni@paperlayer.test'
team:
- 'Administration'
- name: 'Lonny Collins'
gender: female
email: 'lonny@paperlayer.test'
team:
- 'Warehouse'
- name: 'Madge Madsen'
gender: female
email: 'madge@paperlayer.test'
team:
- 'Warehouse'
- name: 'Glenn Max'
gender: female
email: 'glenn@paperlayer.test'
team:
- 'Warehouse'
- name: 'Jerry DiCanio'
gender: male
email: 'jerry@paperlayer.test'
team:
- 'Warehouse'
- name: 'Phillip Martin'
gender: male
email: 'phillip@paperlayer.test'
team:
- 'Warehouse'
- name: 'Michael Josh'
gender: male
email: 'michale_josh@paperlayer.test'
team:
- 'Warehouse'
- name: 'Matt Hudson'
gender: male
email: 'matt@paperlayer.test'
team:
- 'Warehouse'
- name: 'Gideon'
gender: male
email: 'gideon@paperlayer.test'
team:
- 'Warehouse'
- name: 'Bruce'
gender: male
email: 'bruce@paperlayer.test'
team:
- 'Warehouse'
- name: 'Frank'
gender: male
email: 'frank@paperlayer.test'
team:
- 'Warehouse'
- name: 'Louanne Kelley'
gender: female
email: 'louanne@paperlayer.test'
- name: 'Devon White'
gender: male
email: 'devon@paperlayer.test'
- name: 'Kendall'
gender: male
email: 'kendall@paperlayer.test'
- email: 'sadiq@paperlayer.test'
name: 'Sadiq'
gender: male
teams:
- '💰 Sales'
- '💼 Management'
- '👩‍💼 Administration'
- '🚛 Warehouse'
labels:
- title: 'billing'
color: '#28AD21'
show_on_sidebar: true
- title: 'software'
color: '#8F6EF2'
show_on_sidebar: true
- title: 'delivery'
color: '#A2FDD5'
show_on_sidebar: true
- title: 'ops-handover'
color: '#A53326'
show_on_sidebar: true
- title: 'premium-customer'
color: '#6FD4EF'
show_on_sidebar: true
- title: 'lead'
color: '#F161C8'
show_on_sidebar: true
contacts:
- name: "Lorrie Trosdall"
email: "ltrosdall0@bravesites.test"
gender: 'female'
conversations:
- channel: Channel::WebWidget
messages:
- message_type: incoming
content: hello world
- name: "Tiffanie Cloughton"
email: "tcloughton1@newyorker.test"
gender: 'female'
conversations:
- channel: Channel::FacebookPage
messages:
- message_type: incoming
content: hello world
- name: "Melonie Keatch"
email: "mkeatch2@reuters.test"
gender: 'female'
conversations:
- channel: Channel::TwitterProfile
messages:
- message_type: incoming
content: hello world
- name: "Olin Canniffe"
email: "ocanniffe3@feedburner.test"
gender: 'male'
conversations:
- channel: Channel::Whatsapp
messages:
- message_type: incoming
content: hello world
- name: "Viviene Corp"
email: "vcorp4@instagram.test"
gender: 'female'
conversations:
- channel: Channel::Sms
source_id: "+1234567"
messages:
- message_type: incoming
content: hello world
- name: "Drake Pittway"
email: "dpittway5@chron.test"
gender: 'male'
conversations:
- channel: Channel::Line
messages:
- message_type: incoming
content: hello world
- name: "Klaus Crawley"
email: "kcrawley6@narod.ru"
gender: 'male'
conversations:
- channel: Channel::WebWidget
messages:
- message_type: incoming
content: hello world
- name: "Bing Cusworth"
email: "bcusworth7@arstechnica.test"
gender: 'male'
conversations:
- channel: Channel::TwitterProfile
messages:
- message_type: incoming
content: hello world
- name: "Claus Jira"
email: "cjira8@comcast.net"
gender: 'male'
conversations:
- channel: Channel::Whatsapp
messages:
- message_type: incoming
content: hello world
- name: "Quent Dalliston"
email: "qdalliston9@zimbio.test"
gender: 'male'
conversations:
- channel: Channel::Whatsapp
messages:
- message_type: incoming
content: hello world
- name: "Coreen Mewett"
email: "cmewetta@home.pl"
gender: 'female'
conversations:
- channel: Channel::FacebookPage
messages:
- message_type: incoming
content: hello world
- name: "Benyamin Janeway"
email: "bjanewayb@ustream.tv"
gender: 'male'
conversations:
- channel: Channel::Line
messages:
- message_type: incoming
content: hello world
- name: "Cordell Dalinder"
email: "cdalinderc@msn.test"
gender: 'male'
conversations:
- channel: Channel::Email
source_id: "cdalinderc@msn.test"
messages:
- message_type: incoming
content: hello world
- name: "Merrile Petruk"
email: "mpetrukd@wunderground.test"
gender: 'female'
conversations:
- channel: Channel::Email
source_id: "mpetrukd@wunderground.test"
messages:
- message_type: incoming
content: hello world
- name: "Nathaniel Vannuchi"
email: "nvannuchie@photobucket.test"
gender: 'male'
conversations:
- channel: Channel::FacebookPage
messages:
- message_type: incoming
content: "Hey there,I need some help with billing, my card is not working on the website."
- name: "Olia Olenchenko"
email: "oolenchenkof@bluehost.test"
gender: 'female'
conversations:
- channel: Channel::WebWidget
assignee: michael_scott@paperlayer.test
messages:
- message_type: incoming
content: "Billing section is not working, it throws some error."
- name: "Elisabeth Derington"
email: "ederingtong@printfriendly.test"
gender: 'female'
conversations:
- channel: Channel::Whatsapp
messages:
- message_type: incoming
content: "Hey \n I didn't get the product delivered, but it shows it is delivered to my address. Please check"
- name: "Willy Castelot"
email: "wcasteloth@exblog.jp"
gender: 'male'
conversations:
- channel: Channel::WebWidget
messages:
- message_type: incoming
content: "Hey there, \n I need some help with the product, my button is not working on the website."
- name: "Ophelia Folkard"
email: "ofolkardi@taobao.test"
gender: 'female'
conversations:
- channel: Channel::WebWidget
assignee: michael_scott@paperlayer.test
messages:
- message_type: incoming
content: "Hey, \n My card is not working on your website. Please help"
- name: "Candice Matherson"
email: "cmathersonj@va.gov"
gender: 'female'
conversations:
- channel: Channel::Email
source_id: "cmathersonj@va.gov"
assignee: michael_scott@paperlayer.test
messages:
- message_type: incoming
content: "Hey, \n I'm looking for some help to figure out if it is the right product for me."
- message_type: outgoing
content: Welcome to PaperLayer. Our Team will be getting back you shortly.
- message_type: outgoing
content: How may i help you ?
sender: michael_scott@paperlayer.test