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.
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
-
+
+ Compte bloqué chez Sendinblue ?
+ Vous pouvez le <%= link_to('débloquer', manager_user_unblock_email_path(@user), method: :put, class: 'button') %>
+ puis lui envoyer
+
+
Bonjour,
votre email était bloqué par notre prestataire.
@@ -109,12 +113,18 @@ Cela peut arriver si vous, ou ceux qui gèrent vos emails, marquent nos emails c
Nous vous invitons donc à autoriser les emails émis depuis demarches-simplifiees.fr
-Bien cordialement
-
Problème chez Sendinblue ? Regardez leur page de status.
+Bien cordialement
+
+
+ Problème chez Sendinblue ?
+ Regardez leur page de status.
+
+
Bonjour,
Désolé, notre prestataire d'envoi d'email subit actuellement des soucis avec sa plateforme ;
vous allez recevoir cet email sous peu.
-Bien cordialement,
+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.