demarches-simplifiees / demarches-simplifiees.fr

Dématérialiser et simplifier les démarches administratives
https://www.demarches-simplifiees.fr
GNU Affero General Public License v3.0
190 stars 89 forks source link

Monitoring des mails / mails prioritaires #8395

Open mfo opened 1 year ago

mfo commented 1 year ago
mfo commented 1 year ago

@colinux ; au besoin, partage d'un petit snippet a lancer ds la console de dev pour jouer ac les API dolist d'envoie.

class Dolist::API
  EMAIL_MESSAGES_ADRESSES_REPLIES = "https://apiv9.dolist.net/v1/email/messages/addresses/replies?AccountID=%{account_id}"
  EMAIL_MESSAGES_ADRESSES_PACKSENDERS = "https://apiv9.dolist.net/v1/email/messages/addresses/packsenders?AccountID=%{account_id}"
  EMAIL_SENDING_TRANSACTIONAL = "https://apiv9.dolist.net/v1/email/sendings/transactional?AccountID=%{account_id}"
  EMAIL_SENDING_TRANSACTIONAL_SEARCH = "https://apiv9.dolist.net/v1/email/sendings/transactional/search?AccountID=%{account_id}"

  def send_email(mail)
      url = format(EMAIL_SENDING_TRANSACTIONAL, account_id: account_id)
      body = {
        "TransactionalSending": {
          "Type": "TransactionalService",
          "Contact": {
            "FieldList": [
              {
                "ID": EMAIL_KEY,
                "Value": mail.to.first
              }
            ]
          },
          "Message": {
            "Name": mail['X-Dolist-Message-Name'].value,
            "Subject": mail.subject,
            "SenderID": sender_id,
            "ForceHttp": true,
            # "ReplyAddressID": 0,
            "Format": "text",
            "DisableOpenTracking": true,
            "IsTrackingValidated": true
          },
          "MessageContent": {
            "SourceCode": "string",
            "EncodingType": "UTF8",
            "EnableTrackingDetection": true
          },
          "ScheduleDate": 1.seconds.from_now
        }
      }
      puts body.inspect
      post(url, body.to_json)
    end

  def client_key
    "this-is-a-secret"
  end

  def account_id
    "same"
  end

  def senders
    url = format(EMAIL_MESSAGES_ADRESSES_PACKSENDERS, account_id: account_id)
    get(url)
  end

  def replies
    url = format(EMAIL_MESSAGES_ADRESSES_REPLIES, account_id: account_id)
    get(url) 
  end

  def sender_id 
    Dolist::API.new.senders.dig("ItemList", 0, "Pack", "ID")
  end  

  def get(url)
    response = Typhoeus.get(url, headers:).tap do
      self.class.save_rate_limit_headers(_1.headers)
    end

    JSON.parse(response.response_body)
  end

end

email =DeviseUserMailer.confirmation_instructions(User.where(email: 'martin.fourcade@beta.gouv.fr').first, SecureRandom.hex)
Dolist::API.new.send_email('martin.fourcade@beta.gouv.fr')
mfo commented 1 year ago

@colinux un autre snippet d'une method d'envoie via une delivery method repluggé sur une API (ses) ; on pourra loadbalancer genre dolist_smtp: 49, dolist_api: 1

# frozen_string_literal: true

class Sesv2Mailer
  def initialize(mail); end

  # see: https://docs.aws.amazon.com/sdk-for-ruby/v2/api/Aws/SESV2/Client.html#send_email-instance_method
  def deliver!(mail)
    ses.send_email(
      {}.merge({ from_email_address: mail.from.first, destination: { to_addresses: mail.to } },
               content_options(mail),
               unsubscribe_list_options(mail))
    )
  rescue Aws::SESV2::Errors::ServiceError => e
    Rails.logger.info "Email not sent. Error message: #{e}"
  ensure
    log_to_console(mail)
  end

  private

  def content_options(mail)
    if mail.html_part.nil? && mail.text_part.nil?
      raw_content_options(mail)
    else
      body_and_text_content_options(mail)
    end
  end

  def raw_content_options(mail)
    {
      content: {
        raw: {
          data: mail.encoded
        }
      }
    }
  end

  def body_and_text_content_options(mail)
    {
      content: {
        simple: {
          body: {
            html: { charset: encoding, data: mail.html_part.body.decoded },
            text: { charset: encoding, data: mail.text_part.body.decoded }
          },
          subject: {
            data: mail.subject,
            charset: encoding
          }
        }
      }
    }
  end

  def unsubscribe_list_options(mail)
    return {} if mail['X-topicname'].nil? # devise admin...

    {
      configuration_set_name: Rails.env,
      list_management_options: {
        contact_list_name: 'one-list',
        topic_name: mail['X-topicname'].value
      }
    }
  end

  def log_to_console(mail)
    return if Rails.env.production? || Rails.env.staging?

    email_console_log(mail.to, mail.from, mail.subject, mail.html_part.body.decoded)
  end

  def encoding
    'UTF-8'
  end

  def ses
    @ses ||= Aws::SESV2::Client.new(
      region: 'eu-west-3',
      access_key_id: Rails.application.credentials.dig(:aws, :access_key_id),
      secret_access_key: Rails.application.credentials.dig(:aws, :secret_access_key)
    )
  end
end
mfo commented 1 year ago

update ; attente de réponse de dolist (cf, mail. semblerait que l'api de send transactionnel soit activable a la demande). pour le moment ils ne sont pas pressé de répondre.