feat: Enable template variables in channel greeting messages (#6971)

This commit is contained in:
Tejaswini Chile
2023-04-26 20:23:46 +05:30
committed by GitHub
parent 3fa654f5c6
commit 99dfe1d5af
9 changed files with 112 additions and 4 deletions

View File

@@ -1,2 +1,5 @@
class AccountDrop < BaseDrop
def name
@obj.try(:name)
end
end

View File

@@ -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

View File

@@ -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>

View File

@@ -4,6 +4,7 @@
<woot-message-editor
v-model="greetingsMessage"
:is-format-mode="true"
:enable-variables="true"
class="input"
:placeholder="placeholder"
:min-height="4"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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