feat: Enable template variables in channel greeting messages (#6971)
This commit is contained in:
@@ -1,2 +1,5 @@
|
||||
class AccountDrop < BaseDrop
|
||||
def name
|
||||
@obj.try(:name)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,4 +10,26 @@ module EmailHelper
|
||||
def normalize_email_with_plus_addressing(email)
|
||||
"#{email.split('@').first.split('+').first}@#{email.split('@').last}".downcase
|
||||
end
|
||||
|
||||
def parse_email_variables(conversation, email)
|
||||
case email
|
||||
when modified_liquid_content(email)
|
||||
template = Liquid::Template.parse(modified_liquid_content(email))
|
||||
template.render(message_drops(conversation))
|
||||
when URI::MailTo::EMAIL_REGEXP
|
||||
email
|
||||
end
|
||||
end
|
||||
|
||||
def modified_liquid_content(email)
|
||||
# This regex is used to match the code blocks in the content
|
||||
# We don't want to process liquid in code blocks
|
||||
email.gsub(/`(.*?)`/m, '{% raw %}`\\1`{% endraw %}')
|
||||
end
|
||||
|
||||
def message_drops(conversation)
|
||||
{
|
||||
'contact' => ContactDrop.new(conversation.contact)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,7 +17,16 @@
|
||||
<div v-if="isBusinessHoursEnabled" class="business-hours-wrap">
|
||||
<label class="unavailable-input-wrap">
|
||||
{{ $t('INBOX_MGMT.BUSINESS_HOURS.UNAVAILABLE_MESSAGE_LABEL') }}
|
||||
<textarea v-model="unavailableMessage" type="text" />
|
||||
<label v-if="isRichEditorEnabled" class="richtext">
|
||||
<woot-message-editor
|
||||
v-model="unavailableMessage"
|
||||
:enable-variables="true"
|
||||
:is-format-mode="true"
|
||||
class="input"
|
||||
:min-height="4"
|
||||
/>
|
||||
</label>
|
||||
<textarea v-else v-model="unavailableMessage" type="text" />
|
||||
</label>
|
||||
<div class="timezone-input-wrap">
|
||||
<label>
|
||||
@@ -61,7 +70,9 @@
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
||||
import SettingsSection from 'dashboard/components/SettingsSection';
|
||||
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor';
|
||||
import BusinessDay from './BusinessDay';
|
||||
import {
|
||||
timeSlotParse,
|
||||
@@ -79,8 +90,9 @@ export default {
|
||||
components: {
|
||||
SettingsSection,
|
||||
BusinessDay,
|
||||
WootMessageEditor,
|
||||
},
|
||||
mixins: [alertMixin],
|
||||
mixins: [alertMixin, inboxMixin],
|
||||
props: {
|
||||
inbox: {
|
||||
type: Object,
|
||||
@@ -115,6 +127,15 @@ export default {
|
||||
timeZones() {
|
||||
return [...timeZoneOptions()];
|
||||
},
|
||||
isRichEditorEnabled() {
|
||||
if (
|
||||
this.isATwilioChannel ||
|
||||
this.isATwitterInbox ||
|
||||
this.isAFacebookInbox
|
||||
)
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
inbox() {
|
||||
@@ -190,4 +211,11 @@ export default {
|
||||
.business-hours-wrap {
|
||||
margin-bottom: var(--space-medium);
|
||||
}
|
||||
|
||||
.richtext {
|
||||
padding: 0 var(--space-normal);
|
||||
border-radius: var(--border-radius-normal);
|
||||
border: 1px solid var(--color-border);
|
||||
margin: 0 0 var(--space-normal);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<woot-message-editor
|
||||
v-model="greetingsMessage"
|
||||
:is-format-mode="true"
|
||||
:enable-variables="true"
|
||||
class="input"
|
||||
:placeholder="placeholder"
|
||||
:min-height="4"
|
||||
|
||||
@@ -13,12 +13,13 @@ module Liquidable
|
||||
'contact' => ContactDrop.new(conversation.contact),
|
||||
'agent' => UserDrop.new(sender),
|
||||
'conversation' => ConversationDrop.new(conversation),
|
||||
'inbox' => InboxDrop.new(inbox)
|
||||
'inbox' => InboxDrop.new(inbox),
|
||||
'account' => AccountDrop.new(conversation.account)
|
||||
}
|
||||
end
|
||||
|
||||
def liquid_processable_message?
|
||||
content.present? && message_type == 'outgoing'
|
||||
content.present? && (message_type == 'outgoing' || message_type == 'template')
|
||||
end
|
||||
|
||||
def process_liquid_in_content
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class ActionService
|
||||
include EmailHelper
|
||||
|
||||
def initialize(conversation)
|
||||
@conversation = conversation.reload
|
||||
end
|
||||
@@ -59,6 +61,7 @@ class ActionService
|
||||
emails = emails[0].gsub(/\s+/, '').split(',')
|
||||
|
||||
emails.each do |email|
|
||||
email = parse_email_variables(@conversation, email)
|
||||
ConversationReplyMailer.with(account: @conversation.account).conversation_transcript(@conversation, email)&.deliver_later
|
||||
end
|
||||
end
|
||||
|
||||
@@ -91,6 +91,7 @@ RSpec.describe AutomationRules::ActionService do
|
||||
describe '#perform with send_email_transcript action' do
|
||||
before do
|
||||
rule.actions << { action_name: 'send_email_transcript', action_params: ['contact@example.com, agent@example.com,agent1@example.com'] }
|
||||
rule.save
|
||||
end
|
||||
|
||||
it 'will send email to transcript to action params emails' do
|
||||
@@ -102,6 +103,17 @@ RSpec.describe AutomationRules::ActionService do
|
||||
|
||||
described_class.new(rule, account, conversation).perform
|
||||
end
|
||||
|
||||
it 'will send email to transcript to contacts' do
|
||||
rule.actions = [{ action_name: 'send_email_transcript', action_params: ['{{contact.email}}'] }]
|
||||
rule.save
|
||||
|
||||
mailer = double
|
||||
allow(ConversationReplyMailer).to receive(:with).and_return(mailer)
|
||||
allow(mailer).to receive(:conversation_transcript).with(conversation, conversation.contact.email)
|
||||
|
||||
described_class.new(rule.reload, account, conversation).perform
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,5 +8,26 @@ describe ::MessageTemplates::Template::Greeting do
|
||||
described_class.new(conversation: conversation).perform
|
||||
expect(conversation.messages.count).to eq(1)
|
||||
end
|
||||
|
||||
it 'creates the greeting messages with template variable' do
|
||||
conversation.inbox.update!(greeting_message: 'Hey, {{contact.name}} welcome to our board.')
|
||||
described_class.new(conversation: conversation).perform
|
||||
expect(conversation.messages.count).to eq(1)
|
||||
expect(conversation.messages.last.content).to eq("Hey, #{conversation.contact.name} welcome to our board.")
|
||||
end
|
||||
|
||||
it 'creates the greeting messages with more than one variable strings' do
|
||||
conversation.inbox.update!(greeting_message: 'Hey, {{contact.name}} welcome to our board. - from {{account.name}}')
|
||||
described_class.new(conversation: conversation).perform
|
||||
expect(conversation.messages.count).to eq(1)
|
||||
expect(conversation.messages.last.content).to eq("Hey, #{conversation.contact.name} welcome to our board. - from #{conversation.account.name}")
|
||||
end
|
||||
|
||||
it 'creates the greeting messages' do
|
||||
conversation.inbox.update!(greeting_message: 'Hello welcome to our board.')
|
||||
described_class.new(conversation: conversation).perform
|
||||
expect(conversation.messages.count).to eq(1)
|
||||
expect(conversation.messages.last.content).to eq('Hello welcome to our board.')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,5 +9,22 @@ describe ::MessageTemplates::Template::OutOfOffice do
|
||||
expect(conversation.messages.template.count).to eq(1)
|
||||
expect(conversation.messages.template.first.content).to eq(conversation.inbox.out_of_office_message)
|
||||
end
|
||||
|
||||
it 'creates the out of office messages with template variable' do
|
||||
conversation.inbox.update!(out_of_office_message: 'Hey, {{contact.name}} we are unavailable at the moment.')
|
||||
described_class.new(conversation: conversation).perform
|
||||
expect(conversation.messages.count).to eq(1)
|
||||
expect(conversation.messages.last.content).to eq("Hey, #{conversation.contact.name} we are unavailable at the moment.")
|
||||
end
|
||||
|
||||
it 'creates the out of office messages with more than one variable strings' do
|
||||
conversation.inbox.update!(out_of_office_message:
|
||||
'Hey, {{contact.name}} we are unavailable at the moment. - from {{account.name}}')
|
||||
described_class.new(conversation: conversation).perform
|
||||
expect(conversation.messages.count).to eq(1)
|
||||
expect(conversation.messages.last.content).to eq(
|
||||
"Hey, #{conversation.contact.name} we are unavailable at the moment. - from #{conversation.account.name}"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user