Feat: attachments automation (#4266)
This commit is contained in:
@@ -7,14 +7,22 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont
|
||||
end
|
||||
|
||||
def create
|
||||
@automation_rule = Current.account.automation_rules.create(automation_rules_permit)
|
||||
@automation_rule.update(actions: params[:actions])
|
||||
@automation_rule = Current.account.automation_rules.new(automation_rules_permit)
|
||||
@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
|
||||
|
||||
def show; end
|
||||
|
||||
def update
|
||||
@automation_rule.update(automation_rules_permit)
|
||||
process_attachments
|
||||
@automation_rule
|
||||
end
|
||||
|
||||
def destroy
|
||||
@@ -31,6 +39,14 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont
|
||||
|
||||
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
|
||||
params.permit(
|
||||
:name, :description, :event_name, :account_id, :active,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#
|
||||
class AutomationRule < ApplicationRecord
|
||||
belongs_to :account
|
||||
has_many_attached :files
|
||||
|
||||
validate :json_conditions_format
|
||||
validate :json_actions_format
|
||||
@@ -26,8 +27,8 @@ class AutomationRule < ApplicationRecord
|
||||
|
||||
scope :active, -> { where(active: true) }
|
||||
|
||||
CONDITIONS_ATTRS = %w[country_code status browser_language assignee_id team_id referer].freeze
|
||||
ACTIONS_ATTRS = %w[send_message add_label send_email_to_team assign_team assign_best_agents].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 send_attachments].freeze
|
||||
|
||||
private
|
||||
|
||||
@@ -35,13 +36,17 @@ class AutomationRule < ApplicationRecord
|
||||
return if conditions.nil?
|
||||
|
||||
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
|
||||
|
||||
def json_actions_format
|
||||
return if actions.nil?
|
||||
|
||||
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
|
||||
|
||||
@@ -21,6 +21,15 @@ class AutomationRules::ActionService
|
||||
|
||||
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)
|
||||
emails.each do |email|
|
||||
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'
|
||||
|
||||
params = { content: message[0], private: false }
|
||||
mb = Messages::MessageBuilder.new(@administrator, @conversation, params)
|
||||
mb = Messages::MessageBuilder.new(nil, @conversation, params)
|
||||
mb.perform
|
||||
end
|
||||
|
||||
@@ -85,10 +94,6 @@ class AutomationRules::ActionService
|
||||
end
|
||||
end
|
||||
|
||||
def administrator
|
||||
@administrator ||= @account.administrators.first
|
||||
end
|
||||
|
||||
def agent_belongs_to_account?(agent_ids)
|
||||
@account.agents.pluck(:id).include?(agent_ids[0])
|
||||
end
|
||||
|
||||
@@ -84,6 +84,23 @@ RSpec.describe 'Api::V1::Accounts::AutomationRulesController', type: :request do
|
||||
}.with_indifferent_access
|
||||
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
|
||||
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(account.automation_rules.count).to eq(1)
|
||||
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
|
||||
|
||||
|
||||
@@ -42,8 +42,12 @@ describe AutomationRuleListener do
|
||||
{ 'action_name' => 'send_email_transcript', 'action_params' => 'new_agent@example.com' },
|
||||
{ 'action_name' => 'mute_conversation', 'action_params' => nil },
|
||||
{ '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
|
||||
|
||||
describe '#conversation_status_changed' do
|
||||
@@ -112,7 +116,7 @@ describe AutomationRuleListener do
|
||||
|
||||
conversation.reload
|
||||
|
||||
expect(conversation.messages.last.content).to eq('Send this message.')
|
||||
expect(conversation.messages.first.content).to eq('Send this message.')
|
||||
end
|
||||
|
||||
it 'triggers automation rule changes status to snoozed' do
|
||||
@@ -150,6 +154,18 @@ describe AutomationRuleListener do
|
||||
|
||||
listener.conversation_status_changed(event)
|
||||
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
|
||||
|
||||
@@ -225,7 +241,7 @@ describe AutomationRuleListener do
|
||||
|
||||
conversation.reload
|
||||
|
||||
expect(conversation.messages.last.content).to eq('Send this message.')
|
||||
expect(conversation.messages.first.content).to eq('Send this message.')
|
||||
end
|
||||
|
||||
it 'triggers automation_rule with contact standard attributes' do
|
||||
@@ -333,7 +349,7 @@ describe AutomationRuleListener do
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user