-
-
Notifications
You must be signed in to change notification settings - Fork 306
Sender
Sender takes care of email composing and sending.
Sender service’s duties are, primarily, composing emails and sending them. It’ll read emails to be sent from the SendEmail SQS queue, it’ll compose them (which involves parsing liquid tags) and send them through SES.
-
list
: it sends an SNS notification with the campaign and recipient data to thePrecompileEmailTopic
for every recipient contained in a campaign to be sent.
It’ll have two lambda functions, precompileEmail
, that will compose emails and place all the needed info in a SQS queue specific for the given user, and sendEmails
, that will send a batch of emails through SES. There will be as many SQS queues as users, and each of them will have a CloudWatch alarm that triggers a SNS message to the SendEmailsTopic
, so that it notifies sendEmails
that has to send messages from that queue. It'll get a batch of messages and invoke itself when it finishes, in case the queue is not empty.
This service publishes and reads messages from the following SNS topics:
PrecompileEmail
SendEmails
And SQS queues:
-
SendEmail
: actually, this won't be a single queue, but there will be as many queues as users (they'll be named after their IDs, so that user can be easily identified) and one more for all the users in the free plan.
Lists
service publish messages to this topic, including recipient's email and metadata, and the campaign info, for each recipient in a campaign.
{
"userId": "...",
"sender": {
"region": "...",
"apiKey": "...",
"apiSecret": "...",
"ratePerSecond": "...",
"emailAddress": "...",
"fromName": "..."
},
"campaign": {
"id": "...",
"body": "...",
"subject": "..."
},
"recipient": {
"email": "...",
"metadata": {
"name": "...",
"surname": "..."
}
}
}
-
Lists service
will push a notification, that will be fetched byprecompileEmail
function.
{
"userId": "...",
"sender": {
"region": "...",
"apiKey": "...",
"apiSecret": "...",
"ratePerSecond": "...",
"emailAddress": "...",
"fromName": "..."
},
"campaign": {
"id": "...",
"body": "...",
"subject": "..."
},
"recipient": {
"email": "...",
"metadata": {
"name": "...",
"surname": "..."
}
}
}
-
precompileEmail
parses subject and body liquid tags and pushes the message to the SQS queue named after the user ID.
{
"userId": "...",
"sender": {
"region": "...",
"apiKey": "...",
"apiSecret": "...",
"ratePerSecond": "...",
"emailAddress": "...",
"fromName": "..."
},
"campaign": {
"id": "...",
"body": "<parsed_body>",
"subject": "<parsed_subject>"
},
"recipient": {
"email": "..."
}
}
There will be a Cloud Watch alarm set up so that it triggers an SNS event when the queue is not empty. sendEmails
function is subscribed to the topic, and starts sending emails from the given queue.
This is a simplified version of the actual message, generated by Cloud Watch, but the important info is only the queue name.
{
"AlarmName": "queueNotEmpty",
"AlarmDescription": "queueNotEmpty",
"AWSAccountId": "862946620411",
"NewStateValue": "ALARM",
"StateChangeTime": "2016-02-11T15:16:41.224+0000",
"Region": "US - N. Virginia",
"OldStateValue": "OK",
"Trigger": {
"MetricName": "ApproximateNumberOfMessagesVisible",
"Namespace": "AWS/SQS",
"Dimensions": [
{
"name": "QueueName",
"value": "test-queue"
}
]
}
}
-
sendEmails
gets a notification from the topic.
{
"AlarmName": "queueNotEmpty",
"AlarmDescription": "queueNotEmpty",
"AWSAccountId": "862946620411",
"NewStateValue": "ALARM",
"StateChangeTime": "2016-02-11T15:16:41.224+0000",
"Region": "US - N. Virginia",
"OldStateValue": "OK",
"Trigger": {
"MetricName": "ApproximateNumberOfMessagesVisible",
"Namespace": "AWS/SQS",
"Dimensions": [
{
"name": "QueueName",
"value": "test-queue"
}
]
}
}
-
sendEmails
gets a batch of emails from the queue and sends them asynchronously. If the queue it's not empty, it'll invoke itself again, providing the queue info.
precompileEmail
function parses subject and body liquid tags and pushes the message to the queue.
{
"userId": "...",
"sender": {
"region": "...",
"apiKey": "...",
"apiSecret": "...",
"ratePerSecond": "...",
"emailAddress": "...",
"fromName": "..."
},
"campaign": {
"id": "...",
"body": "<parsed_body>",
"subject": "<parsed_subject>"
},
"recipient": {
"email": "..."
}
}