diff --git a/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee b/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee
index 0ab23151d..c7d2002e6 100644
--- a/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee
+++ b/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee
@@ -117,7 +117,7 @@ class App.UiElement.ticket_perform_action
element = @placeholder(item, attribute, params, groups, elements)
@rebuildAttributeSelectors(item, element, groupAndAttribute, elements, meta, attribute)
item.append(element)
-
+
@disableRemoveForOneAttribute(item)
item
@@ -348,20 +348,38 @@ class App.UiElement.ticket_perform_action
if !_.isArray(meta.recipient)
meta.recipient = [meta.recipient]
- column_select_options = []
+ columnSelectOptions = []
for key, value of options
selected = undefined
for recipient in meta.recipient
if key is recipient
selected = true
- column_select_options.push({ value: key, name: App.i18n.translateInline(value), selected: selected })
+ columnSelectOptions.push({ value: key, name: App.i18n.translateInline(value), selected: selected })
- column_select = new App.ColumnSelect
+ columnSelectRecipientUserOptions = []
+ for user in App.User.all()
+ key = "userid_#{user.id}"
+ selected = undefined
+ for recipient in meta.recipient
+ if key is recipient
+ selected = true
+ columnSelectRecipientUserOptions.push({ value: key, name: "#{user.firstname} #{user.lastname}", selected: selected })
+
+ columnSelectRecipient = new App.ColumnSelect
attribute:
name: "#{name}::recipient"
- options: column_select_options
+ options: [
+ {
+ label: 'Variables',
+ group: columnSelectOptions
+ },
+ {
+ label: 'User',
+ group: columnSelectRecipientUserOptions
+ },
+ ]
- selection = column_select.element()
+ selectionRecipient = columnSelectRecipient.element()
notificationElement = $( App.view('generic/ticket_perform_action/notification')(
attribute: attribute
@@ -369,7 +387,7 @@ class App.UiElement.ticket_perform_action
notificationType: notificationType
meta: meta || {}
))
- notificationElement.find('.js-recipient select').replaceWith(selection)
+ notificationElement.find('.js-recipient select').replaceWith(selectionRecipient)
visibilitySelection = App.UiElement.select.render(
name: "#{name}::internal"
diff --git a/app/assets/javascripts/app/views/generic/column_select.jst.eco b/app/assets/javascripts/app/views/generic/column_select.jst.eco
index 82a12872f..a5072fc3f 100644
--- a/app/assets/javascripts/app/views/generic/column_select.jst.eco
+++ b/app/assets/javascripts/app/views/generic/column_select.jst.eco
@@ -34,7 +34,7 @@
<% for option in @attribute.options: %>
<% if option.group != undefined: %>
-
<%= option.label %>
+
<%= @T(option.label) %>
<% for o in option.group: %>
<%= o.name %>
<% end %>
@@ -43,4 +43,4 @@
<% end %>
<% end %>
-
\ No newline at end of file
+
diff --git a/app/assets/javascripts/app/views/generic/ticket_perform_action/notification.jst.eco b/app/assets/javascripts/app/views/generic/ticket_perform_action/notification.jst.eco
index 82c99b5d9..4348ce1af 100644
--- a/app/assets/javascripts/app/views/generic/ticket_perform_action/notification.jst.eco
+++ b/app/assets/javascripts/app/views/generic/ticket_perform_action/notification.jst.eco
@@ -12,14 +12,6 @@
-
-
-
-
-
-
-
-
<% if @notificationType is 'email': %>
diff --git a/app/models/ticket.rb b/app/models/ticket.rb
index 0e165e21a..f2c8b3095 100644
--- a/app/models/ticket.rb
+++ b/app/models/ticket.rb
@@ -1340,6 +1340,13 @@ result
User.group_access(group_id, 'full').sort_by(&:login).each do |user|
recipients_raw.push(user.email)
end
+ elsif recipient =~ /\Auserid_(\d+)\z/
+ user = User.lookup(id: $1)
+ if !user
+ logger.warn "Can't find configured Trigger Email recipient User with ID '#{$1}'"
+ next
+ end
+ recipients_raw.push(user.email)
else
logger.error "Unknown email notification recipient '#{recipient}'"
next
@@ -1538,6 +1545,11 @@ result
owner_id
when 'ticket_agents'
User.group_access(group_id, 'full').sort_by(&:login)
+ when /\Auserid_(\d+)\z/
+ return $1 if User.exists?($1)
+
+ logger.warn "Can't find configured Trigger SMS recipient User with ID '#{$1}'"
+ nil
else
logger.error "Unknown sms notification recipient '#{recipient}'"
nil
@@ -1548,6 +1560,7 @@ result
Array(value['recipient'])
.each_with_object([]) { |recipient_type, sum| sum.concat(Array(sms_recipients_by_type(recipient_type, article))) }
.map { |user_or_id| User.lookup(id: user_or_id) }
+ .uniq(&:id)
.select { |user| user.mobile.present? }
end
diff --git a/public/assets/tests/form_extended.js b/public/assets/tests/form_extended.js
index badcce98e..8c652b0ce 100644
--- a/public/assets/tests/form_extended.js
+++ b/public/assets/tests/form_extended.js
@@ -727,7 +727,7 @@ test('form checks', function() {
internal: 'false'
},
},
- }
+ }
new App.ControllerForm({
el: el,
model: {
diff --git a/spec/models/trigger/sms_spec.rb b/spec/models/trigger/sms_spec.rb
index 86bdffc51..7fb9e2dce 100644
--- a/spec/models/trigger/sms_spec.rb
+++ b/spec/models/trigger/sms_spec.rb
@@ -61,5 +61,36 @@ RSpec.describe Trigger do
expect(triggered_article.body).to match(time_in_zone.strftime('%d.%m.%y'))
end
end
+
+ context 'recipients' do
+
+ let(:recipient1) { create(:agent_user, mobile: '+37061010000', groups: [ticket_group]) }
+ let(:recipient2) { create(:agent_user, mobile: '+37061010001', groups: [ticket_group]) }
+ let(:recipient3) { create(:agent_user, mobile: '+37061010002', groups: [ticket_group]) }
+
+ let(:ticket_group) { create(:group) }
+
+ let(:ticket) do
+ ticket = create(:ticket, group: ticket_group, created_by_id: create(:agent_user).id)
+ Observer::Transaction.commit
+ ticket
+ end
+
+ before do
+ create(:channel, area: 'Sms::Notification')
+ create(:trigger,
+ disable_notification: false,
+ perform: {
+ 'notification.sms': {
+ recipient: ['ticket_agents', "userid_#{recipient1.id}", "userid_#{recipient2.id}", "userid_#{recipient3.id}"],
+ body: 'Hello World!',
+ }
+ })
+ end
+
+ it 'contains no duplicates' do
+ expect(ticket.articles.last.preferences['sms_recipients'].sort).to eq([recipient1.mobile, recipient2.mobile, recipient3.mobile].sort)
+ end
+ end
end
end
diff --git a/spec/models/trigger_spec.rb b/spec/models/trigger_spec.rb
index f3b075347..5f01c9823 100644
--- a/spec/models/trigger_spec.rb
+++ b/spec/models/trigger_spec.rb
@@ -6,6 +6,35 @@ RSpec.describe Trigger, type: :model do
it_behaves_like 'ApplicationModel', can_assets: { selectors: %i[condition perform] }
+ describe 'validation' do
+
+ let(:condition) do
+ { 'ticket.action' => { 'operator' => 'is', 'value' => 'create' } }
+ end
+ let(:perform) do
+ { 'ticket.title' => { 'value'=>'triggered' } }
+ end
+
+ context 'notification.email' do
+ context 'missing recipient' do
+
+ let(:perform) do
+ {
+ 'notification.email' => {
+ 'subject' => 'Hello',
+ 'body' => 'World!'
+ }
+ }
+ end
+
+ it 'raises an error' do
+ expect { trigger.save! }.to raise_error(Exceptions::UnprocessableEntity, 'Invalid perform notification.email, recipient is missing!')
+ end
+ end
+ end
+
+ end
+
describe 'Send-email triggers' do
before do
described_class.destroy_all # Default DB state includes three sample triggers
@@ -87,6 +116,57 @@ RSpec.describe Trigger, type: :model do
)
end
end
+
+ context 'notification.email recipient' do
+ let!(:ticket) { create(:ticket) }
+ let!(:recipient1) { create(:user, email: 'test1@zammad-test.com') }
+ let!(:recipient2) { create(:user, email: 'test2@zammad-test.com') }
+ let!(:recipient3) { create(:user, email: 'test3@zammad-test.com') }
+
+ let(:perform) do
+ {
+ 'notification.email' => {
+ 'recipient' => recipient,
+ 'subject' => 'Hello',
+ 'body' => 'World!'
+ }
+ }
+ end
+
+ before { Observer::Transaction.commit }
+
+ context 'mix of recipient group keyword and single recipient users' do
+ let(:recipient) { [ 'ticket_customer', "userid_#{recipient1.id}", "userid_#{recipient2.id}", "userid_#{recipient3.id}" ] }
+
+ it 'contains all recipients' do
+ expect(ticket.articles.last.to).to eq("#{ticket.customer.email}, #{recipient1.email}, #{recipient2.email}, #{recipient3.email}")
+ end
+
+ context 'duplicate recipient' do
+ let(:recipient) { [ 'ticket_customer', "userid_#{ticket.customer.id}" ] }
+
+ it 'contains only one recipient' do
+ expect(ticket.articles.last.to).to eq(ticket.customer.email.to_s)
+ end
+ end
+ end
+
+ context 'list of single users only' do
+ let(:recipient) { [ "userid_#{recipient1.id}", "userid_#{recipient2.id}", "userid_#{recipient3.id}" ] }
+
+ it 'contains all recipients' do
+ expect(ticket.articles.last.to).to eq("#{recipient1.email}, #{recipient2.email}, #{recipient3.email}")
+ end
+ end
+
+ context 'recipient group keyword only' do
+ let(:recipient) { 'ticket_customer' }
+
+ it 'contains matching recipient' do
+ expect(ticket.articles.last.to).to eq(ticket.customer.email.to_s)
+ end
+ end
+ end
end
context 'for condition "ticket updated"' do