From 97efd36bc56defcbfc3b0928a4a00c0bc061b9eb Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Thu, 26 Jun 2025 01:19:58 +0530 Subject: [PATCH] fix: Add missing CSAT URL in email reply templates (#11808) As part of PR [#11622](https://github.com/chatwoot/chatwoot/pull/11622), we intentionally hide CSAT survey URLs from agents in the dashboard to avoid exposing those links internally. However, email replies being external communications to contacts should still include the survey URLs. We missed handling that specific case for email channels. All other external channels like WhatsApp, Instagram, Telegram, etc., were already working correctly and continue to include the survey URLs as intended. --------- Co-authored-by: Pranav --- .../email_reply.html.erb | 2 +- .../mailers/conversation_reply_mailer_spec.rb | 21 +++++++++++++++++++ .../message_content_presenter_spec.rb | 17 ++++++++------- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/app/views/mailers/conversation_reply_mailer/email_reply.html.erb b/app/views/mailers/conversation_reply_mailer/email_reply.html.erb index 319ba4b4e..feb5dff96 100644 --- a/app/views/mailers/conversation_reply_mailer/email_reply.html.erb +++ b/app/views/mailers/conversation_reply_mailer/email_reply.html.erb @@ -1,5 +1,5 @@ <% if @message.content %> - <%= ChatwootMarkdownRenderer.new(@message.content).render_message %> + <%= ChatwootMarkdownRenderer.new(@message.outgoing_content).render_message %> <% end %> <% if @large_attachments.present? %>

Attachments:

diff --git a/spec/mailers/conversation_reply_mailer_spec.rb b/spec/mailers/conversation_reply_mailer_spec.rb index 8485fcf7a..2a0d6c8b0 100644 --- a/spec/mailers/conversation_reply_mailer_spec.rb +++ b/spec/mailers/conversation_reply_mailer_spec.rb @@ -154,6 +154,27 @@ RSpec.describe ConversationReplyMailer do expect(mail.message_id).to eq message.source_id end + context 'when message is a CSAT survey' do + let(:csat_message) do + create(:message, conversation: conversation, account: account, message_type: 'template', + content_type: 'input_csat', content: 'How would you rate our support?', sender: agent) + end + + it 'includes CSAT survey URL in outgoing_content' do + with_modified_env 'FRONTEND_URL' => 'https://app.chatwoot.com' do + mail = described_class.email_reply(csat_message).deliver_now + expect(mail.decoded).to include "https://app.chatwoot.com/survey/responses/#{conversation.uuid}" + end + end + + it 'uses outgoing_content for CSAT message body' do + with_modified_env 'FRONTEND_URL' => 'https://app.chatwoot.com' do + mail = described_class.email_reply(csat_message).deliver_now + expect(mail.decoded).to include csat_message.outgoing_content + end + end + end + context 'with email attachments' do it 'includes small attachments as email attachments' do message_with_attachment = create(:message, conversation: conversation, account: account, message_type: 'outgoing', diff --git a/spec/presenters/message_content_presenter_spec.rb b/spec/presenters/message_content_presenter_spec.rb index b1be37ef2..f85bdb8d1 100644 --- a/spec/presenters/message_content_presenter_spec.rb +++ b/spec/presenters/message_content_presenter_spec.rb @@ -34,20 +34,21 @@ RSpec.describe MessageContentPresenter do before do allow(message.inbox).to receive(:web_widget?).and_return(false) - allow(ENV).to receive(:fetch).with('FRONTEND_URL', nil).and_return('https://app.chatwoot.com') end it 'returns I18n default message when no CSAT config and dynamically generates survey URL' do - expected_url = "https://app.chatwoot.com/survey/responses/#{conversation.uuid}" - allow(I18n).to receive(:t).with('conversations.survey.response', link: expected_url) - .and_return("Please rate this conversation, #{expected_url}") - expect(presenter.outgoing_content).to eq("Please rate this conversation, #{expected_url}") + with_modified_env 'FRONTEND_URL' => 'https://app.chatwoot.com' do + expected_url = "https://app.chatwoot.com/survey/responses/#{conversation.uuid}" + expect(presenter.outgoing_content).to include(expected_url) + end end it 'returns CSAT config message when config exists and dynamically generates survey URL' do - allow(message.inbox).to receive(:csat_config).and_return({ 'message' => 'Custom CSAT message' }) - expected_url = "https://app.chatwoot.com/survey/responses/#{conversation.uuid}" - expect(presenter.outgoing_content).to eq("Custom CSAT message #{expected_url}") + with_modified_env 'FRONTEND_URL' => 'https://app.chatwoot.com' do + allow(message.inbox).to receive(:csat_config).and_return({ 'message' => 'Custom CSAT message' }) + expected_url = "https://app.chatwoot.com/survey/responses/#{conversation.uuid}" + expect(presenter.outgoing_content).to eq("Custom CSAT message #{expected_url}") + end end end end