From 79ab31eebcf5ceb97f4eb292138432ff12064825 Mon Sep 17 00:00:00 2001 From: Adrien Di Pasquale Date: Wed, 11 Dec 2024 16:13:01 +0100 Subject: [PATCH] =?UTF-8?q?ajout=20du=20mail=20de=20r=C3=A9ponse=20no=5Fre?= =?UTF-8?q?ply?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/handle_inbound_email_job.rb | 8 +++- app/mailers/application_mailer.rb | 7 +++ app/mailers/custom_devise_mailer.rb | 7 +-- app/mailers/users/no_reply_mailer.rb | 30 ++++++++++++ .../users/no_reply_mailer/no_reply.html.slim | 10 ++++ spec/jobs/handle_inbound_email_job_spec.rb | 34 +++++++++++++- .../previews/users/no_reply_mailer_preview.rb | 10 ++++ spec/mailers/users/no_reply_mailer_spec.rb | 46 +++++++++++++++++++ 8 files changed, 144 insertions(+), 8 deletions(-) create mode 100644 app/mailers/users/no_reply_mailer.rb create mode 100644 app/views/mailers/users/no_reply_mailer/no_reply.html.slim create mode 100644 spec/mailers/previews/users/no_reply_mailer_preview.rb create mode 100644 spec/mailers/users/no_reply_mailer_spec.rb diff --git a/app/jobs/handle_inbound_email_job.rb b/app/jobs/handle_inbound_email_job.rb index cb90ac3348..2e2743f2de 100644 --- a/app/jobs/handle_inbound_email_job.rb +++ b/app/jobs/handle_inbound_email_job.rb @@ -21,7 +21,9 @@ def self.uuid_from_email_address(email_address) def perform(sendinblue_hash) @sendinblue_hash = sendinblue_hash.with_indifferent_access - if rdv&.agents&.pluck(:email)&.compact&.any? + if source_mail.to.first.match(/ne-pas-repondre@reply\.[a-z\-\.]+$/) + reply_no_reply + elsif rdv&.agents&.pluck(:email)&.compact&.any? notify_agents else forward_to_default_mailbox @@ -30,6 +32,10 @@ def perform(sendinblue_hash) private + def reply_no_reply + Users::NoReplyMailer.with(source_mail:).no_reply.deliver_now + end + def notify_agents Agents::ReplyTransferMailer.notify_agent_of_user_reply( rdv: rdv, diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index eb945269bc..54390cbaa4 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -28,4 +28,11 @@ def rfc5322_name_and_email(name, email) def default_from domain.support_email end + + def no_reply_from + rfc5322_name_and_email( + "Ne pas répondre - #{domain.name}", + "ne-pas-repondre@#{domain.reply_host_name}" + ) + end end diff --git a/app/mailers/custom_devise_mailer.rb b/app/mailers/custom_devise_mailer.rb index 4626bfa1e3..f2ace15d6e 100644 --- a/app/mailers/custom_devise_mailer.rb +++ b/app/mailers/custom_devise_mailer.rb @@ -24,12 +24,7 @@ def invitation_instructions(record, token, opts = {}) private def set_no_reply_for_users - if @resource.is_a?(User) - mail.from = rfc5322_name_and_email( - "Ne pas répondre - #{domain.name}", - "ne-pas-repondre@#{reply_host_name}" - ) - end + mail.from = no_reply_from if @resource.is_a?(User) end def domain diff --git a/app/mailers/users/no_reply_mailer.rb b/app/mailers/users/no_reply_mailer.rb new file mode 100644 index 0000000000..8083390342 --- /dev/null +++ b/app/mailers/users/no_reply_mailer.rb @@ -0,0 +1,30 @@ +class Users::NoReplyMailer < ApplicationMailer + class UnrecognizableEmailAddressError < StandardError; end + + # @param [Mail::Message] source_mail : le mail initial envoyé par l’usager et transféré par Brevo à notre serveur + def no_reply + mail( + from: no_reply_from, + to: params[:source_mail].from.first, + subject: "Mail non reçu" + ) + end + + private + + def domain + @domain ||= begin + reply_email_domain = params[:source_mail].to.first.split("@").last + case reply_email_domain + when /rdv-solidarites/ + Domain::RDV_SOLIDARITES + when /rdv-service-public/ || /rdv\.anct\.gouv/ || /rdv-mairie/ + Domain::RDV_MAIRIE + when /rdv-aide-numerique/ + Domain::RDV_AIDE_NUMERIQUE + else + raise UnrecognizableEmailAddressError, params[:source_mail].to.to_s + end + end + end +end diff --git a/app/views/mailers/users/no_reply_mailer/no_reply.html.slim b/app/views/mailers/users/no_reply_mailer/no_reply.html.slim new file mode 100644 index 0000000000..92e92ca418 --- /dev/null +++ b/app/views/mailers/users/no_reply_mailer/no_reply.html.slim @@ -0,0 +1,10 @@ +div + p + ' Votre réponse email n’a pas pu être délivrée. + | Cette adresse n’est pas destinée à recevoir des réponses. + p + ' Si vous souhaitez annuler ou décaler un RDV, vous pouvez cliquer sur les liens reçus dans les précédents emails ou bien + = link_to "retrouver tous vos RDV en vous connectant ici", new_user_session_url(host: domain.host_name) + '. + .btn-wrapper + = link_to("J’ai besoin d’aide", contact_url(host: domain.host_name), class: "btn btn-primary") diff --git a/spec/jobs/handle_inbound_email_job_spec.rb b/spec/jobs/handle_inbound_email_job_spec.rb index bf876e31cc..e0a28b6dd7 100644 --- a/spec/jobs/handle_inbound_email_job_spec.rb +++ b/spec/jobs/handle_inbound_email_job_spec.rb @@ -38,7 +38,7 @@ end end - describe "#perform" do + describe "#perform - pour des réponses à des mails transactionnels de RDV" do subject(:perform_job) { described_class.perform_now(sendinblue_payload) } before do @@ -158,4 +158,36 @@ end end end + + describe "#perform - pour des réponses au emails ne-pas-repondre" do + subject(:perform_job) { described_class.perform_now(sendinblue_payload) } + + let(:sendinblue_payload) do + { + Cc: [], + ReplyTo: nil, + Subject: "", + Attachments: [], + Headers: { + "Message-ID": "", + Subject: "", + From: "Bénédicte Ficiaire ", + To: "ne-pas-repondre@reply.rdv-solidarites.fr", + Date: "Thu, 12 May 2022 12:22:15 +0200", + }, + ExtractedMarkdownMessage: "Je souhaite annuler mon RDV", + ExtractedMarkdownSignature: nil, + RawHtmlBody: %(
Je souhaite annuler mon RDV
\n\n), + RawTextBody: "Je souhaite annuler mon RDV\n", + } + end + + it "répond automatiquement à l’usager" do + expect { perform_job }.to change { ActionMailer::Base.deliveries.size }.by(1) + transferred_email = ActionMailer::Base.deliveries.last + expect(transferred_email.to).to eq(["bene_ficiaire@lapin.fr"]) + expect(transferred_email.from).to eq(["ne-pas-repondre@reply.rdv-solidarites-test.localhost"]) + expect(transferred_email.html_part.body.to_s).to include(%(Votre réponse email n’a pas pu être délivrée)) + end + end end diff --git a/spec/mailers/previews/users/no_reply_mailer_preview.rb b/spec/mailers/previews/users/no_reply_mailer_preview.rb new file mode 100644 index 0000000000..28d0ed462a --- /dev/null +++ b/spec/mailers/previews/users/no_reply_mailer_preview.rb @@ -0,0 +1,10 @@ +class Users::NoReplyMailerPreview < ActionMailer::Preview + def no_reply + source_mail = Mail.new do + from "jeanne@barret.fr" + to "ne-pas-repondre@reply.rdv-solidarites-test.localhost" + end + + Users::NoReplyMailer.with(source_mail:).no_reply + end +end diff --git a/spec/mailers/users/no_reply_mailer_spec.rb b/spec/mailers/users/no_reply_mailer_spec.rb new file mode 100644 index 0000000000..0826488a3b --- /dev/null +++ b/spec/mailers/users/no_reply_mailer_spec.rb @@ -0,0 +1,46 @@ +RSpec.describe Users::NoReplyMailer, type: :mailer do + describe "#no_reply" do + context "l’usager a répondu à l’adresse no-reply du même environnement" do + let(:source_mail) do + Mail.new do + from "jeanne@barret.fr" + to "ne-pas-repondre@reply.rdv-solidarites-test.localhost" + end + end + + it "répond depuis la même adresse no-reply" do + mail = described_class.with(source_mail:).no_reply + expect(mail[:from].to_s).to eq(%("Ne pas répondre - RDV Solidarités" )) + expect(mail.to).to eq(["jeanne@barret.fr"]) + end + end + + context "l’usager a répondu à une adresse no-reply d’un autre environnement" do + let(:source_mail) do + Mail.new do + from "jeanne@barret.fr" + to "ne-pas-repondre@reply.rdv-solidarites.fr" + end + end + + it "répond depuis l’adresse no-reply de l’environnement courant" do + mail = described_class.with(source_mail:).no_reply + expect(mail[:from].to_s).to eq(%("Ne pas répondre - RDV Solidarités" )) + expect(mail.to).to eq(["jeanne@barret.fr"]) + end + end + + context "l’adresse n’est pas reconnaissable" do + let(:source_mail) do + Mail.new do + from "jeanne@barret.fr" + to "adresse@surprenante.fr" + end + end + + it "répond depuis l’adresse no-reply de l’environnement courant" do + expect { described_class.with(source_mail:).no_reply.deliver_now }.to raise_exception Users::NoReplyMailer::UnrecognizableEmailAddressError + end + end + end +end