From 76e74003ad54af4c421a34ef1bdb9bbe030b58fe Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Thu, 8 Apr 2021 17:13:39 +0200 Subject: [PATCH 1/4] manager: fix SendInBlue emails --- app/controllers/manager/users_controller.rb | 9 +----- app/helpers/email_helper.rb | 7 ++--- app/lib/sendinblue/api.rb | 34 ++++++++++++++++++++ app/lib/sent_mail.rb | 3 ++ app/views/manager/users/emails.html.erb | 35 +++++++++++---------- 5 files changed, 60 insertions(+), 28 deletions(-) create mode 100644 app/lib/sent_mail.rb diff --git a/app/controllers/manager/users_controller.rb b/app/controllers/manager/users_controller.rb index 0fcdc27e8..604ba99d7 100644 --- a/app/controllers/manager/users_controller.rb +++ b/app/controllers/manager/users_controller.rb @@ -49,14 +49,7 @@ module Manager def emails @user = User.find(params[:id]) - - transactionnal_api = ::SibApiV3Sdk::TransactionalEmailsApi.new - - @transactionnal_emails = transactionnal_api.get_transac_emails_list(email: @user.email) - @events = transactionnal_api.get_email_event_report(email: @user.email, days: 30) - - rescue ::SibApiV3Sdk::ApiError => e - flash.alert = "Impossible de récupérer les emails de cet utilisateur chez Sendinblue : #{e.message}" + @sent_mails = Sendinblue::API.new.sent_mails(@user.email) end def unblock_user diff --git a/app/helpers/email_helper.rb b/app/helpers/email_helper.rb index 9bd74dc65..60cfb1fde 100644 --- a/app/helpers/email_helper.rb +++ b/app/helpers/email_helper.rb @@ -1,9 +1,8 @@ module EmailHelper - def event_color_code(email_events) - unique_events = email_events.map(&:event) - if unique_events.include?('delivered') + def status_color_code(status) + if status.include?('delivered') return 'email-sent' - elsif unique_events.include?('blocked') || unique_events.include?('hardBounces') + elsif status.include?('blocked') || status.include?('hardBounces') return 'email-blocked' else return '' diff --git a/app/lib/sendinblue/api.rb b/app/lib/sendinblue/api.rb index 7cfe78ae9..2e287999e 100644 --- a/app/lib/sendinblue/api.rb +++ b/app/lib/sendinblue/api.rb @@ -16,6 +16,7 @@ class Sendinblue::API end def update_contact(email, attributes = {}) + # TODO: refactor this to use the official SiB SDK (by using contact create + attributes) req = post_api_request('contacts', email: email, attributes: attributes, updateEnabled: true) req.on_complete do |response| if !response.success? @@ -25,6 +26,35 @@ class Sendinblue::API hydra.queue(req) end + # Get messages sent to a user through SendInBlue. + # + # Returns an array of SentMail objects. + def sent_mails(email_address) + client = ::SibApiV3Sdk::TransactionalEmailsApi.new + @events = client.get_email_event_report(email: email_address, days: 30).events + + if @events.blank? + Rails.logger.info "SendInBlue::API: no messages found for email address '#{email_address}'" + return [] + end + + @events.group_by(&:message_id).values.map do |message_events| + latest_event = message_events.first + SentMail.new( + from: latest_event.from, + to: latest_event.email, + subject: latest_event.subject, + delivered_at: parse_date(latest_event.date), + status: latest_event.event, + service_name: 'SendInBlue', + external_url: 'https://app-smtp.sendinblue.com/log' + ) + end + rescue ::SibApiV3Sdk::ApiError => e + Rails.logger.error e.message + [] + end + def run hydra.run @hydra = nil @@ -70,4 +100,8 @@ class Sendinblue::API def client_key Rails.application.secrets.sendinblue[:api_v3_key] end + + def parse_date(date) + date.is_a?(String) ? Time.zone.parse(date) : date + end end diff --git a/app/lib/sent_mail.rb b/app/lib/sent_mail.rb new file mode 100644 index 000000000..828dd62e1 --- /dev/null +++ b/app/lib/sent_mail.rb @@ -0,0 +1,3 @@ +# Represent an email sent using an external API +class SentMail < Struct.new(:from, :to, :subject, :delivered_at, :status, :service_name, :external_url, keyword_init: true) +end diff --git a/app/views/manager/users/emails.html.erb b/app/views/manager/users/emails.html.erb index 6af6416d3..b0b4ccfd8 100644 --- a/app/views/manager/users/emails.html.erb +++ b/app/views/manager/users/emails.html.erb @@ -18,9 +18,9 @@

Historique des email

-<% if @transactionnal_emails.present? %> +<% if @sent_mails.present? %>

- Cet historique contient les 30 derniers jours. Pour un recherche plus fine, il faut fouiller les logs. + Cet historique contient les 30 derniers jours. Pour un recherche plus fine, il faut fouiller les logs de SendInblue ou de Mailjet.

@@ -29,41 +29,44 @@ Émetteur + + - <% @transactionnal_emails&.transactional_emails&.reverse&.each do |email| %> - <% matching_events = @events&.events&.select { |e| e.message_id == email.message_id } %> - + <% @sent_mails.each do |email| %> + + <% end %>
- Sujet + Objet Date + Statut + + Prestataire +
<%= email.from %> - <%= email.subject %> + <%= email.subject %> - <%= l(email.date.is_a?(String) ? Time.zone.parse(email.date) : email.date, format: '%d/%m/%y à %H:%M') %> + <%= l(email.delivered_at, format: :long) %> -
    - - <% matching_events.each do |event|%> -
  • <%= event.event %>
  • - <% end %> -
+ <%= email.status %> +
+ <%= link_to email.service_name, email.external_url, style: 'text-decoration: underline' %>
<% else %> -

Historique indisponible. Cet email n'existe pas chez Sendinblue, ou nous n'avons pas réussi à échanger. - Vous pouvez éventuellement fouiller leurs logs.

+

Historique indisponible. Cette adresse email n'existe pas chez nos prestataires d'envoi, ou nous n'avons pas réussi à en charger des données. + Vous pouvez éventuellement fouiller les logs de SendInBlue ou de Mailjet.

<% end %>

Problèmes potentiel

From 5e8327ff0930932310ab11453a1de389f8b734a3 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Thu, 8 Apr 2021 17:46:11 +0200 Subject: [PATCH 2/4] manager: refactor SendInBlue unblock action --- app/controllers/manager/users_controller.rb | 16 ++++++++-------- app/lib/sendinblue/api.rb | 9 +++++++++ app/views/manager/users/emails.html.erb | 20 +++++++++++++++----- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/app/controllers/manager/users_controller.rb b/app/controllers/manager/users_controller.rb index 604ba99d7..0dd325515 100644 --- a/app/controllers/manager/users_controller.rb +++ b/app/controllers/manager/users_controller.rb @@ -52,14 +52,14 @@ module Manager @sent_mails = Sendinblue::API.new.sent_mails(@user.email) end - def unblock_user - @user = User.find(params[:id]) - - transactionnal_api = ::SibApiV3Sdk::TransactionalEmailsApi.new - transactionnal_api.smtp_blocked_contacts_email_delete(@user.email) - - rescue ::SibApiV3Sdk::ApiError => e - flash.alert = "Impossible de débloquer cet email auprès de Sendinblue : #{e.message}" + def unblock_email + @user = User.find(params[:user_id]) + if Sendinblue::API.new.unblock_user(@user.email) + flash.notice = "L'adresse email a été débloquée auprès de Sendinblue" + else + flash.alert = "Impossible de débloquer cette addresse email auprès de Sendinblue" + end + redirect_to emails_manager_user_path(@user) end end end diff --git a/app/lib/sendinblue/api.rb b/app/lib/sendinblue/api.rb index 2e287999e..476240c9b 100644 --- a/app/lib/sendinblue/api.rb +++ b/app/lib/sendinblue/api.rb @@ -55,6 +55,15 @@ class Sendinblue::API [] end + def unblock_user(email_address) + client = ::SibApiV3Sdk::TransactionalEmailsApi.new + client.smtp_blocked_contacts_email_delete(email_address) + true + rescue ::SibApiV3Sdk::ApiError => e + Rails.logger.error e.message + false + end + def run hydra.run @hydra = nil diff --git a/app/views/manager/users/emails.html.erb b/app/views/manager/users/emails.html.erb index b0b4ccfd8..764b7a2e0 100644 --- a/app/views/manager/users/emails.html.erb +++ b/app/views/manager/users/emails.html.erb @@ -98,8 +98,12 @@ https://www.demarches-simplifiees.fr/users/password/new Cordialement <% end %> -

Compte bloqué chez Sendinblue ? Vous pouvez le <%= link_to('débloquer', manager_user_unblock_email_path(@user), method: :put, class: 'button', remote: true) %> puis lui envoyer

- +

+ Problème chez Sendinblue ? + Regardez leur page de status. + +

+Bien cordialement, +
From 773c18babf2f89be57c76e1ec1683be77b681c83 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Thu, 8 Apr 2021 17:14:02 +0200 Subject: [PATCH 3/4] manager: improve clarity of emails page --- app/views/manager/users/emails.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/manager/users/emails.html.erb b/app/views/manager/users/emails.html.erb index 764b7a2e0..7e528e00f 100644 --- a/app/views/manager/users/emails.html.erb +++ b/app/views/manager/users/emails.html.erb @@ -17,7 +17,7 @@
-

Historique des email

+

Historique des email

<% if @sent_mails.present? %>

Cet historique contient les 30 derniers jours. Pour un recherche plus fine, il faut fouiller les logs de SendInblue ou de Mailjet. @@ -69,7 +69,7 @@ Vous pouvez éventuellement fouiller les logs de SendInBlue ou de Mailjet.

<% end %> -

Problèmes potentiel

+

Problèmes potentiel

<% if @user.confirmed? %>

Compte activé, n'arrive pas à se connecter ?

From 16f695031b8c221f5959d42805901d7a10bb6093 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 13 Apr 2021 08:57:26 +0000 Subject: [PATCH 4/4] manager: add Mailjet emails to the sent emails list --- app/controllers/manager/users_controller.rb | 13 +++++++- app/lib/mailjet/api.rb | 37 +++++++++++++++++++++ app/views/manager/users/emails.html.erb | 12 +++++-- 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 app/lib/mailjet/api.rb diff --git a/app/controllers/manager/users_controller.rb b/app/controllers/manager/users_controller.rb index 0dd325515..2e2698e7a 100644 --- a/app/controllers/manager/users_controller.rb +++ b/app/controllers/manager/users_controller.rb @@ -49,7 +49,18 @@ module Manager def emails @user = User.find(params[:id]) - @sent_mails = Sendinblue::API.new.sent_mails(@user.email) + + email_services = [ + Mailjet::API.new, + Sendinblue::API.new + ] + + @sent_mails = email_services + .filter(&:properly_configured?) + .map { |api| api.sent_mails(@user.email) } + .flatten + .sort_by(&:delivered_at) + .reverse end def unblock_email diff --git a/app/lib/mailjet/api.rb b/app/lib/mailjet/api.rb new file mode 100644 index 000000000..e97845cdf --- /dev/null +++ b/app/lib/mailjet/api.rb @@ -0,0 +1,37 @@ +class Mailjet::API + def properly_configured? + [Mailjet.config.api_key, Mailjet.config.secret_key].all?(&:present?) + end + + # Get messages sent to a user through SendInBlue. + # + # Returns an array of SentMail objects. + def sent_mails(email_address) + contact = Mailjet::Contact.find(email_address) + if contact.nil? + Rails.logger.info "Mailjet::API: no contact found for email address '#{email_address}'" + return [] + end + + messages = Mailjet::Message.all( + contact: contact.attributes['id'], + from_ts: 30.days.ago.to_datetime.rfc3339, + show_subject: true + ) + + messages.map do |message| + SentMail.new( + from: nil, + to: email_address, + subject: message.attributes['subject'], + delivered_at: message.attributes['arrived_at'], + status: message.attributes['status'], + service_name: 'Mailjet', + external_url: 'https://app.mailjet.com/contacts/subscribers/contact_list' + ) + end + rescue Mailjet::ApiError => e + Rails.logger.error e.message + [] + end +end diff --git a/app/views/manager/users/emails.html.erb b/app/views/manager/users/emails.html.erb index 7e528e00f..7224bd62f 100644 --- a/app/views/manager/users/emails.html.erb +++ b/app/views/manager/users/emails.html.erb @@ -20,7 +20,11 @@

Historique des email

<% if @sent_mails.present? %>

- Cet historique contient les 30 derniers jours. Pour un recherche plus fine, il faut fouiller les logs de SendInblue ou de Mailjet. + Cet historique contient les 30 derniers jours. + Pour un recherche plus fine, il faut fouiller les + logs de SendInblue + ou + de Mailjet.

@@ -66,7 +70,11 @@
<% else %>

Historique indisponible. Cette adresse email n'existe pas chez nos prestataires d'envoi, ou nous n'avons pas réussi à en charger des données. - Vous pouvez éventuellement fouiller les logs de SendInBlue ou de Mailjet.

+ Vous pouvez éventuellement fouiller les + logs de SendInBlue + ou + de Mailjet. +

<% end %>

Problèmes potentiel