From 45d4d3660c646faf8b755e0e73c1022eae84fd69 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Tue, 15 Jul 2025 21:27:35 -0700 Subject: [PATCH] feat: Add private note action to automations (#11926) ## Summary - allow AutomationRule to accept `add_private_note` action - support `add_private_note` in automation action service - expose private note action in frontend constants and i18n - test new automation rule action ## Testing - `pnpm eslint app/javascript/dashboard/routes/dashboard/settings/automation/constants.js` - `bundle exec rubocop app/services/automation_rules/action_service.rb app/models/automation_rule.rb spec/services/automation_rules/action_service_spec.rb` - `bundle exec rspec spec/services/automation_rules/action_service_spec.rb` ------ https://chatgpt.com/codex/tasks/task_e_6870c5f7b8b88326a9bd60b2ba710ccd Co-authored-by: Muhsin Keloth --- .../dashboard/i18n/locale/en/automation.json | 1 + .../settings/automation/constants.js | 5 +++++ app/models/automation_rule.rb | 3 ++- .../automation_rules/action_service.rb | 7 ++++++ .../automation_rules/action_service_spec.rb | 22 +++++++++++++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/app/javascript/dashboard/i18n/locale/en/automation.json b/app/javascript/dashboard/i18n/locale/en/automation.json index cb030332f..cf63de81c 100644 --- a/app/javascript/dashboard/i18n/locale/en/automation.json +++ b/app/javascript/dashboard/i18n/locale/en/automation.json @@ -146,6 +146,7 @@ "SEND_WEBHOOK_EVENT": "Send Webhook Event", "SEND_ATTACHMENT": "Send Attachment", "SEND_MESSAGE": "Send a Message", + "ADD_PRIVATE_NOTE": "Add a Private Note", "CHANGE_PRIORITY": "Change Priority", "ADD_SLA": "Add SLA", "OPEN_CONVERSATION": "Open conversation" diff --git a/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js b/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js index 1b0f0599f..dfa6163d8 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js +++ b/app/javascript/dashboard/routes/dashboard/settings/automation/constants.js @@ -555,6 +555,11 @@ export const AUTOMATION_ACTION_TYPES = [ label: 'SEND_MESSAGE', inputType: 'textarea', }, + { + key: 'add_private_note', + label: 'ADD_PRIVATE_NOTE', + inputType: 'textarea', + }, { key: 'change_priority', label: 'CHANGE_PRIORITY', diff --git a/app/models/automation_rule.rb b/app/models/automation_rule.rb index c8f5a180d..6f3f47d9c 100644 --- a/app/models/automation_rule.rb +++ b/app/models/automation_rule.rb @@ -41,7 +41,8 @@ class AutomationRule < ApplicationRecord def actions_attributes %w[send_message add_label remove_label send_email_to_team assign_team assign_agent send_webhook_event mute_conversation - send_attachment change_status resolve_conversation open_conversation snooze_conversation change_priority send_email_transcript].freeze + send_attachment change_status resolve_conversation open_conversation snooze_conversation change_priority send_email_transcript + add_private_note].freeze end def file_base_data diff --git a/app/services/automation_rules/action_service.rb b/app/services/automation_rules/action_service.rb index 290e14a9e..e409faba2 100644 --- a/app/services/automation_rules/action_service.rb +++ b/app/services/automation_rules/action_service.rb @@ -47,6 +47,13 @@ class AutomationRules::ActionService < ActionService Messages::MessageBuilder.new(nil, @conversation, params).perform end + def add_private_note(message) + return if conversation_a_tweet? + + params = { content: message[0], private: true, content_attributes: { automation_rule_id: @rule.id } } + Messages::MessageBuilder.new(nil, @conversation.reload, params).perform + end + def send_email_to_team(params) teams = Team.where(id: params[0][:team_ids]) diff --git a/spec/services/automation_rules/action_service_spec.rb b/spec/services/automation_rules/action_service_spec.rb index bdfa7af0c..e63fd7545 100644 --- a/spec/services/automation_rules/action_service_spec.rb +++ b/spec/services/automation_rules/action_service_spec.rb @@ -117,5 +117,27 @@ RSpec.describe AutomationRules::ActionService do expect(mailer).to have_received(:conversation_transcript).exactly(1).times end end + + describe '#perform with add_private_note action' do + let(:message_builder) { double } + + before do + allow(Messages::MessageBuilder).to receive(:new).and_return(message_builder) + rule.actions.delete_if { |a| a['action_name'] == 'send_message' } + rule.actions << { action_name: 'add_private_note', action_params: ['Note'] } + end + + it 'will add private note' do + expect(message_builder).to receive(:perform) + described_class.new(rule, account, conversation).perform + end + + it 'will not add note if conversation is a tweet' do + twitter_inbox = create(:inbox, channel: create(:channel_twitter_profile, account: account)) + conversation = create(:conversation, inbox: twitter_inbox, additional_attributes: { type: 'tweet' }) + expect(message_builder).not_to receive(:perform) + described_class.new(rule, account, conversation).perform + end + end end end