Automation enhancement (#4087)
This commit is contained in:
parent
c608ca37e0
commit
e06a6a7c55
17 changed files with 275 additions and 60 deletions
2
Gemfile
2
Gemfile
|
@ -42,7 +42,7 @@ gem 'down', '~> 5.0'
|
||||||
gem 'aws-sdk-s3', require: false
|
gem 'aws-sdk-s3', require: false
|
||||||
gem 'azure-storage-blob', require: false
|
gem 'azure-storage-blob', require: false
|
||||||
gem 'google-cloud-storage', require: false
|
gem 'google-cloud-storage', require: false
|
||||||
gem 'image_processing'
|
gem 'image_processing', '~> 1.12.2'
|
||||||
|
|
||||||
##-- gems for database --#
|
##-- gems for database --#
|
||||||
gem 'groupdate'
|
gem 'groupdate'
|
||||||
|
|
|
@ -688,7 +688,7 @@ DEPENDENCIES
|
||||||
hairtrigger
|
hairtrigger
|
||||||
hashie
|
hashie
|
||||||
html2text
|
html2text
|
||||||
image_processing
|
image_processing (~> 1.12.2)
|
||||||
jbuilder
|
jbuilder
|
||||||
json_refs
|
json_refs
|
||||||
json_schemer
|
json_schemer
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont
|
||||||
params.permit(
|
params.permit(
|
||||||
:name, :description, :event_name, :account_id, :active,
|
:name, :description, :event_name, :account_id, :active,
|
||||||
conditions: [:attribute_key, :filter_operator, :query_operator, { values: [] }],
|
conditions: [:attribute_key, :filter_operator, :query_operator, { values: [] }],
|
||||||
actions: [:action_name, { action_params: [] }]
|
actions: [:action_name, { action_params: [{}] }]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ export const AUTOMATIONS = {
|
||||||
// {
|
// {
|
||||||
// key: 'send_email_to_team',
|
// key: 'send_email_to_team',
|
||||||
// name: 'Send an email to team',
|
// name: 'Send an email to team',
|
||||||
// attributeI18nKey: 'SEND_MESSAGE',
|
// attributeI18nKey: 'SEND_EMAIL_TO_TEAM',
|
||||||
// },
|
// },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -186,7 +186,7 @@ export const AUTOMATIONS = {
|
||||||
// {
|
// {
|
||||||
// key: 'send_email_to_team',
|
// key: 'send_email_to_team',
|
||||||
// name: 'Send an email to team',
|
// name: 'Send an email to team',
|
||||||
// attributeI18nKey: 'SEND_MESSAGE',
|
// attributeI18nKey: 'SEND_EMAIL_TO_TEAM',
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
key: 'assign_agent',
|
key: 'assign_agent',
|
||||||
|
|
|
@ -1,51 +1,58 @@
|
||||||
class AutomationRuleListener < BaseListener
|
class AutomationRuleListener < BaseListener
|
||||||
def conversation_updated(event_obj)
|
def conversation_updated(event_obj)
|
||||||
conversation = event_obj.data[:conversation]
|
conversation = event_obj.data[:conversation]
|
||||||
return unless rule_present?('conversation_updated', conversation)
|
account = conversation.account
|
||||||
|
|
||||||
|
return unless rule_present?('conversation_updated', account)
|
||||||
|
|
||||||
@rules.each do |rule|
|
@rules.each do |rule|
|
||||||
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
|
||||||
AutomationRules::ActionService.new(rule, conversation).perform if conditions_match.present?
|
AutomationRules::ActionService.new(rule, account, conversation).perform if conditions_match.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def conversation_status_changed(event_obj)
|
def conversation_status_changed(event_obj)
|
||||||
conversation = event_obj.data[:conversation]
|
conversation = event_obj.data[:conversation]
|
||||||
return unless rule_present?('conversation_status_changed', conversation)
|
account = conversation.account
|
||||||
|
|
||||||
|
return unless rule_present?('conversation_status_changed', account)
|
||||||
|
|
||||||
@rules.each do |rule|
|
@rules.each do |rule|
|
||||||
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
|
||||||
AutomationRules::ActionService.new(rule, conversation).perform if conditions_match.present?
|
AutomationRules::ActionService.new(rule, account, conversation).perform if conditions_match.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def conversation_created(event_obj)
|
def conversation_created(event_obj)
|
||||||
conversation = event_obj.data[:conversation]
|
conversation = event_obj.data[:conversation]
|
||||||
return unless rule_present?('conversation_created', conversation)
|
account = conversation.account
|
||||||
|
|
||||||
|
return unless rule_present?('conversation_created', account)
|
||||||
|
|
||||||
@rules.each do |rule|
|
@rules.each do |rule|
|
||||||
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).perform
|
||||||
::AutomationRules::ActionService.new(rule, conversation).perform if conditions_match.present?
|
::AutomationRules::ActionService.new(rule, account, conversation).perform if conditions_match.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def message_created(event_obj)
|
def message_created(event_obj)
|
||||||
message = event_obj.data[:message]
|
message = event_obj.data[:message]
|
||||||
conversation = message.conversation
|
account = message.try(:account)
|
||||||
return unless rule_present?('message_created', conversation)
|
|
||||||
|
return unless rule_present?('message_created', account)
|
||||||
|
|
||||||
@rules.each do |rule|
|
@rules.each do |rule|
|
||||||
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, conversation).message_conditions(message)
|
conditions_match = ::AutomationRules::ConditionsFilterService.new(rule, message.conversation).message_conditions
|
||||||
::AutomationRules::ActionService.new(rule, conversation).perform if conditions_match.present?
|
::AutomationRules::ActionService.new(rule, account, message.conversation).perform if conditions_match.present?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def rule_present?(event_name, conversation)
|
def rule_present?(event_name, account)
|
||||||
return if conversation.blank?
|
return if account.blank?
|
||||||
|
|
||||||
@rules = AutomationRule.where(
|
@rules = AutomationRule.where(
|
||||||
event_name: event_name,
|
event_name: event_name,
|
||||||
account_id: conversation.account_id,
|
account_id: account.id,
|
||||||
active: true
|
active: true
|
||||||
)
|
)
|
||||||
@rules.any?
|
@rules.any?
|
||||||
|
|
|
@ -4,50 +4,57 @@ class TeamNotifications::AutomationNotificationMailer < ApplicationMailer
|
||||||
|
|
||||||
@agents = team.team_members
|
@agents = team.team_members
|
||||||
@conversation = conversation
|
@conversation = conversation
|
||||||
@message = message
|
@custom_message = message
|
||||||
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
|
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
|
||||||
|
|
||||||
send_an_email_to_team
|
send_an_email_to_team and return
|
||||||
end
|
end
|
||||||
|
|
||||||
def conversation_updated(conversation, team)
|
def conversation_updated(conversation, team, message)
|
||||||
return unless smtp_config_set_or_development?
|
return unless smtp_config_set_or_development?
|
||||||
|
|
||||||
@agents = team.team_members
|
@agents = team.team_members
|
||||||
@conversation = conversation
|
@conversation = conversation
|
||||||
@message = message
|
@custom_message = message
|
||||||
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
|
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
|
||||||
|
|
||||||
send_an_email_to_team
|
send_an_email_to_team and return
|
||||||
end
|
end
|
||||||
|
|
||||||
def message_created(message, agent)
|
def message_created(conversation, team, message)
|
||||||
return unless smtp_config_set_or_development?
|
return unless smtp_config_set_or_development?
|
||||||
|
|
||||||
@agent = agent
|
@agents = team.team_members
|
||||||
@conversation = message.conversation
|
@conversation = conversation
|
||||||
@message = message
|
@custom_message = message
|
||||||
subject = "#{@agent.available_name}, You have been mentioned in conversation [ID - #{@conversation.display_id}]"
|
|
||||||
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
|
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
|
||||||
send_mail_with_liquid(to: @agent.email, subject: subject)
|
|
||||||
|
send_an_email_to_team and return
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def send_an_email_to_team
|
def send_an_email_to_team
|
||||||
@agents.each do |agent|
|
@agents.each do |agent|
|
||||||
subject = "#{@agent.available_name}, A new conversation [ID - #{@conversation.display_id}] has been created in #{@conversation.inbox&.name}."
|
subject = "#{agent.user.available_name}, This email has been sent via automation rule actions."
|
||||||
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
|
@action_url = app_account_conversation_url(account_id: @conversation.account_id, id: @conversation.display_id)
|
||||||
send_mail_with_liquid(to: agent.email, subject: subject)
|
@agent = agent
|
||||||
|
|
||||||
|
send_mail_with_liquid(to: @agent.user.email, subject: subject)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def liquid_droppables
|
def liquid_droppables
|
||||||
super.merge({
|
super.merge!({
|
||||||
user: @agent,
|
user: @agent.user,
|
||||||
conversation: @conversation,
|
conversation: @conversation,
|
||||||
inbox: @conversation.inbox,
|
inbox: @conversation.inbox
|
||||||
message: @message
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def liquid_locals
|
||||||
|
super.merge!({
|
||||||
|
custom_message: @custom_message
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
class AutomationRule < ApplicationRecord
|
class AutomationRule < ApplicationRecord
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
|
|
||||||
validates :account, presence: true
|
|
||||||
validate :json_conditions_format
|
validate :json_conditions_format
|
||||||
validate :json_actions_format
|
validate :json_actions_format
|
||||||
|
validates :account_id, presence: true
|
||||||
|
|
||||||
scope :active, -> { where(active: true) }
|
scope :active, -> { where(active: true) }
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,8 @@ class Conversation < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def dispatcher_dispatch(event_name)
|
def dispatcher_dispatch(event_name)
|
||||||
|
return if Current.executed_by.present? && Current.executed_by.instance_of?(AutomationRule)
|
||||||
|
|
||||||
Rails.configuration.dispatcher.dispatch(event_name, Time.zone.now, conversation: self, notifiable_assignee_change: notifiable_assignee_change?)
|
Rails.configuration.dispatcher.dispatch(event_name, Time.zone.now, conversation: self, notifiable_assignee_change: notifiable_assignee_change?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,8 @@ class Message < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def dispatch_create_events
|
def dispatch_create_events
|
||||||
|
return if Current.executed_by.present? && Current.executed_by.instance_of?(AutomationRule)
|
||||||
|
|
||||||
Rails.configuration.dispatcher.dispatch(MESSAGE_CREATED, Time.zone.now, message: self)
|
Rails.configuration.dispatcher.dispatch(MESSAGE_CREATED, Time.zone.now, message: self)
|
||||||
|
|
||||||
if outgoing? && conversation.messages.outgoing.count == 1
|
if outgoing? && conversation.messages.outgoing.count == 1
|
||||||
|
@ -174,6 +176,8 @@ class Message < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def dispatch_update_event
|
def dispatch_update_event
|
||||||
|
return if Current.executed_by.present? && Current.executed_by.instance_of?(AutomationRule)
|
||||||
|
|
||||||
Rails.configuration.dispatcher.dispatch(MESSAGE_UPDATED, Time.zone.now, message: self)
|
Rails.configuration.dispatcher.dispatch(MESSAGE_UPDATED, Time.zone.now, message: self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,40 +1,68 @@
|
||||||
class AutomationRules::ActionService
|
class AutomationRules::ActionService
|
||||||
def initialize(rule, conversation)
|
def initialize(rule, account, conversation)
|
||||||
@rule = rule
|
@rule = rule
|
||||||
|
@account = account
|
||||||
@conversation = conversation
|
@conversation = conversation
|
||||||
@account = @conversation.account
|
Current.executed_by = rule
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
@rule.actions.each do |action, _current_index|
|
@rule.actions.each do |action|
|
||||||
action = action.with_indifferent_access
|
action = action.with_indifferent_access
|
||||||
|
begin
|
||||||
send(action[:action_name], action[:action_params])
|
send(action[:action_name], action[:action_params])
|
||||||
|
rescue StandardError => e
|
||||||
|
Sentry.capture_exception(e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
ensure
|
||||||
|
Current.reset
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def send_email_transcript(email)
|
||||||
|
ConversationReplyMailer.with(account: conversation.account).conversation_transcript(@conversation, email)&.deliver_later
|
||||||
|
end
|
||||||
|
|
||||||
|
def mute_conversation(_params)
|
||||||
|
@conversation.mute!
|
||||||
|
end
|
||||||
|
|
||||||
|
def change_status(status)
|
||||||
|
@conversation.update!(status: status[0])
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_webhook_events(webhook_url)
|
||||||
|
payload = @conversation.webhook_data.merge(event: "automation_event: #{@rule.event_name}")
|
||||||
|
WebhookJob.perform_later(webhook_url, payload)
|
||||||
|
end
|
||||||
|
|
||||||
def send_message(message)
|
def send_message(message)
|
||||||
# params = { content: message, private: false }
|
return if @rule.event_name == 'message_created'
|
||||||
# mb = Messages::MessageBuilder.new(@administrator, @conversation, params)
|
|
||||||
# mb.perform
|
params = { content: message[0], private: false }
|
||||||
|
mb = Messages::MessageBuilder.new(@administrator, @conversation, params)
|
||||||
|
mb.perform
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_team(team_ids = [])
|
def assign_team(team_ids = [])
|
||||||
return unless team_belongs_to_account?(team_ids)
|
return unless team_belongs_to_account?(team_ids)
|
||||||
|
|
||||||
@account.teams.find_by(id: team_ids)
|
|
||||||
@conversation.update!(team_id: team_ids[0])
|
@conversation.update!(team_id: team_ids[0])
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_best_agents(agent_ids = [])
|
def assign_best_agent(agent_ids = [])
|
||||||
return unless agent_belongs_to_account?(agent_ids)
|
return unless agent_belongs_to_account?(agent_ids)
|
||||||
|
|
||||||
@agent = @account.users.find_by(id: agent_ids)
|
@agent = @account.users.find_by(id: agent_ids)
|
||||||
@conversation.update_assignee(@agent)
|
|
||||||
|
@conversation.update!(assignee_id: @agent.id) if @agent.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_label(labels = [])
|
def add_label(labels)
|
||||||
|
return if labels.empty?
|
||||||
|
|
||||||
@conversation.add_labels(labels)
|
@conversation.add_labels(labels)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -43,11 +71,11 @@ class AutomationRules::ActionService
|
||||||
|
|
||||||
case @rule.event_name
|
case @rule.event_name
|
||||||
when 'conversation_created', 'conversation_status_changed'
|
when 'conversation_created', 'conversation_status_changed'
|
||||||
TeamNotifications::AutomationNotificationMailer.conversation_creation(@conversation, team, params[:message])
|
TeamNotifications::AutomationNotificationMailer.conversation_creation(@conversation, team, params[:message])&.deliver_now
|
||||||
when 'conversation_updated'
|
when 'conversation_updated'
|
||||||
TeamNotifications::AutomationNotificationMailer.conversation_updated(@conversation, team, params[:message])
|
TeamNotifications::AutomationNotificationMailer.conversation_updated(@conversation, team, params[:message])&.deliver_now
|
||||||
when 'message_created'
|
when 'message_created'
|
||||||
TeamNotifications::AutomationNotificationMailer.message_created(@conversation, team, params[:message])
|
TeamNotifications::AutomationNotificationMailer.message_created(@conversation, team, params[:message])&.deliver_now
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require 'json'
|
require 'json'
|
||||||
|
|
||||||
class AutomationRules::ConditionsFilterService < FilterService
|
class AutomationRules::ConditionsFilterService < FilterService
|
||||||
def initialize(rule, conversation)
|
def initialize(rule, conversation = nil)
|
||||||
super([], nil)
|
super([], nil)
|
||||||
@rule = rule
|
@rule = rule
|
||||||
@conversation = conversation
|
@conversation = conversation
|
||||||
|
@ -21,14 +21,14 @@ class AutomationRules::ConditionsFilterService < FilterService
|
||||||
records.any?
|
records.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
def message_conditions(message)
|
def message_conditions
|
||||||
message_filters = @filters['messages']
|
message_filters = @filters['messages']
|
||||||
|
|
||||||
@rule.conditions.each_with_index do |query_hash, current_index|
|
@rule.conditions.each_with_index do |query_hash, current_index|
|
||||||
current_filter = message_filters[query_hash['attribute_key']]
|
current_filter = message_filters[query_hash['attribute_key']]
|
||||||
@query_string += message_query_string(current_filter, query_hash.with_indifferent_access, current_index)
|
@query_string += message_query_string(current_filter, query_hash.with_indifferent_access, current_index)
|
||||||
end
|
end
|
||||||
records = Message.where(id: message.id).where(@query_string, @filter_values.with_indifferent_access)
|
records = Message.where(conversation: @conversation).where(@query_string, @filter_values.with_indifferent_access)
|
||||||
records.any?
|
records.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -44,6 +44,19 @@ class AutomationRules::ConditionsFilterService < FilterService
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This will be used in future for contact automation rule
|
||||||
|
def contact_conditions(_contact)
|
||||||
|
conversation_filters = @filters['conversations']
|
||||||
|
|
||||||
|
@rule.conditions.each_with_index do |query_hash, current_index|
|
||||||
|
current_filter = conversation_filters[query_hash['attribute_key']]
|
||||||
|
@query_string += conversation_query_string(current_filter, query_hash.with_indifferent_access, current_index)
|
||||||
|
end
|
||||||
|
|
||||||
|
records = base_relation.where(@query_string, @filter_values.with_indifferent_access)
|
||||||
|
records.any?
|
||||||
|
end
|
||||||
|
|
||||||
def conversation_query_string(current_filter, query_hash, current_index)
|
def conversation_query_string(current_filter, query_hash, current_index)
|
||||||
attribute_key = query_hash['attribute_key']
|
attribute_key = query_hash['attribute_key']
|
||||||
query_operator = query_hash['query_operator']
|
query_operator = query_hash['query_operator']
|
||||||
|
@ -63,6 +76,6 @@ class AutomationRules::ConditionsFilterService < FilterService
|
||||||
end
|
end
|
||||||
|
|
||||||
def base_relation
|
def base_relation
|
||||||
Conversation.where(id: @conversation)
|
Conversation.where(id: @conversation.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<p>Hi {{user.available_name}}</p>
|
<p>Hi {{user.available_name}}</p>
|
||||||
|
|
||||||
|
|
||||||
<p>Time to save the world. A new conversation has been created in {{ inbox.name }}</p>
|
<p>{{ custom_message }}</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Click <a href="{{ action_url }}">here</a> to get cracking.
|
Click <a href="{{ action_url }}">here</a> to get cracking.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<p>Hi {{user.available_name}}</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>{{ custom_message }}</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Click <a href="{{ action_url }}">here</a> to get cracking.
|
||||||
|
</p>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<p>Hi {{user.available_name}}</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>{{ custom_message }}</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Click <a href="{{ action_url }}">here</a> to get cracking.
|
||||||
|
</p>
|
|
@ -2,12 +2,14 @@ module Current
|
||||||
thread_mattr_accessor :user
|
thread_mattr_accessor :user
|
||||||
thread_mattr_accessor :account
|
thread_mattr_accessor :account
|
||||||
thread_mattr_accessor :account_user
|
thread_mattr_accessor :account_user
|
||||||
|
thread_mattr_accessor :executed_by
|
||||||
thread_mattr_accessor :contact
|
thread_mattr_accessor :contact
|
||||||
|
|
||||||
def self.reset
|
def self.reset
|
||||||
Current.user = nil
|
Current.user = nil
|
||||||
Current.account = nil
|
Current.account = nil
|
||||||
Current.account_user = nil
|
Current.account_user = nil
|
||||||
|
Current.executed_by = nil
|
||||||
Current.contact = nil
|
Current.contact = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,16 +31,36 @@ describe AutomationRuleListener do
|
||||||
},
|
},
|
||||||
{ 'action_name' => 'assign_team', 'action_params' => [team.id] },
|
{ 'action_name' => 'assign_team', 'action_params' => [team.id] },
|
||||||
{ 'action_name' => 'add_label', 'action_params' => %w[support priority_customer] },
|
{ 'action_name' => 'add_label', 'action_params' => %w[support priority_customer] },
|
||||||
{ 'action_name' => 'assign_best_agents', 'action_params' => [user_1.id] }
|
{ 'action_name' => 'send_webhook_events', 'action_params' => 'https://www.example.com' },
|
||||||
|
{ 'action_name' => 'assign_best_agent', 'action_params' => [user_1.id] },
|
||||||
|
{ '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.'] }
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#conversation_status_changed' do
|
describe '#conversation_status_changed' do
|
||||||
context 'when rule matches' do
|
context 'when rule matches' do
|
||||||
|
it 'triggers automation rule send webhook events' do
|
||||||
|
payload = conversation.webhook_data.merge(event: "automation_event: #{automation_rule.event_name}")
|
||||||
|
|
||||||
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
|
||||||
|
|
||||||
|
expect(WebhookJob).to receive(:perform_later).with('https://www.example.com', payload).once
|
||||||
|
|
||||||
|
listener.conversation_status_changed(event)
|
||||||
|
end
|
||||||
|
|
||||||
it 'triggers automation rule to assign team' do
|
it 'triggers automation rule to assign team' do
|
||||||
expect(conversation.team_id).not_to eq(team.id)
|
expect(conversation.team_id).not_to eq(team.id)
|
||||||
|
|
||||||
automation_rule
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
|
||||||
|
|
||||||
listener.conversation_status_changed(event)
|
listener.conversation_status_changed(event)
|
||||||
|
|
||||||
conversation.reload
|
conversation.reload
|
||||||
|
@ -51,6 +71,9 @@ describe AutomationRuleListener do
|
||||||
expect(conversation.labels).to eq([])
|
expect(conversation.labels).to eq([])
|
||||||
|
|
||||||
automation_rule
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
|
||||||
|
|
||||||
listener.conversation_status_changed(event)
|
listener.conversation_status_changed(event)
|
||||||
|
|
||||||
conversation.reload
|
conversation.reload
|
||||||
|
@ -61,12 +84,65 @@ describe AutomationRuleListener do
|
||||||
expect(conversation.assignee).to be_nil
|
expect(conversation.assignee).to be_nil
|
||||||
|
|
||||||
automation_rule
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
|
||||||
|
|
||||||
listener.conversation_status_changed(event)
|
listener.conversation_status_changed(event)
|
||||||
|
|
||||||
conversation.reload
|
conversation.reload
|
||||||
|
|
||||||
expect(conversation.assignee).to eq(user_1)
|
expect(conversation.assignee).to eq(user_1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'triggers automation rule send message to the contacts' do
|
||||||
|
expect(conversation.messages).to be_empty
|
||||||
|
|
||||||
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
|
||||||
|
|
||||||
|
listener.conversation_status_changed(event)
|
||||||
|
|
||||||
|
conversation.reload
|
||||||
|
|
||||||
|
expect(conversation.messages.last.content).to eq('Send this message.')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'triggers automation rule changes status to snoozed' do
|
||||||
|
expect(conversation.status).to eq('resolved')
|
||||||
|
|
||||||
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
|
||||||
|
|
||||||
|
listener.conversation_status_changed(event)
|
||||||
|
|
||||||
|
conversation.reload
|
||||||
|
|
||||||
|
expect(conversation.status).to eq('snoozed')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'triggers automation rule send email transcript to the mentioned email' do
|
||||||
|
mailer = double
|
||||||
|
|
||||||
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
|
||||||
|
|
||||||
|
listener.conversation_status_changed(event)
|
||||||
|
|
||||||
|
conversation.reload
|
||||||
|
|
||||||
|
allow(mailer).to receive(:conversation_transcript)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'triggers automation rule send email to the team' do
|
||||||
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_creation)
|
||||||
|
|
||||||
|
listener.conversation_status_changed(event)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -114,6 +190,42 @@ describe AutomationRuleListener do
|
||||||
|
|
||||||
expect(conversation.assignee).to eq(user_1)
|
expect(conversation.assignee).to eq(user_1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'triggers automation rule send email transcript to the mentioned email' do
|
||||||
|
mailer = double
|
||||||
|
|
||||||
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated)
|
||||||
|
|
||||||
|
listener.conversation_updated(event)
|
||||||
|
|
||||||
|
conversation.reload
|
||||||
|
|
||||||
|
allow(mailer).to receive(:conversation_transcript)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'triggers automation rule send email to the team' do
|
||||||
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated)
|
||||||
|
|
||||||
|
listener.conversation_updated(event)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'triggers automation rule send message to the contacts' do
|
||||||
|
expect(conversation.messages).to be_empty
|
||||||
|
|
||||||
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:conversation_updated)
|
||||||
|
|
||||||
|
listener.conversation_updated(event)
|
||||||
|
|
||||||
|
conversation.reload
|
||||||
|
|
||||||
|
expect(conversation.messages.last.content).to eq('Send this message.')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -137,6 +249,9 @@ describe AutomationRuleListener do
|
||||||
expect(conversation.team_id).not_to eq(team.id)
|
expect(conversation.team_id).not_to eq(team.id)
|
||||||
|
|
||||||
automation_rule
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created)
|
||||||
|
|
||||||
listener.message_created(event)
|
listener.message_created(event)
|
||||||
|
|
||||||
conversation.reload
|
conversation.reload
|
||||||
|
@ -147,22 +262,41 @@ describe AutomationRuleListener do
|
||||||
expect(conversation.labels).to eq([])
|
expect(conversation.labels).to eq([])
|
||||||
|
|
||||||
automation_rule
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created)
|
||||||
|
|
||||||
listener.message_created(event)
|
listener.message_created(event)
|
||||||
|
|
||||||
conversation.reload
|
conversation.reload
|
||||||
expect(conversation.labels.pluck(:name)).to eq(%w[support priority_customer])
|
expect(conversation.labels.pluck(:name)).to eq(%w[support priority_customer])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'triggers automation rule to assign best agents' do
|
it 'triggers automation rule to assign best agent' do
|
||||||
expect(conversation.assignee).to be_nil
|
expect(conversation.assignee).to be_nil
|
||||||
|
|
||||||
automation_rule
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created)
|
||||||
|
|
||||||
listener.message_created(event)
|
listener.message_created(event)
|
||||||
|
|
||||||
conversation.reload
|
conversation.reload
|
||||||
|
|
||||||
expect(conversation.assignee).to eq(user_1)
|
expect(conversation.assignee).to eq(user_1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'triggers automation rule send email transcript to the mentioned email' do
|
||||||
|
mailer = double
|
||||||
|
|
||||||
|
automation_rule
|
||||||
|
|
||||||
|
expect(TeamNotifications::AutomationNotificationMailer).to receive(:message_created)
|
||||||
|
|
||||||
|
listener.message_created(event)
|
||||||
|
|
||||||
|
conversation.reload
|
||||||
|
|
||||||
|
allow(mailer).to receive(:conversation_transcript)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,11 +2,13 @@ require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe AutomationRule, type: :model do
|
RSpec.describe AutomationRule, type: :model do
|
||||||
describe 'associations' do
|
describe 'associations' do
|
||||||
|
let(:account) { create(:account) }
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{
|
{
|
||||||
name: 'Notify Conversation Created and mark priority query',
|
name: 'Notify Conversation Created and mark priority query',
|
||||||
description: 'Notify all administrator about conversation created and mark priority query',
|
description: 'Notify all administrator about conversation created and mark priority query',
|
||||||
event_name: 'conversation_created',
|
event_name: 'conversation_created',
|
||||||
|
account_id: account.id,
|
||||||
conditions: [
|
conditions: [
|
||||||
{
|
{
|
||||||
attribute_key: 'browser_language',
|
attribute_key: 'browser_language',
|
||||||
|
|
Loading…
Reference in a new issue