I was originally using AWS SES for mail sending from my Lambda, but it has very slow delivery.
I then decided to switch to MailJet and use their API for sending mails. I am using the NuGet package, V3.1 of the API, and pretty much the sample code from MailJet to send the mails async.
public async Task<bool> SendEmailAsync(EmailModel model)
{
Boolean sent = false;
MailjetClient client = new MailjetClient(Environment.GetEnvironmentVariable("EmailAPIKey"), Environment.GetEnvironmentVariable("EmailAPISecret"))
{
Version = ApiVersion.V3_1,
};
MailjetRequest request = new MailjetRequest
{
Resource = Send.Resource,
}.Property(Send.Messages, new JArray {
new JObject {
{"From", new JObject {
{"Email", Environment.GetEnvironmentVariable("SenderEmail")},
{"Name", Environment.GetEnvironmentVariable("SenderEmailName")}
}
},
{"HTMLPart", model.EmailHtmlBody},
{"Subject", model.EmailSubject},
{"TextPart", model.EmailTextBody},
{"To", new JArray {
new JObject {
{"Email", model.EmailTo},
{"Name", model.EmailTo}
}
}}
}
});
try
{
MailjetResponse response = await client.PostAsync(request);
if (response.IsSuccessStatusCode)
{
sent = true;
LambdaLogger.Log(string.Format("Total: {0}, Count: {1}\n", response.GetTotal(), response.GetCount()));
LambdaLogger.Log(response.GetData().ToString());
}
else
{
sent = false;
LambdaLogger.Log(string.Format("StatusCode: {0}\n", response.StatusCode));
LambdaLogger.Log(string.Format("ErrorInfo: {0}\n", response.GetErrorInfo()));
LambdaLogger.Log(response.GetData().ToString());
LambdaLogger.Log(string.Format("ErrorMessage: {0}\n", response.GetErrorMessage()));
}
}
catch (Exception mailFail)
{
sent = false;
LambdaLogger.Log(string.Format("Failed: {0}\n", mailFail.Message.ToString() + " : " + mailFail.InnerException.Message.ToString()));
}
return sent;
}
When I test the code locally everything works just fine.
When I deploy the lambda to AWS and call the method for sending mails, it is completely random if the mail is send. I am guessing it is the async part which fails for some reason, I am hoping someone can help me to figure this out, because for now I am stuck on this issue.
Or if someone can tell me how to get Amazon SES to send without delay.
From the question:
it is completely random
And from a comment:
it seems like the lambda just keeps running and does not wait for the reply from MailJet
It is sounding like an async/await issue, but probably not where you think. Note that you are correctly awaiting the result of the MailJet operation:
MailjetResponse response = await client.PostAsync(request);
But that's only in this method. This method is of course async
:
public async Task<bool> SendEmailAsync(EmailModel model)
When you call this method, do you await
it? The method where you call it, that should also be async
. Do you await that? Basically, are you "async all the way down"?
It sounds like somewhere in the codebase there's an async operation that's being invoked and then forgotten.