Feat: attachments automation (#4266)

This commit is contained in:
Tejaswini Chile
2022-03-30 08:08:58 +05:30
committed by GitHub
parent 3f2ac2042f
commit 15fd37b124
5 changed files with 135 additions and 15 deletions

View File

@@ -7,14 +7,22 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont
end end
def create def create
@automation_rule = Current.account.automation_rules.create(automation_rules_permit) @automation_rule = Current.account.automation_rules.new(automation_rules_permit)
@automation_rule.update(actions: params[:actions]) @automation_rule.actions = params[:actions]
render json: { error: @automation_rule.errors.messages }, status: :unprocessable_entity and return unless @automation_rule.valid?
@automation_rule.save!
process_attachments
@automation_rule
end end
def show; end def show; end
def update def update
@automation_rule.update(automation_rules_permit) @automation_rule.update(automation_rules_permit)
process_attachments
@automation_rule
end end
def destroy def destroy
@@ -31,6 +39,14 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont
private private
def process_attachments
return if params[:attachments].blank?
params[:attachments].each do |uploaded_attachment|
@automation_rule.files.attach(uploaded_attachment)
end
end
def automation_rules_permit def automation_rules_permit
params.permit( params.permit(
:name, :description, :event_name, :account_id, :active, :name, :description, :event_name, :account_id, :active,

View File

@@ -19,6 +19,7 @@
# #
class AutomationRule < ApplicationRecord class AutomationRule < ApplicationRecord
belongs_to :account belongs_to :account
has_many_attached :files
validate :json_conditions_format validate :json_conditions_format
validate :json_actions_format validate :json_actions_format
@@ -26,8 +27,8 @@ class AutomationRule < ApplicationRecord
scope :active, -> { where(active: true) } scope :active, -> { where(active: true) }
CONDITIONS_ATTRS = %w[country_code status browser_language assignee_id team_id referer].freeze CONDITIONS_ATTRS = %w[email country_code status message_type browser_language assignee_id team_id referer city company].freeze
ACTIONS_ATTRS = %w[send_message add_label send_email_to_team assign_team assign_best_agents].freeze ACTIONS_ATTRS = %w[send_message add_label send_email_to_team assign_team assign_best_agents send_attachments].freeze
private private
@@ -35,13 +36,17 @@ class AutomationRule < ApplicationRecord
return if conditions.nil? return if conditions.nil?
attributes = conditions.map { |obj, _| obj['attribute_key'] } attributes = conditions.map { |obj, _| obj['attribute_key'] }
(attributes - CONDITIONS_ATTRS).blank? conditions = attributes - CONDITIONS_ATTRS
conditions -= account.custom_attribute_definitions.pluck(:attribute_key)
errors.add(:conditions, "Automation conditions #{conditions.join(',')} not supported.") if conditions.any?
end end
def json_actions_format def json_actions_format
return if actions.nil? return if actions.nil?
attributes = actions.map { |obj, _| obj['attribute_key'] } attributes = actions.map { |obj, _| obj['attribute_key'] }
(attributes - ACTIONS_ATTRS).blank? actions = attributes - ACTIONS_ATTRS
errors.add(:actions, "Automation actions #{actions.join(',')} not supported.") if actions.any?
end end
end end

View File

@@ -21,6 +21,15 @@ class AutomationRules::ActionService
private private
def send_attachments(_file_params)
return if @rule.event_name == 'message_created'
blobs = @rule.files.map { |file, _| file.blob }
params = { content: nil, private: false, attachments: blobs }
mb = Messages::MessageBuilder.new(nil, @conversation, params)
mb.perform
end
def send_email_transcript(emails) def send_email_transcript(emails)
emails.each do |email| emails.each do |email|
ConversationReplyMailer.with(account: @conversation.account).conversation_transcript(@conversation, email)&.deliver_later ConversationReplyMailer.with(account: @conversation.account).conversation_transcript(@conversation, email)&.deliver_later
@@ -48,7 +57,7 @@ class AutomationRules::ActionService
return if @rule.event_name == 'message_created' return if @rule.event_name == 'message_created'
params = { content: message[0], private: false } params = { content: message[0], private: false }
mb = Messages::MessageBuilder.new(@administrator, @conversation, params) mb = Messages::MessageBuilder.new(nil, @conversation, params)
mb.perform mb.perform
end end
@@ -85,10 +94,6 @@ class AutomationRules::ActionService
end end
end end
def administrator
@administrator ||= @account.administrators.first
end
def agent_belongs_to_account?(agent_ids) def agent_belongs_to_account?(agent_ids)
@account.agents.pluck(:id).include?(agent_ids[0]) @account.agents.pluck(:id).include?(agent_ids[0])
end end

View File

@@ -84,6 +84,23 @@ RSpec.describe 'Api::V1::Accounts::AutomationRulesController', type: :request do
}.with_indifferent_access }.with_indifferent_access
end end
it 'throws an error for unknown attributes in condtions' do
expect(account.automation_rules.count).to eq(0)
params[:conditions] << {
attribute_key: 'unknown_attribute',
filter_operator: 'equal_to',
values: ['en'],
query_operator: 'AND'
}
post "/api/v1/accounts/#{account.id}/automation_rules",
headers: administrator.create_new_auth_token,
params: params
expect(response).to have_http_status(:unprocessable_entity)
expect(account.automation_rules.count).to eq(0)
end
it 'Saves for automation_rules for account with country_code and browser_language conditions' do it 'Saves for automation_rules for account with country_code and browser_language conditions' do
expect(account.automation_rules.count).to eq(0) expect(account.automation_rules.count).to eq(0)
@@ -113,6 +130,67 @@ RSpec.describe 'Api::V1::Accounts::AutomationRulesController', type: :request do
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
expect(account.automation_rules.count).to eq(1) expect(account.automation_rules.count).to eq(1)
end end
it 'Saves file in the automation actions to send an attachments' do
file = fixture_file_upload(Rails.root.join('spec/assets/avatar.png'), 'image/png')
params[:attachments] = [file]
params[:actions] = [
{
action_name: :send_message,
action_params: ['Welcome to the chatwoot platform.']
},
{
action_name: :update_additional_attributes,
action_params: [{ intiated_at: '2021-12-03 17:25:26.844536 +0530' }]
},
{
action_name: :send_attachments
}
]
expect(account.automation_rules.count).to eq(0)
post "/api/v1/accounts/#{account.id}/automation_rules",
headers: administrator.create_new_auth_token,
params: params
expect(response).to have_http_status(:success)
expect(account.automation_rules.count).to eq(1)
automation_rule = account.automation_rules.first
expect(automation_rule.files.presence).to be_truthy
expect(automation_rule.files.count).to eq(1)
end
it 'Saves files in the automation actions to send multiple attachments' do
file_1 = fixture_file_upload(Rails.root.join('spec/assets/avatar.png'), 'image/png')
file_2 = fixture_file_upload(Rails.root.join('spec/assets/sample.pdf'), 'image/png')
params[:attachments] = [file_1, file_2]
params[:actions] = [
{
action_name: :send_message,
action_params: ['Welcome to the chatwoot platform.']
},
{
action_name: :update_additional_attributes,
action_params: [{ intiated_at: '2021-12-03 17:25:26.844536 +0530' }]
},
{
action_name: :send_attachments
}
]
expect(account.automation_rules.count).to eq(0)
post "/api/v1/accounts/#{account.id}/automation_rules",
headers: administrator.create_new_auth_token,
params: params
expect(response).to have_http_status(:success)
expect(account.automation_rules.count).to eq(1)
automation_rule = account.automation_rules.first
expect(automation_rule.files.presence).to be_truthy
expect(automation_rule.files.count).to eq(2)
end
end end
end end

View File

@@ -42,8 +42,12 @@ describe AutomationRuleListener do
{ 'action_name' => 'send_email_transcript', 'action_params' => 'new_agent@example.com' }, { 'action_name' => 'send_email_transcript', 'action_params' => 'new_agent@example.com' },
{ 'action_name' => 'mute_conversation', 'action_params' => nil }, { 'action_name' => 'mute_conversation', 'action_params' => nil },
{ 'action_name' => 'change_status', 'action_params' => ['snoozed'] }, { 'action_name' => 'change_status', 'action_params' => ['snoozed'] },
{ 'action_name' => 'send_message', 'action_params' => ['Send this message.'] } { 'action_name' => 'send_message', 'action_params' => ['Send this message.'] },
{ 'action_name' => 'send_attachments' }
]) ])
file = fixture_file_upload(Rails.root.join('spec/assets/avatar.png'), 'image/png')
automation_rule.files.attach(file)
automation_rule.save
end end
describe '#conversation_status_changed' do describe '#conversation_status_changed' do
@@ -112,7 +116,7 @@ describe AutomationRuleListener do
conversation.reload conversation.reload
expect(conversation.messages.last.content).to eq('Send this message.') expect(conversation.messages.first.content).to eq('Send this message.')
end end
it 'triggers automation rule changes status to snoozed' do it 'triggers automation rule changes status to snoozed' do
@@ -150,6 +154,18 @@ describe AutomationRuleListener do
listener.conversation_status_changed(event) listener.conversation_status_changed(event)
end end
it 'triggers automation rule send attachments in messages' do
automation_rule
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
listener.conversation_status_changed(event)
conversation.reload
expect(conversation.messages.last.attachments.count).to eq(1)
end
end end
end end
@@ -225,7 +241,7 @@ describe AutomationRuleListener do
conversation.reload conversation.reload
expect(conversation.messages.last.content).to eq('Send this message.') expect(conversation.messages.first.content).to eq('Send this message.')
end end
it 'triggers automation_rule with contact standard attributes' do it 'triggers automation_rule with contact standard attributes' do
@@ -333,7 +349,7 @@ describe AutomationRuleListener do
conversation.reload conversation.reload
expect(conversation.messages.last.content).to eq('Send this message.') expect(conversation.messages.first.content).to eq('Send this message.')
end end
end end
end end