Merge pull request #6076 from betagouv/refactor-sib-api
Manager : corrige l'affichage des emails envoyés (#6076)
This commit is contained in:
commit
2730fac40d
6 changed files with 148 additions and 41 deletions
|
@ -50,23 +50,27 @@ module Manager
|
||||||
def emails
|
def emails
|
||||||
@user = User.find(params[:id])
|
@user = User.find(params[:id])
|
||||||
|
|
||||||
transactionnal_api = ::SibApiV3Sdk::TransactionalEmailsApi.new
|
email_services = [
|
||||||
|
Mailjet::API.new,
|
||||||
|
Sendinblue::API.new
|
||||||
|
]
|
||||||
|
|
||||||
@transactionnal_emails = transactionnal_api.get_transac_emails_list(email: @user.email)
|
@sent_mails = email_services
|
||||||
@events = transactionnal_api.get_email_event_report(email: @user.email, days: 30)
|
.filter(&:properly_configured?)
|
||||||
|
.map { |api| api.sent_mails(@user.email) }
|
||||||
rescue ::SibApiV3Sdk::ApiError => e
|
.flatten
|
||||||
flash.alert = "Impossible de récupérer les emails de cet utilisateur chez Sendinblue : #{e.message}"
|
.sort_by(&:delivered_at)
|
||||||
|
.reverse
|
||||||
end
|
end
|
||||||
|
|
||||||
def unblock_user
|
def unblock_email
|
||||||
@user = User.find(params[:id])
|
@user = User.find(params[:user_id])
|
||||||
|
if Sendinblue::API.new.unblock_user(@user.email)
|
||||||
transactionnal_api = ::SibApiV3Sdk::TransactionalEmailsApi.new
|
flash.notice = "L'adresse email a été débloquée auprès de Sendinblue"
|
||||||
transactionnal_api.smtp_blocked_contacts_email_delete(@user.email)
|
else
|
||||||
|
flash.alert = "Impossible de débloquer cette addresse email auprès de Sendinblue"
|
||||||
rescue ::SibApiV3Sdk::ApiError => e
|
end
|
||||||
flash.alert = "Impossible de débloquer cet email auprès de Sendinblue : #{e.message}"
|
redirect_to emails_manager_user_path(@user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
module EmailHelper
|
module EmailHelper
|
||||||
def event_color_code(email_events)
|
def status_color_code(status)
|
||||||
unique_events = email_events.map(&:event)
|
if status.include?('delivered')
|
||||||
if unique_events.include?('delivered')
|
|
||||||
return 'email-sent'
|
return 'email-sent'
|
||||||
elsif unique_events.include?('blocked') || unique_events.include?('hardBounces')
|
elsif status.include?('blocked') || status.include?('hardBounces')
|
||||||
return 'email-blocked'
|
return 'email-blocked'
|
||||||
else
|
else
|
||||||
return ''
|
return ''
|
||||||
|
|
37
app/lib/mailjet/api.rb
Normal file
37
app/lib/mailjet/api.rb
Normal file
|
@ -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
|
|
@ -16,6 +16,7 @@ class Sendinblue::API
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_contact(email, attributes = {})
|
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 = post_api_request('contacts', email: email, attributes: attributes, updateEnabled: true)
|
||||||
req.on_complete do |response|
|
req.on_complete do |response|
|
||||||
if !response.success?
|
if !response.success?
|
||||||
|
@ -25,6 +26,44 @@ class Sendinblue::API
|
||||||
hydra.queue(req)
|
hydra.queue(req)
|
||||||
end
|
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 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
|
def run
|
||||||
hydra.run
|
hydra.run
|
||||||
@hydra = nil
|
@hydra = nil
|
||||||
|
@ -70,4 +109,8 @@ class Sendinblue::API
|
||||||
def client_key
|
def client_key
|
||||||
Rails.application.secrets.sendinblue[:api_v3_key]
|
Rails.application.secrets.sendinblue[:api_v3_key]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parse_date(date)
|
||||||
|
date.is_a?(String) ? Time.zone.parse(date) : date
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
3
app/lib/sent_mail.rb
Normal file
3
app/lib/sent_mail.rb
Normal file
|
@ -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
|
|
@ -17,10 +17,14 @@
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section class="main-content__body">
|
<section class="main-content__body">
|
||||||
<h2>Historique des email</h2>
|
<h2 style="font-size: 1.3em; margin: 24px 0 8px 0">Historique des email</h2>
|
||||||
<% if @transactionnal_emails.present? %>
|
<% if @sent_mails.present? %>
|
||||||
<p>
|
<p>
|
||||||
Cet historique contient les 30 derniers jours. Pour un recherche plus fine, il faut <a href="https://app-smtp.sendinblue.com/log">fouiller les logs</a>.
|
Cet historique contient les 30 derniers jours.
|
||||||
|
Pour un recherche plus fine, il faut fouiller les
|
||||||
|
<a href="https://app-smtp.sendinblue.com/log">logs de SendInblue</a>
|
||||||
|
ou
|
||||||
|
<a href="https://app.mailjet.com/contacts/subscribers/contact_list">de Mailjet</a>.
|
||||||
</p>
|
</p>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -29,17 +33,22 @@
|
||||||
Émetteur
|
Émetteur
|
||||||
</th>
|
</th>
|
||||||
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
|
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
|
||||||
Sujet
|
Objet
|
||||||
</th>
|
</th>
|
||||||
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
|
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
|
||||||
Date
|
Date
|
||||||
</th>
|
</th>
|
||||||
|
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
|
||||||
|
Statut
|
||||||
|
</th>
|
||||||
|
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
|
||||||
|
Prestataire
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<% @transactionnal_emails&.transactional_emails&.reverse&.each do |email| %>
|
<% @sent_mails.each do |email| %>
|
||||||
<% matching_events = @events&.events&.select { |e| e.message_id == email.message_id } %>
|
<tr class="<%= status_color_code(email.status) %>">
|
||||||
<tr class="<%= event_color_code(matching_events) %>">
|
|
||||||
<td class="cell-data cell-data--string" style="">
|
<td class="cell-data cell-data--string" style="">
|
||||||
<%= email.from %>
|
<%= email.from %>
|
||||||
</td>
|
</td>
|
||||||
|
@ -47,26 +56,28 @@
|
||||||
<%= email.subject %>
|
<%= email.subject %>
|
||||||
</td>
|
</td>
|
||||||
<td class="cell-data cell-data--string" style="text-align: center;">
|
<td class="cell-data cell-data--string" style="text-align: center;">
|
||||||
<%= 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) %>
|
||||||
</td>
|
</td>
|
||||||
<td class="cell-data cell-data--string" style="text-align: center;">
|
<td class="cell-data cell-data--string" style="text-align: center;">
|
||||||
<ul>
|
<%= email.status %>
|
||||||
|
</td>
|
||||||
<% matching_events.each do |event|%>
|
<td class="cell-data cell-data--string" style="">
|
||||||
<li><%= event.event %></li>
|
<%= link_to email.service_name, email.external_url, style: 'text-decoration: underline' %>
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<% else %>
|
<% else %>
|
||||||
<p>Historique indisponible. Cet email n'existe pas chez Sendinblue, ou nous n'avons pas réussi à échanger.
|
<p>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 <a href="https://app-smtp.sendinblue.com/log">fouiller leurs logs</a>.</p>
|
Vous pouvez éventuellement fouiller les
|
||||||
|
<a href="https://app-smtp.sendinblue.com/log">logs de SendInBlue</a>
|
||||||
|
ou
|
||||||
|
<a href="https://app.mailjet.com/contacts/subscribers/contact_list">de Mailjet</a>.
|
||||||
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<h2>Problèmes potentiel</h2>
|
<h2 style="font-size: 1.3em; margin: 24px 0 8px 0">Problèmes potentiel</h2>
|
||||||
|
|
||||||
<% if @user.confirmed? %>
|
<% if @user.confirmed? %>
|
||||||
<p><strong>Compte activé, n'arrive pas à se connecter</strong> ? <button class="btn btn-secondary btn-small" onclick="reveal_email('#activated-cant-connect')">Voir la suggestion d’email</button></p>
|
<p><strong>Compte activé, n'arrive pas à se connecter</strong> ? <button class="btn btn-secondary btn-small" onclick="reveal_email('#activated-cant-connect')">Voir la suggestion d’email</button></p>
|
||||||
|
@ -95,7 +106,11 @@ https://www.demarches-simplifiees.fr/users/password/new
|
||||||
|
|
||||||
Cordialement</pre>
|
Cordialement</pre>
|
||||||
<% end %>
|
<% end %>
|
||||||
<p><strong>Compte <a href="https://app-smtp.sendinblue.com/block">bloqué</a> chez Sendinblue ?</strong> Vous pouvez le <%= link_to('débloquer', manager_user_unblock_email_path(@user), method: :put, class: 'button', remote: true) %> puis lui envoyer <button class="btn btn-secondary btn-small" onclick="reveal_email('#unblock_email')">le mail suivant</button></p>
|
<p>
|
||||||
|
<strong>Compte <a href="https://app-smtp.sendinblue.com/block">bloqué</a> chez Sendinblue ?</strong>
|
||||||
|
Vous pouvez le <%= link_to('débloquer', manager_user_unblock_email_path(@user), method: :put, class: 'button') %>
|
||||||
|
puis lui envoyer <button class="btn btn-secondary btn-small" onclick="reveal_email('#unblock_email')">le mail suivant</button>
|
||||||
|
</p>
|
||||||
<pre class="hidden" id="unblock_email">
|
<pre class="hidden" id="unblock_email">
|
||||||
Bonjour,
|
Bonjour,
|
||||||
|
|
||||||
|
@ -106,12 +121,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
|
Nous vous invitons donc à autoriser les emails émis depuis demarches-simplifiees.fr
|
||||||
|
|
||||||
Bien cordialement</pre>
|
Bien cordialement
|
||||||
<p><strong>Problème chez Sendinblue ?</strong> Regardez leur <a href="https://status.sendinblue.com/">page de status</a>. <button class="btn btn-secondary btn-small" onclick="reveal_email('#pb-sendinblue')">Voir la suggestion d’email</button></p>
|
</pre>
|
||||||
|
<p>
|
||||||
|
<strong>Problème chez Sendinblue ?</strong>
|
||||||
|
Regardez leur <a href="https://status.sendinblue.com/">page de status</a>.
|
||||||
|
<button class="btn btn-secondary btn-small" onclick="reveal_email('#pb-sendinblue')">Voir la suggestion d’email</button>
|
||||||
|
</p>
|
||||||
<pre class="hidden" id="pb-sendinblue">
|
<pre class="hidden" id="pb-sendinblue">
|
||||||
Bonjour,
|
Bonjour,
|
||||||
Désolé, notre prestataire d'envoi d'email subit actuellement des soucis avec sa plateforme ;
|
Désolé, notre prestataire d'envoi d'email subit actuellement des soucis avec sa plateforme ;
|
||||||
vous allez recevoir cet email sous peu.
|
vous allez recevoir cet email sous peu.
|
||||||
|
|
||||||
Bien cordialement,</pre>
|
Bien cordialement,
|
||||||
|
</pre>
|
||||||
</section>
|
</section>
|
||||||
|
|
Loading…
Add table
Reference in a new issue