Comment stocker les notifications Amazon SNS pour les e-mails Amazon SES dans DynamoDB à l'aide de Lambda ?

Dernière mise à jour : 11/11/2021

J'utilise le service Amazon Simple Notification Service (Amazon SNS) pour recevoir des notifications sur les e-mails envoyés via Amazon Simple Email Service (Amazon SES). Comment configurer une fonction AWS Lambda pour stocker ces notifications dans une table Amazon DynamoDB ?

Solution

Remarque : l'exemple de fonction Lambda suivant peut être utilisé comme modèle pour écrire des données dans un système de gestion de la relation client (CRM) ou d'autres destinations.

(Prérequis) Configurer une adresse e-mail ou un domaine Amazon SES avec une rubrique Amazon SNS configurée pour recevoir des notifications d'Amazon SES

Créer une table DynamoDB

1.    Créez une table dans DynamoDB avec les attributs suivants :
Pour le nom de table, saisissez SESNotifications.
Pour la Clé de partition primaire, entrez SESMessageId.
Pour la Clé de tri primaire, entrez SnsPublishTime.

2.    Pour permettre à Lambda d'interroger la table et de créer un rapport Amazon SES, configurez les index secondaires suivants :

Nom d'index Clé de partition Clé de tri
SESMessageType-Index SESMessageType (Chaîne) SnsPublishTime (Chaîne)
SESMessageComplaintType-Index SESComplaintFeedbackType (Chaîne) SnsPublishTime (Chaîne)

Remarque : vous pouvez ajouter d'autres index secondaires si nécessaire.

Pour plus d'informations sur la création d'une table dans DynamoDB, consultez Démarrer avec Amazon DynamoDB.

Ajoutez des autorisations au rôle IAM de la fonction Lambda qui lui permettent d'appeler la table DynamoDB

Créer un rôle AWS Identity and Access Management (IAM). Configurez le rôle pour permettre à votre fonction Lambda d'appeler l'API DynamoDB:PutItem en procédant comme suit :

Remarque : la création et l'utilisation d'un nouveau rôle IAM pour différentes fonctions Lambda font partie des bonnes pratiques. Évitez de réutiliser un même rôle dans plusieurs fonctions.

1.    Dans le panneau de navigation de gauche de la console IAM, choisissez Roles (Rôles).

2.    Sélectionnez Create role (Créer un rôle).

3.    Pour Select type of trusted entity (Sélectionner le type d'entité de confiance), sélectionnez Service AWS.

4.    Pour Choose a use case (Choisir un cas d'utilisation), choisissez Lambda. Choisissez Next: Permissions (Étape suivante : autorisations).

5.    Pour Attach permissions policies (Attacher des stratégies d'autorisations), cochez la case à côté de la stratégie gérée AWSLambdaBasicExecutionRole . Ensuite, choisissez Next: Tags (Suivant : Balises).

6.    (Facultatif) Ajoutez des identifications IAM au rôle correspondant à votre cas d'utilisation. Pour plus d'informations, consultez Identification des ressources IAM.

7.    Sélectionnez Next: Review (Suivant : vérification).

8.    Pour Role name* (Nom du rôle), saisissez lambda_ses_execution.

9.    Sélectionnez Create role (Créer un rôle).

10.    Revenez à la vue IAM Roles (Rôles IAM) et choisissez le rôle que vous avez créé.

11.    Dans la vue Permissions (Autorisations), choisissez Add inline policy (Ajouter une stratégie en ligne).

12.    Dans l'onglet Visual editor (Éditeur visuel), sélectionnez Choose a service (Choisir un service).

13.    Choisissez DynamoDB.

14.    Dans le champ de recherche Actions, saisissez PutItem. Dans la liste déroulante qui s'affiche, cochez la case en regard de PutItem.

15.    Pour Resources (Ressources), choisissez Specific (Spécifique).

16.    Sélectionnez Add ARN (Ajouter ARN). Ensuite, dans la zone de texte qui s'affiche, saisissez l'Amazon Resource Name (ARN) de votre table DynamoDB.

17.    Choisissez Review policy (Examiner une politique).

18.    Pour Name (Nom), saisissez un nom pour la politique.

19.    Choisissez Create policy (Créer une politique).

Exemple de politique IAM en ligne qui accorde l'accès à une table DynamoDB

------------------------IAM Policy Begins---------------------------
{
    "Version": "2012-10-17",
    "Statement": [
         {
            "Sid": "Stmt1428510662000",
            "Effect": "Allow",
            "Action": [
                "DynamoDB:PutItem"
            ],
            "Resource": [
                "arn:aws:DynamoDB:us-east-1:12345678912:table/SESNotifications"
            ]
        }
    ]
}
------------------------IAM Policy Ends-----------------------------

Créez une fonction Lambda pour traiter les notifications Amazon SES et Amazon SNS

Créez la fonction Lambda sesnotificationscode à l'aide de l'exemple de code de fonction suivant.

Important :veillez à attribuer à la fonction le rôle lambda_ses_execution que vous avez créé.

Exemple de code de fonction Lambda qui vérifie les notifications Amazon SNS et place les notifications Amazon SES associées dans une table DynamoDB

Important : remplacez la valeur du paramètre TableName SESNotifications par le nom de votre table DynamoDB.

--------------------------Lambda Code Begins------------------------
console.log("Loading event");

var aws = require("aws-sdk");
var ddb = new aws.DynamoDB({ params: { TableName: "SESNotifications" } });

exports.handler = function (event, context, callback) {
  console.log("Received event:", JSON.stringify(event, null, 2));

  var SnsPublishTime = event.Records[0].Sns.Timestamp;
  var SnsTopicArn = event.Records[0].Sns.TopicArn;
  var SESMessage = event.Records[0].Sns.Message;

  SESMessage = JSON.parse(SESMessage);

  var SESMessageType = SESMessage.notificationType;
  var SESMessageId = SESMessage.mail.messageId;
  var SESDestinationAddress = SESMessage.mail.destination.toString();
  var LambdaReceiveTime = new Date().toString();

  if (SESMessageType == "Bounce") {
    var SESreportingMTA = SESMessage.bounce.reportingMTA;
    var SESbounceSummary = JSON.stringify(SESMessage.bounce.bouncedRecipients);
    var itemParams = {
      Item: {
        SESMessageId: { S: SESMessageId },
        SnsPublishTime: { S: SnsPublishTime },
        SESreportingMTA: { S: SESreportingMTA },
        SESDestinationAddress: { S: SESDestinationAddress },
        SESbounceSummary: { S: SESbounceSummary },
        SESMessageType: { S: SESMessageType },
      },
    };
    ddb.putItem(itemParams, function (err, data) {
      if (err) {
        callback(err)
      } else {
        console.log(data);
        callback(null,'')
      }
    });
  } else if (SESMessageType == "Delivery") {
    var SESsmtpResponse1 = SESMessage.delivery.smtpResponse;
    var SESreportingMTA1 = SESMessage.delivery.reportingMTA;
    var itemParamsdel = {
      Item: {
        SESMessageId: { S: SESMessageId },
        SnsPublishTime: { S: SnsPublishTime },
        SESsmtpResponse: { S: SESsmtpResponse1 },
        SESreportingMTA: { S: SESreportingMTA1 },
        SESDestinationAddress: { S: SESDestinationAddress },
        SESMessageType: { S: SESMessageType },
      },
    };
    ddb.putItem(itemParamsdel, function (err, data) {
      if (err) {
        callback(err)
      } else {
        console.log(data);
        callback(null,'')
      }
    });
  } else if (SESMessageType == "Complaint") {
    var SESComplaintFeedbackType = SESMessage.complaint.complaintFeedbackType;
    var SESFeedbackId = SESMessage.complaint.feedbackId;
    var itemParamscomp = {
      Item: {
        SESMessageId: { S: SESMessageId },
        SnsPublishTime: { S: SnsPublishTime },
        SESComplaintFeedbackType: { S: SESComplaintFeedbackType },
        SESFeedbackId: { S: SESFeedbackId },
        SESDestinationAddress: { S: SESDestinationAddress },
        SESMessageType: { S: SESMessageType },
      },
    };
    ddb.putItem(itemParamscomp, function (err, data) {
      if (err) {
        callback(err)
      } else {
        console.log(data);
        callback(null,'')
      }
    });
  }
};
------------------------Lambda Code Ends----------------------------

Abonnez la fonction Lambda à une ou plusieurs rubriques Amazon SNS

Pour abonner une fonction à une rubrique Amazon SNS à l'aide de la console Amazon SNS

1.    Dans le panneau de navigation gauche de la console Amazon SNS, choisissez Topics (Rubriques).

2.    Identifiez la rubrique SNS utilisée dans Amazon SES pour les notifications de retour à l'expéditeur. Par exemple, une rubrique SNS nommée ses_notifications_repo.

3.    Choisissez l'ARN de la rubrique SNS. La page Topic Details (Détails de la rubrique) s'ouvre.

4.    Choisissez Create Subscription (Créer un abonnement).

5.    Pour Protocol (Protocole), choisissez AWS Lambda.

6.    Pour Endpoint (Point de terminaison), saisissez l'ARN de votre fonction Lambda.

7.    Choisissez Create Subscription (Créer un abonnement).

8.    (Facultatif) Répétez les étapes 1 à 7 pour chaque rubrique de notification supplémentaire que vous souhaitez abonner à votre fonction.

Pour abonner une fonction à une rubrique Amazon SNS à l'aide de la console Lambda

1.    Ouvrez la page Functions (Fonctions) dans la console Lambda.

2.    Choisissez la fonction Lambda que vous avez créée.

3.    Dans le panneau Function overview (Présentation de la fonction), cliquez sur le bouton+Add trigger (Ajouter un déclencheur).

4.    Dans la liste déroulante Trigger configuration (Configuration du déclencheur), choisissez SNS. Un panneau de configuration s'affiche.

5.    Dans la liste déroulante de SNS topic (Rubrique SNS), choisissez la rubrique SNS à laquelle vous souhaitez abonner la fonction.

6.    Choisissez Add (Ajouter).

7.    (Facultatif) Répétez les étapes 1 à 6 pour chaque rubrique de notification supplémentaire que vous voulez abonner à votre fonction.

Testez la configuration en envoyant un message Amazon SES pour appeler la fonction Lambda

Pour envoyer un message de test Amazon SES, utilisez l'une des adresses de simulateur de boîte aux lettres disponibles.

Remarque : l'utilisation de l'une des adresses de simulateur de boîte aux lettres lors de l'envoi de messages de test éviter d'impacter négativement vos métriques de délivrabilité SES.

Lorsque vous envoyez le message de test, Amazon SES publie une notification dans la rubrique SNS. Amazon SNS envoie la notification à Lambda sous la forme d'un objet de notification d'événement SES JSON-escaped dans l'objet d'événement SNS.

Pour créer des exemples d'événements pour les tests locaux à l'aide de la console Lambda, consultez Exemples de données d'événement qu'Amazon SES publie sur Amazon SNS.

Important : vous ne pouvez pas utiliser les exemples de données d'événement qu'Amazon SES publie sur Amazon SNS lorsqu'elles sont écrites pour envoyer des messages de test dans la console Lambda. Pour utiliser les exemples de test dans la console Lambda, vous devez remplacer la clé de message eventType par NotificationType. Si vous ne modifiez pas la clé de message, le test échoue.

Télécharger un rapport depuis DynamoDB pour afficher des notifications Amazon SES

Pour interroger, trier et télécharger le contenu de la table DynamoDB en tant que fichier CSV, procédez comme suit :

1.    Dans la console DynamoDB, choisissez la table SESNotifications.

2.    Choisissez l'onglet Items (Éléments).

3.    Créez une recherche par Requête ou par Analyse. Pour plus d'informations, consultez Bonnes pratiques d'interrogation et d'analyse de données.

Remarque : vous pouvez utiliser l'exportation de table DynamoDB pour planifier un téléchargement du fichier vers un compartiment Amazon Simple Storage Service (Amazon S3) à intervalles réguliers. Pour plus d'informations, consultez Exportation de données de table DynamoDB vers Amazon S3.