diff --git a/app/controllers/api/v1/accounts/inboxes_controller.rb b/app/controllers/api/v1/accounts/inboxes_controller.rb index fe19400c3..45a190bfb 100644 --- a/app/controllers/api/v1/accounts/inboxes_controller.rb +++ b/app/controllers/api/v1/accounts/inboxes_controller.rb @@ -10,7 +10,12 @@ class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController def create ActiveRecord::Base.transaction do channel = web_widgets.create!(permitted_params[:channel].except(:type)) if permitted_params[:channel][:type] == 'web_widget' - @inbox = Current.account.inboxes.build(name: permitted_params[:name], channel: channel) + @inbox = Current.account.inboxes.build( + name: permitted_params[:name], + greeting_message: permitted_params[:greeting_message], + greeting_enabled: permitted_params[:greeting_enabled], + channel: channel + ) @inbox.avatar.attach(permitted_params[:avatar]) @inbox.save! end @@ -56,11 +61,12 @@ class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController end def permitted_params - params.permit(:id, :avatar, :name, channel: [:type, :website_url, :widget_color, :welcome_title, :welcome_tagline, :agent_away_message]) + params.permit(:id, :avatar, :name, :greeting_message, :greeting_enabled, channel: + [:type, :website_url, :widget_color, :welcome_title, :welcome_tagline]) end def inbox_update_params - params.permit(:enable_auto_assignment, :name, :avatar, channel: [:website_url, :widget_color, :welcome_title, - :welcome_tagline, :agent_away_message]) + params.permit(:enable_auto_assignment, :name, :avatar, :greeting_message, :greeting_enabled, + channel: [:website_url, :widget_color, :welcome_title, :welcome_tagline]) end end diff --git a/app/javascript/dashboard/i18n/locale/el/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/el/inboxMgmt.json index 0a18b005b..7622b72f1 100644 --- a/app/javascript/dashboard/i18n/locale/el/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/el/inboxMgmt.json @@ -54,7 +54,7 @@ "LABEL": "Καλώς ήλθατε (Tagline)", "PLACEHOLDER": "Είναι απλό να συνδεθείτε μαζί μας. Ζητήστε μας οτιδήποτε, ή μοιραστείτε την εμπειρία σας." }, - "CHANNEL_AGENT_AWAY_MESSAGE": { + "CHANNEL_GREETING_MESSAGE": { "LABEL": "Μήνυμα όταν δεν υπάρχουν πράκτορες", "PLACEHOLDER": "Τυπικά απαντάμε σε μερικές ώρες." }, diff --git a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json index 514391664..c885c9ab5 100644 --- a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json @@ -63,10 +63,16 @@ "LABEL": "Welcome Tagline", "PLACEHOLDER": "We make it simple to connect with us. Ask us anything, or share your feedback." }, - "CHANNEL_AGENT_AWAY_MESSAGE": { - "LABEL": "Agents Away Message", + "CHANNEL_GREETING_MESSAGE": { + "LABEL": "Channel greeting message", "PLACEHOLDER": "Acme Inc typically replies in a few hours." }, + "CHANNEL_GREETING_TOGGLE": { + "LABEL": "Enable channel greeting", + "HELP_TEXT": "Send a greeting message to the user when he starts the conversation.", + "ENABLED": "Enabled", + "DISABLED": "Disabled" + }, "WIDGET_COLOR": { "LABEL": "Widget Color", "PLACEHOLDER": "Update the widget color used in widget" diff --git a/app/javascript/dashboard/i18n/locale/es/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/es/inboxMgmt.json index 0c71f17a2..9c19709d2 100644 --- a/app/javascript/dashboard/i18n/locale/es/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/es/inboxMgmt.json @@ -63,7 +63,7 @@ "LABEL": "Bienvenido Tagline", "PLACEHOLDER": "Facilitamos la conexión con nosotros. Pídanos cualquier cosa o comparte tus comentarios." }, - "CHANNEL_AGENT_AWAY_MESSAGE": { + "CHANNEL_GREETING_MESSAGE": { "LABEL": "Mensaje de Agentes Ausentes", "PLACEHOLDER": "Acme Inc normalmente responde en unas pocas horas." }, diff --git a/app/javascript/dashboard/i18n/locale/fr/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/fr/inboxMgmt.json index fe35bf261..48bf6f51c 100644 --- a/app/javascript/dashboard/i18n/locale/fr/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/fr/inboxMgmt.json @@ -54,7 +54,7 @@ "LABEL": "Slogan d'accueil", "PLACEHOLDER": "C'est simple de rentrer en contact avec nous. Demandez-nous quoi que ce soit ou partagez vos commentaires." }, - "CHANNEL_AGENT_AWAY_MESSAGE": { + "CHANNEL_GREETING_MESSAGE": { "LABEL": "Message lorsque les agents sont absents", "PLACEHOLDER": "Acme Inc répond en général en quelques heures." }, diff --git a/app/javascript/dashboard/i18n/locale/nl/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/nl/inboxMgmt.json index 981ca5ffc..74f3e97ac 100644 --- a/app/javascript/dashboard/i18n/locale/nl/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/nl/inboxMgmt.json @@ -54,9 +54,15 @@ "LABEL": "Welkom Tagline", "PLACEHOLDER": "We maken het eenvoudig om met ons te verbinden. Vraag ons iets of deel uw feedback." }, - "CHANNEL_AGENT_AWAY_MESSAGE": { - "LABEL": "Agents Afwezig Bericht", - "PLACEHOLDER": "Acme Inc reageert meestal binnen een paar uur." + "CHANNEL_GREETING_MESSAGE": { + "LABEL": "Kanaalbegroeting", + "PLACEHOLDER": "Acme Inc antwoordt meestal binnen een paar uur." + }, + "CHANNEL_GREETING_TOGGLE": { + "LABEL": "Kanaalbegroeting inschakelen", + "HELP_TEXT": "Stuur een begroetingsbericht naar de gebruiker wanneer hij het gesprek start.", + "ENABLED": "Ingeschakeld", + "DISABLED": "Gehandicapt" }, "WIDGET_COLOR": { "LABEL": "Kleur van widget", diff --git a/app/javascript/dashboard/i18n/locale/pt/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/pt/inboxMgmt.json index 631470370..4fca33c25 100644 --- a/app/javascript/dashboard/i18n/locale/pt/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/pt/inboxMgmt.json @@ -54,7 +54,7 @@ "LABEL": "Bem-vindo Slogan", "PLACEHOLDER": "Nós simplificamos nos conectar com a gente. Pergunte a nós qualquer coisa ou compartilhe seus comentários." }, - "CHANNEL_AGENT_AWAY_MESSAGE": { + "CHANNEL_GREETING_MESSAGE": { "LABEL": "Mensagem Ausente dos Agentes", "PLACEHOLDER": "Acme Inc normalmente responde em algumas horas." }, diff --git a/app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json index 8320edde7..7198a343e 100644 --- a/app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json @@ -54,7 +54,7 @@ "LABEL": "Bem-vindo, saudação", "PLACEHOLDER": "Nós tornamos simples a conexão conosco. Pergunte qualquer assunto ou compartilhe seus comentários." }, - "CHANNEL_AGENT_AWAY_MESSAGE": { + "CHANNEL_GREETING_MESSAGE": { "LABEL": "Mensagem de agente ausente", "PLACEHOLDER": "Acme Inc tipicamente retorna em algumas horas." }, diff --git a/app/javascript/dashboard/i18n/locale/ro/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/ro/inboxMgmt.json index 702a3b1d5..581121dbb 100644 --- a/app/javascript/dashboard/i18n/locale/ro/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/ro/inboxMgmt.json @@ -54,7 +54,7 @@ "LABEL": "Tagline de Bun Venit", "PLACEHOLDER": "Noi facem conectarea cu noi simplă. Întreabă-ne orice, sau partajează-ți feedback-ul." }, - "CHANNEL_AGENT_AWAY_MESSAGE": { + "CHANNEL_GREETING_MESSAGE": { "LABEL": "Mesaj Agent Indisponibil", "PLACEHOLDER": "De obicei, Acme Inc răspunde în câteva ore." }, diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue index b36756b6e..99671a7c1 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue @@ -18,7 +18,7 @@ - - - + {{ $t('INBOX_MGMT.ADD.WEBSITE_CHANNEL.WIDGET_COLOR.LABEL') }} - + + + {{ + $t('INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_TOGGLE.LABEL') + }} + + + {{ + $t( + 'INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_TOGGLE.ENABLED' + ) + }} + + + {{ + $t( + 'INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_TOGGLE.DISABLED' + ) + }} + + + + {{ + $t( + 'INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_TOGGLE.HELP_TEXT' + ) + }} + + + + + {{ $t('INBOX_MGMT.SETTINGS_POPUP.AUTO_ASSIGNMENT') }} - + {{ $t('INBOX_MGMT.EDIT.AUTO_ASSIGNMENT.ENABLED') }} - + {{ $t('INBOX_MGMT.EDIT.AUTO_ASSIGNMENT.DISABLED') }} @@ -183,13 +198,14 @@ export default { avatarFile: null, avatarUrl: '', selectedAgents: [], + greetingEnabled: true, + greetingMessage: '', autoAssignment: false, isAgentListUpdating: false, selectedInboxName: '', channelWebsiteUrl: '', channelWelcomeTitle: '', channelWelcomeTagline: '', - channelAgentAwayMessage: '', autoAssignmentOptions: [ { value: true, @@ -247,11 +263,12 @@ export default { this.fetchAttachedAgents(); this.avatarUrl = this.inbox.avatar_url; this.selectedInboxName = this.inbox.name; + this.greetingEnabled = this.inbox.greeting_enabled; + this.greetingMessage = this.inbox.greeting_message; this.autoAssignment = this.inbox.enable_auto_assignment; this.channelWebsiteUrl = this.inbox.website_url; this.channelWelcomeTitle = this.inbox.welcome_title; this.channelWelcomeTagline = this.inbox.welcome_tagline; - this.channelAgentAwayMessage = this.inbox.agent_away_message; }); }, async fetchAttachedAgents() { @@ -294,12 +311,13 @@ export default { id: this.currentInboxId, name: this.selectedInboxName, enable_auto_assignment: this.autoAssignment, + greeting_enabled: this.greetingEnabled, + greeting_message: this.greetingMessage, channel: { widget_color: this.inbox.widget_color, website_url: this.channelWebsiteUrl, welcome_title: this.channelWelcomeTitle, welcome_tagline: this.channelWelcomeTagline, - agent_away_message: this.channelAgentAwayMessage, }, }; if (this.avatarFile) { diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Website.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Website.vue index 644eb10a1..c992d38a0 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Website.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Website.vue @@ -6,9 +6,8 @@ /> - + :message="$t('INBOX_MGMT.ADD.WEBSITE_CHANNEL.LOADING_MESSAGE')" + /> - - + + {{ $t('INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_TOGGLE.LABEL') }} + + + {{ + $t( + 'INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_TOGGLE.ENABLED' + ) + }} + + + {{ + $t( + 'INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_TOGGLE.DISABLED' + ) + }} + + + {{ $t( - 'INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_AGENT_AWAY_MESSAGE.LABEL' + 'INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_TOGGLE.HELP_TEXT' ) }} + + + + + {{ + $t('INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_MESSAGE.LABEL') + }} @@ -124,7 +147,8 @@ export default { channelWidgetColor: '#009CE0', channelWelcomeTitle: '', channelWelcomeTagline: '', - channelAgentAwayMessage: '', + greetingEnabled: false, + greetingMessage: '', }; }, computed: { @@ -138,13 +162,14 @@ export default { 'inboxes/createWebsiteChannel', { name: this.inboxName, + greeting_enabled: this.greetingEnabled, + greeting_message: this.greetingMessage, channel: { type: 'web_widget', website_url: this.channelWebsiteUrl, widget_color: this.channelWidgetColor, welcome_title: this.channelWelcomeTitle, welcome_tagline: this.channelWelcomeTagline, - agent_away_message: this.channelAgentAwayMessage, }, } ); diff --git a/app/models/inbox.rb b/app/models/inbox.rb index 4fb395ba5..b5d276c56 100644 --- a/app/models/inbox.rb +++ b/app/models/inbox.rb @@ -7,6 +7,8 @@ # id :integer not null, primary key # channel_type :string # enable_auto_assignment :boolean default(TRUE) +# greeting_enabled :boolean default(FALSE) +# greeting_message :string # name :string not null # created_at :datetime not null # updated_at :datetime not null diff --git a/app/models/message.rb b/app/models/message.rb index 696ae5a2b..b8678ea0a 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -71,11 +71,9 @@ class Message < ApplicationRecord has_many :attachments, dependent: :destroy, autosave: true, before_add: :validate_attachments_limit after_create :reopen_conversation, - :execute_message_template_hooks, :notify_via_mail - # we need to wait for the active storage attachments to be available - after_create_commit :dispatch_create_events, :send_reply + after_create_commit :execute_after_create_commit_callbacks after_update :dispatch_update_event @@ -117,6 +115,14 @@ class Message < ApplicationRecord private + def execute_after_create_commit_callbacks + # rails issue with order of active record callbacks being executed + # https://github.com/rails/rails/issues/20911 + dispatch_create_events + send_reply + execute_message_template_hooks + end + def dispatch_create_events Rails.configuration.dispatcher.dispatch(MESSAGE_CREATED, Time.zone.now, message: self) diff --git a/app/services/facebook/send_reply_service.rb b/app/services/facebook/send_reply_service.rb index 9173ecac7..f80f329fd 100644 --- a/app/services/facebook/send_reply_service.rb +++ b/app/services/facebook/send_reply_service.rb @@ -23,7 +23,7 @@ class Facebook::SendReplyService def outgoing_message_from_chatwoot? # messages sent directly from chatwoot won't have source_id. - message.outgoing? && !message.source_id + (message.outgoing? || message.template?) && !message.source_id end # def reopen_lock diff --git a/app/services/message_templates/hook_execution_service.rb b/app/services/message_templates/hook_execution_service.rb index c626c4671..947c0f39f 100644 --- a/app/services/message_templates/hook_execution_service.rb +++ b/app/services/message_templates/hook_execution_service.rb @@ -4,6 +4,8 @@ class MessageTemplates::HookExecutionService def perform return if inbox.agent_bot_inbox&.active? + ::MessageTemplates::Template::Greeting.new(conversation: conversation).perform if should_send_greeting? + ::MessageTemplates::Template::EmailCollect.new(conversation: conversation).perform if should_send_email_collect? end @@ -16,8 +18,16 @@ class MessageTemplates::HookExecutionService conversation.messages.outgoing.count.zero? && conversation.messages.template.count.zero? end + def should_send_greeting? + first_message_from_contact? && conversation.inbox.greeting_enabled? + end + + def email_collect_was_sent? + conversation.messages.where(content_type: 'input_email').present? + end + def should_send_email_collect? - !contact_has_email? && conversation.inbox.web_widget? && first_message_from_contact? + !contact_has_email? && conversation.inbox.web_widget? && !email_collect_was_sent? end def contact_has_email? diff --git a/app/services/message_templates/template/email_collect.rb b/app/services/message_templates/template/email_collect.rb index e9e830d3b..667b6b6cd 100644 --- a/app/services/message_templates/template/email_collect.rb +++ b/app/services/message_templates/template/email_collect.rb @@ -3,7 +3,6 @@ class MessageTemplates::Template::EmailCollect def perform ActiveRecord::Base.transaction do - conversation.messages.create!(typical_reply_message_params) conversation.messages.create!(ways_to_reach_you_message_params) conversation.messages.create!(email_input_box_template_message_params) end @@ -17,21 +16,6 @@ class MessageTemplates::Template::EmailCollect delegate :contact, :account, to: :conversation delegate :inbox, to: :message - def typical_reply_message_params - content = @conversation.inbox&.channel&.agent_away_message - if content.blank? - content = I18n.t('conversations.templates.typical_reply_message_body', - account_name: account.name) - end - - { - account_id: @conversation.account_id, - inbox_id: @conversation.inbox_id, - message_type: :template, - content: content - } - end - def ways_to_reach_you_message_params content = I18n.t('conversations.templates.ways_to_reach_you_message_body', account_name: account.name) diff --git a/app/services/message_templates/template/greeting.rb b/app/services/message_templates/template/greeting.rb new file mode 100644 index 000000000..478cc9bb7 --- /dev/null +++ b/app/services/message_templates/template/greeting.rb @@ -0,0 +1,32 @@ +class MessageTemplates::Template::Greeting + pattr_initialize [:conversation!] + + def perform + ActiveRecord::Base.transaction do + conversation.messages.create!(greeting_message_params) + end + rescue StandardError => e + Raven.capture_exception(e) + true + end + + private + + delegate :contact, :account, to: :conversation + delegate :inbox, to: :message + + def greeting_message_params + content = @conversation.inbox&.greeting_message + if content.blank? + content = I18n.t('conversations.templates.greeting_message_body', + account_name: account.name) + end + + { + account_id: @conversation.account_id, + inbox_id: @conversation.inbox_id, + message_type: :template, + content: content + } + end +end diff --git a/app/services/twilio/outgoing_message_service.rb b/app/services/twilio/outgoing_message_service.rb index 015b2f75f..6c4371d76 100644 --- a/app/services/twilio/outgoing_message_service.rb +++ b/app/services/twilio/outgoing_message_service.rb @@ -5,7 +5,7 @@ class Twilio::OutgoingMessageService return if message.private return if message.source_id return if inbox.channel.class.to_s != 'Channel::TwilioSms' - return unless message.outgoing? + return unless outgoing_message? twilio_message = client.messages.create(message_params) message.update!(source_id: twilio_message.sid) @@ -39,6 +39,10 @@ class Twilio::OutgoingMessageService @channel ||= inbox.channel end + def outgoing_message? + message.outgoing? || message.template? + end + def client ::Twilio::REST::Client.new(channel.account_sid, channel.auth_token) end diff --git a/app/services/twitter/direct_message_parser_service.rb b/app/services/twitter/direct_message_parser_service.rb index f68d60815..bf83958ba 100644 --- a/app/services/twitter/direct_message_parser_service.rb +++ b/app/services/twitter/direct_message_parser_service.rb @@ -64,7 +64,7 @@ class Twitter::DirectMessageParserService < Twitter::WebhooksBaseService end def set_conversation - @conversation = @contact_inbox.conversations.first + @conversation = @contact_inbox.conversations.where("additional_attributes ->> 'type' = 'direct_message'").first return if @conversation @conversation = ::Conversation.create!(conversation_params) diff --git a/app/services/twitter/send_reply_service.rb b/app/services/twitter/send_reply_service.rb index e30786dc0..b68b3aef6 100644 --- a/app/services/twitter/send_reply_service.rb +++ b/app/services/twitter/send_reply_service.rb @@ -56,7 +56,7 @@ class Twitter::SendReplyService end def outgoing_message_from_chatwoot? - message.outgoing? + (message.outgoing? || message.template?) end delegate :additional_attributes, to: :contact diff --git a/app/views/api/v1/accounts/inboxes/create.json.jbuilder b/app/views/api/v1/accounts/inboxes/create.json.jbuilder index a596c0dd6..c046402bc 100644 --- a/app/views/api/v1/accounts/inboxes/create.json.jbuilder +++ b/app/views/api/v1/accounts/inboxes/create.json.jbuilder @@ -2,12 +2,13 @@ json.id @inbox.id json.channel_id @inbox.channel_id json.name @inbox.name json.channel_type @inbox.channel_type +json.greeting_enabled @inbox.greeting_enabled +json.greeting_message @inbox.greeting_message json.avatar_url @inbox.try(:avatar_url) json.website_token @inbox.channel.try(:website_token) json.widget_color @inbox.channel.try(:widget_color) json.website_url @inbox.channel.try(:website_url) json.welcome_title @inbox.channel.try(:welcome_title) json.welcome_tagline @inbox.channel.try(:welcome_tagline) -json.agent_away_message @inbox.channel.try(:agent_away_message) json.web_widget_script @inbox.channel.try(:web_widget_script) json.enable_auto_assignment @inbox.enable_auto_assignment diff --git a/app/views/api/v1/accounts/inboxes/index.json.jbuilder b/app/views/api/v1/accounts/inboxes/index.json.jbuilder index 7d6879634..da52d6632 100644 --- a/app/views/api/v1/accounts/inboxes/index.json.jbuilder +++ b/app/views/api/v1/accounts/inboxes/index.json.jbuilder @@ -4,13 +4,14 @@ json.payload do json.channel_id inbox.channel_id json.name inbox.name json.channel_type inbox.channel_type + json.greeting_enabled inbox.greeting_enabled + json.greeting_message inbox.greeting_message json.avatar_url inbox.try(:avatar_url) json.page_id inbox.channel.try(:page_id) json.widget_color inbox.channel.try(:widget_color) json.website_url inbox.channel.try(:website_url) json.welcome_title inbox.channel.try(:welcome_title) json.welcome_tagline inbox.channel.try(:welcome_tagline) - json.agent_away_message inbox.channel.try(:agent_away_message) json.enable_auto_assignment inbox.enable_auto_assignment json.web_widget_script inbox.channel.try(:web_widget_script) json.phone_number inbox.channel.try(:phone_number) diff --git a/app/views/api/v1/accounts/inboxes/update.json.jbuilder b/app/views/api/v1/accounts/inboxes/update.json.jbuilder index a596c0dd6..c046402bc 100644 --- a/app/views/api/v1/accounts/inboxes/update.json.jbuilder +++ b/app/views/api/v1/accounts/inboxes/update.json.jbuilder @@ -2,12 +2,13 @@ json.id @inbox.id json.channel_id @inbox.channel_id json.name @inbox.name json.channel_type @inbox.channel_type +json.greeting_enabled @inbox.greeting_enabled +json.greeting_message @inbox.greeting_message json.avatar_url @inbox.try(:avatar_url) json.website_token @inbox.channel.try(:website_token) json.widget_color @inbox.channel.try(:widget_color) json.website_url @inbox.channel.try(:website_url) json.welcome_title @inbox.channel.try(:welcome_title) json.welcome_tagline @inbox.channel.try(:welcome_tagline) -json.agent_away_message @inbox.channel.try(:agent_away_message) json.web_widget_script @inbox.channel.try(:web_widget_script) json.enable_auto_assignment @inbox.enable_auto_assignment diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 250b3a003..ea5d46706 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -36,6 +36,6 @@ ca: assigned: "Assignada a %{assignee_name} per %{user_name}" removed: "%{user_name} ha tret l'assignació de la conversa" templates: - typical_reply_message_body: "%{account_name} normalment respon a les poques hores." + greeting_message_body: "%{account_name} normalment respon a les poques hores." ways_to_reach_you_message_body: "Fes saber a l'equip la forma de posar-nos en contacte amb tu." email_input_box_message_body: "Rep les notificacions per correu electrònic" diff --git a/config/locales/cs.yml b/config/locales/cs.yml index bf9ac59d7..e03370860 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -36,6 +36,6 @@ cs: assigned: "Přiřazeno k %{assignee_name} uživatelem %{user_name}" removed: "Konverzace zrušena uživatelem %{user_name}" templates: - typical_reply_message_body: "%{account_name} obvykle odpovídá za několik hodin." + greeting_message_body: "%{account_name} obvykle odpovídá za několik hodin." ways_to_reach_you_message_body: "Dejte týmu způsob, jak se k vám dostat." email_input_box_message_body: "Dostat upozornění e-mailem" diff --git a/config/locales/de.yml b/config/locales/de.yml index 5000c0344..6c007a159 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -51,6 +51,6 @@ de: assigned: "%{user_name} von %{assignee_name} zugewiesen" removed: "Gespräch nicht zugewiesen von %{user_name}" templates: - typical_reply_message_body: "%{account_name} Antworten in der Regel in wenigen Stunden." + greeting_message_body: "%{account_name} Antworten in der Regel in wenigen Stunden." ways_to_reach_you_message_body: "Geben Sie dem Team einen Weg, Sie zu erreichen." email_input_box_message_body: "Lassen Sie sich per E-Mail benachrichtigen" diff --git a/config/locales/el.yml b/config/locales/el.yml index 6282505cf..5f7a74dfc 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -36,7 +36,7 @@ el: assigned: "Ανατέθηκε στον %{assignee_name} από τον %{user_name}" removed: "Η συνομιλία σημάνθηκε ως μη ανατεθειμένη από τον %{user_name}" templates: - typical_reply_message_body: "Ο/Η %{account_name} συνήθως απαντάει σε μερικές ώρες." + greeting_message_body: "Ο/Η %{account_name} συνήθως απαντάει σε μερικές ώρες." ways_to_reach_you_message_body: "Δώστε στην ομάδα ένα τρόπο να φτάσει σε σας." email_input_box_message_body: "Ειδοποιηθείτε με email" reply: diff --git a/config/locales/en.yml b/config/locales/en.yml index 3b9afe3e4..f1852aa0c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -51,7 +51,7 @@ en: assigned: "Assigned to %{assignee_name} by %{user_name}" removed: "Conversation unassigned by %{user_name}" templates: - typical_reply_message_body: "%{account_name} typically replies in a few hours." + greeting_message_body: "%{account_name} typically replies in a few hours." ways_to_reach_you_message_body: "Give the team a way to reach you." email_input_box_message_body: "Get notified by email" reply: diff --git a/config/locales/es.yml b/config/locales/es.yml index a85633fc7..5b968a6d9 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -36,7 +36,7 @@ es: assigned: "Asignado a %{assignee_name} por %{user_name}" removed: "Conversación no asignada por %{user_name}" templates: - typical_reply_message_body: "%{account_name} normalmente responde en unas pocas horas." + greeting_message_body: "%{account_name} normalmente responde en unas pocas horas." ways_to_reach_you_message_body: "Dale al equipo una forma de llegar a ti." email_input_box_message_body: "Recibir notificaciones por correo electrónico" reply: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 5651c1fd5..9ff3ccbe7 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -36,7 +36,7 @@ fr: assigned: "Assigné à %{assignee_name} par %{user_name}" removed: "Responsable de la conversation supprimé par %{user_name}" templates: - typical_reply_message_body: "%{account_name} répond généralement en quelques heures." + greeting_message_body: "%{account_name} répond généralement en quelques heures." ways_to_reach_you_message_body: "Donnez à l'équipe un moyen de vous recontacter." email_input_box_message_body: "Recevez des notifications par courriel" reply: diff --git a/config/locales/it.yml b/config/locales/it.yml index 1e2d843bc..a7ef603b4 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -36,6 +36,6 @@ it: assigned: "Assegnato a %{assignee_name} da %{user_name}" removed: "Conversazione non assegnata da %{user_name}" templates: - typical_reply_message_body: "%{account_name} risponde tipicamente tra qualche ora." + greeting_message_body: "%{account_name} risponde tipicamente tra qualche ora." ways_to_reach_you_message_body: "Offri alla squadra un modo per raggiungerti." email_input_box_message_body: "Ricevi una notifica via email" diff --git a/config/locales/ml.yml b/config/locales/ml.yml index 7cf0efe49..2dd97a3ff 100644 --- a/config/locales/ml.yml +++ b/config/locales/ml.yml @@ -36,6 +36,6 @@ ml: assigned: "%{assignee_name} %{user_name}-നെ നിയുക്തനാക്കി " removed: "%{user_name} സംഭാഷണം നിയുക്തമല്ലാതാക്കി" templates: - typical_reply_message_body: "%{account_name} സാധാരണ കുറച്ച് മണിക്കൂറിനുള്ളിൽ മറുപടി നൽകുന്നു." + greeting_message_body: "%{account_name} സാധാരണ കുറച്ച് മണിക്കൂറിനുള്ളിൽ മറുപടി നൽകുന്നു." ways_to_reach_you_message_body: "നിങ്ങളിലേക്ക് എത്താൻ ടീമിന് ഒരു വഴി നൽകുക." email_input_box_message_body: "ഇമെയിൽ വഴി അറിയിപ്പ് നേടുക" diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 370378423..e6091f25b 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -36,6 +36,6 @@ nl: assigned: "Toegewezen aan %{assignee_name} door %{user_name}" removed: "Gesprek niet toegewezen door %{user_name}" templates: - typical_reply_message_body: "%{account_name} reageert meestal binnen een paar uur." + greeting_message_body: "%{account_name} reageert meestal binnen een paar uur." ways_to_reach_you_message_body: "Geef het team een manier om je te bereiken." email_input_box_message_body: "Ontvang een melding via e-mail" diff --git a/config/locales/pl.yml b/config/locales/pl.yml index a5f579186..fa159567a 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -36,6 +36,6 @@ pl: assigned: "Przypisane do %{assignee_name} przez %{user_name}" removed: "Rozmowa nieprzypisana przez %{user_name}" templates: - typical_reply_message_body: "%{account_name} zazwyczaj odpowiada w kilka godzin." + greeting_message_body: "%{account_name} zazwyczaj odpowiada w kilka godzin." ways_to_reach_you_message_body: "Daj drużynie możliwość dotarcia do Ciebie." email_input_box_message_body: "Otrzymuj powiadomienia przez e-mail" diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 554fee99a..a1c20837f 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -36,6 +36,6 @@ pt: assigned: "Atribuído a %{assignee_name} por %{user_name}" removed: "Conversa não atribuída por %{user_name}" templates: - typical_reply_message_body: "%{account_name} normalmente responde em algumas horas." + greeting_message_body: "%{account_name} normalmente responde em algumas horas." ways_to_reach_you_message_body: "Dê à equipe um jeito de contatá-lo." email_input_box_message_body: "Seja notificado por e-mail" diff --git a/config/locales/pt_BR.yml b/config/locales/pt_BR.yml index 4c496c68a..8ce6be097 100644 --- a/config/locales/pt_BR.yml +++ b/config/locales/pt_BR.yml @@ -36,6 +36,6 @@ pt-BR: assigned: "Atribuído a %{assignee_name} por %{user_name}" removed: "Conversa não atribuída por %{user_name}" templates: - typical_reply_message_body: "%{account_name} normalmente responde em algumas horas." + greeting_message_body: "%{account_name} normalmente responde em algumas horas." ways_to_reach_you_message_body: "Informe uma forma para entrarmos em contato com você." email_input_box_message_body: "Seja notificado por e-mail" diff --git a/config/locales/ro.yml b/config/locales/ro.yml index db83cb3ef..a685277e2 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -36,7 +36,7 @@ ro: assigned: "Atribuit lui %{assignee_name} de %{user_name}" removed: "Conversație neasociată de %{user_name}" templates: - typical_reply_message_body: "%{account_name} răspunde de obicei în câteva ore." + greeting_message_body: "%{account_name} răspunde de obicei în câteva ore." ways_to_reach_you_message_body: "Dă-i echipei o modalitate de a te contacta." email_input_box_message_body: "Primește notificări prin e-mail" reply: diff --git a/config/locales/sv.yml b/config/locales/sv.yml index fa70633f2..9a8029a91 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -36,6 +36,6 @@ sv: assigned: "Tilldelad till %{assignee_name} av %{user_name}" removed: "Konversation otilldelad av %{user_name}" templates: - typical_reply_message_body: "%{account_name} svarar vanligtvis om några timmar." + greeting_message_body: "%{account_name} svarar vanligtvis om några timmar." ways_to_reach_you_message_body: "Ge laget ett sätt att nå dig." email_input_box_message_body: "Få meddelande via e-post" diff --git a/db/migrate/20200605130625_agent_away_message_to_auto_reply.rb b/db/migrate/20200605130625_agent_away_message_to_auto_reply.rb new file mode 100644 index 000000000..9bf1d49c6 --- /dev/null +++ b/db/migrate/20200605130625_agent_away_message_to_auto_reply.rb @@ -0,0 +1,21 @@ +class AgentAwayMessageToAutoReply < ActiveRecord::Migration[6.0] + def change + add_column :inboxes, :greeting_enabled, :boolean, default: false # rubocop:disable Rails/BulkChangeTable + add_column :inboxes, :greeting_message, :string + + migrate_agent_away_to_greeting + + remove_column :channel_web_widgets, :agent_away_message, :string + end + + def migrate_agent_away_to_greeting + ::Channel::WebWidget.find_in_batches do |widget_batch| + widget_batch.each do |widget| + inbox = widget.inbox + inbox.greeting_enabled = true + inbox.greeting_message = widget.agent_away_message + widget.save! + end + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 914058c79..f237be8f0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -161,7 +161,6 @@ ActiveRecord::Schema.define(version: 2020_06_07_140737) do t.string "widget_color", default: "#1f93ff" t.string "welcome_title" t.string "welcome_tagline" - t.string "agent_away_message" t.index ["website_token"], name: "index_channel_web_widgets_on_website_token", unique: true end @@ -245,6 +244,8 @@ ActiveRecord::Schema.define(version: 2020_06_07_140737) do t.datetime "updated_at", null: false t.string "channel_type" t.boolean "enable_auto_assignment", default: true + t.boolean "greeting_enabled", default: false + t.string "greeting_message" t.index ["account_id"], name: "index_inboxes_on_account_id" end diff --git a/spec/controllers/api/v1/widget/messages_controller_spec.rb b/spec/controllers/api/v1/widget/messages_controller_spec.rb index e4983fa57..a8120d93e 100644 --- a/spec/controllers/api/v1/widget/messages_controller_spec.rb +++ b/spec/controllers/api/v1/widget/messages_controller_spec.rb @@ -24,8 +24,8 @@ RSpec.describe '/api/v1/widget/messages', type: :request do expect(response).to have_http_status(:success) json_response = JSON.parse(response.body) - # 2 messages created + 3 messages by the template hook - expect(json_response.length).to eq(5) + # 2 messages created + 2 messages by the email hook + expect(json_response.length).to eq(4) end end end diff --git a/spec/finders/message_finder_spec.rb b/spec/finders/message_finder_spec.rb index e51c7c406..58dafcef6 100644 --- a/spec/finders/message_finder_spec.rb +++ b/spec/finders/message_finder_spec.rb @@ -15,7 +15,7 @@ describe ::MessageFinder do create(:message, account: account, inbox: inbox, conversation: conversation) create(:message, message_type: 'activity', account: account, inbox: inbox, conversation: conversation) create(:message, message_type: 'activity', account: account, inbox: inbox, conversation: conversation) - # this outgoing message creates 3 additional messages because of the hook execution service + # this outgoing message creates 2 additional messages because of the email hook execution service create(:message, message_type: 'outgoing', account: account, inbox: inbox, conversation: conversation) end @@ -25,7 +25,7 @@ describe ::MessageFinder do it 'filter conversations by status' do result = message_finder.perform - expect(result.count).to be 7 + expect(result.count).to be 6 end end @@ -34,7 +34,7 @@ describe ::MessageFinder do it 'filter conversations by status' do result = message_finder.perform - expect(result.count).to be 5 + expect(result.count).to be 4 end end @@ -44,7 +44,7 @@ describe ::MessageFinder do it 'filter conversations by status' do result = message_finder.perform - expect(result.count).to be 7 + expect(result.count).to be 6 end end end diff --git a/spec/lib/webhooks/twitter_spec.rb b/spec/lib/webhooks/twitter_spec.rb index 28220406b..cb01d03da 100644 --- a/spec/lib/webhooks/twitter_spec.rb +++ b/spec/lib/webhooks/twitter_spec.rb @@ -7,7 +7,7 @@ describe Webhooks::Twitter do let!(:account) { create(:account) } # FIX ME: recipient id is set to 1 inside event factories let!(:twitter_channel) { create(:channel_twitter_profile, account: account, profile_id: '1') } - let!(:twitter_inbox) { create(:inbox, channel: twitter_channel, account: account) } + let!(:twitter_inbox) { create(:inbox, channel: twitter_channel, account: account, greeting_enabled: false) } let!(:dm_params) { build(:twitter_message_create_event).with_indifferent_access } let!(:tweet_params) { build(:tweet_create_event).with_indifferent_access } diff --git a/spec/mailboxes/conversation_mailbox_spec.rb b/spec/mailboxes/conversation_mailbox_spec.rb index c3e5dfa2a..65a757058 100644 --- a/spec/mailboxes/conversation_mailbox_spec.rb +++ b/spec/mailboxes/conversation_mailbox_spec.rb @@ -6,7 +6,7 @@ RSpec.describe ConversationMailbox, type: :mailbox do describe 'add mail as reply in a conversation' do let(:agent) { create(:user, email: 'agent1@example.com') } let(:reply_mail) { create_inbound_email_from_fixture('reply.eml') } - let(:conversation) { create(:conversation, assignee: agent) } + let(:conversation) { create(:conversation, assignee: agent, inbox: create(:inbox, greeting_enabled: false)) } let(:described_subject) { described_class.receive reply_mail } let(:serialized_attributes) { %w[text_content html_content number_of_attachments subject date to from in_reply_to cc bcc message_id] } diff --git a/spec/services/message_templates/hook_execution_service_spec.rb b/spec/services/message_templates/hook_execution_service_spec.rb index 90a7893ad..4b5b8537f 100644 --- a/spec/services/message_templates/hook_execution_service_spec.rb +++ b/spec/services/message_templates/hook_execution_service_spec.rb @@ -5,17 +5,22 @@ describe ::MessageTemplates::HookExecutionService do it 'calls ::MessageTemplates::Template::EmailCollect' do contact = create(:contact, email: nil) conversation = create(:conversation, contact: contact) - message = create(:message, conversation: conversation) - # this hook will only get executed for conversations with out any template messages - message.conversation.messages.template.destroy_all + # ensure greeting hook is enabled + conversation.inbox.update(greeting_enabled: true) email_collect_service = double + greeting_service = double allow(::MessageTemplates::Template::EmailCollect).to receive(:new).and_return(email_collect_service) allow(email_collect_service).to receive(:perform).and_return(true) + allow(::MessageTemplates::Template::Greeting).to receive(:new).and_return(greeting_service) + allow(greeting_service).to receive(:perform).and_return(true) - described_class.new(message: message).perform + # described class gets called in message after commit + message = create(:message, conversation: conversation) + expect(::MessageTemplates::Template::Greeting).to have_received(:new).with(conversation: message.conversation) + expect(greeting_service).to have_received(:perform) expect(::MessageTemplates::Template::EmailCollect).to have_received(:new).with(conversation: message.conversation) expect(email_collect_service).to have_received(:perform) end diff --git a/spec/services/message_templates/template/email_collect_spec.rb b/spec/services/message_templates/template/email_collect_spec.rb index 1d688e37a..4fe5256c7 100644 --- a/spec/services/message_templates/template/email_collect_spec.rb +++ b/spec/services/message_templates/template/email_collect_spec.rb @@ -6,7 +6,7 @@ describe ::MessageTemplates::Template::EmailCollect do it 'creates the email collect messages' do described_class.new(conversation: conversation).perform - expect(conversation.messages.count).to eq(3) + expect(conversation.messages.count).to eq(2) end end end diff --git a/spec/services/message_templates/template/greeting_spec.rb b/spec/services/message_templates/template/greeting_spec.rb new file mode 100644 index 000000000..7d1f45d8c --- /dev/null +++ b/spec/services/message_templates/template/greeting_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +describe ::MessageTemplates::Template::Greeting do + context 'when this hook is called' do + let(:conversation) { create(:conversation) } + + it 'creates the email collect messages' do + described_class.new(conversation: conversation).perform + expect(conversation.messages.count).to eq(1) + end + end +end diff --git a/spec/services/twilio/incoming_message_service_spec.rb b/spec/services/twilio/incoming_message_service_spec.rb index 7b895bd35..277a4f683 100644 --- a/spec/services/twilio/incoming_message_service_spec.rb +++ b/spec/services/twilio/incoming_message_service_spec.rb @@ -3,7 +3,8 @@ require 'rails_helper' describe Twilio::IncomingMessageService do let!(:account) { create(:account) } let!(:twilio_sms) do - create(:channel_twilio_sms, account: account, phone_number: '+1234567890', account_sid: 'ACxxx') + create(:channel_twilio_sms, account: account, phone_number: '+1234567890', account_sid: 'ACxxx', + inbox: create(:inbox, account: account, greeting_enabled: false)) end let!(:contact) { create(:contact, account: account, phone_number: '+12345') } let(:contact_inbox) { create(:contact_inbox, source_id: '+12345', contact: contact, inbox: twilio_sms.inbox) }
+ {{ + $t( + 'INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_TOGGLE.HELP_TEXT' + ) + }} +
{{ $t( - 'INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_AGENT_AWAY_MESSAGE.LABEL' + 'INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_GREETING_TOGGLE.HELP_TEXT' ) }} +