Transactional email on .net core with Sendwithus
Transactional emails can be a real bugbear for business and for marketers. They are often buried in source code, require dev involvement to update, and lack powerful tracking, analytics and segmentation that we now take for granted in e-mail marketing.
There must be a better way
There is! Enter sendwithus
Sendwithus is a layer on top of your transactional mailer like Sendgrid, Mailgun, etc. Here are the supported mailers.
- Versioned templates in multiple locales/languages
- A/B testing, segmentation, drip campaigns
- Powerful analytics, reporting and per-recipient auditing
- Automation on email events (such as bounces) which can be important in transactional emails, but often overlooked
- Automation on segment.com events - which can allow you to remove the email code from your solution entirely - we won't cover this here but it's pretty cool
OK cool, let's try it
Firstly, you'll need to sign up with sendwithus for free. Be sure to complete the on-boarding when signing up so that it creates a test email template.
Optionally you may signup for and register an email service provider now, but it's not required right away if we're just doing a quick test.
Once that's done, we can write a .net core client.
We're assuming integration into an existing asp.net core project. We'll need:
- Configuration (to store our API keys etc)
- A simple REST client to send emails
- Some objects to encapsulate the request and response, and a way to serialize into sendwithus compatible JSON
Configuration in .net core
web.config is no more. We'll have to make an appsettings.json file. Here's ours:
To load the config, I prefer to load into a class using IOptions<T>. Create a class "SendWithUsConfig.cs"
We need to load the config (and inject it into the IOC container) in Startup.cs - I've only included the bits you need for config here... cherry pick into your own Startup.cs file.
A simple REST client in .net core
At the time of writing WebClient hasn't been ported to .net core, so we need to use HttpClient instead. We will use this in combination with Newtonsoft.Json and a custom contract resolver to map our PascalCase property names to snake_case.
Here's the REST method: https://www.sendwithus.com/docs/api#sending-emails - a sample request might look like:
The Proxy classes
We'll need to make some classes, here's the Request classes (note I've shortened it a bit for this example):
And here is the Response:
Next... Json Serialization
We're using good old Newtonsoft.Json for this. Apart from the fact that our .net classes are PascalCase and the JSON needs to be snake_case, the property names are identical. The solution is to write a ContractResolver with an elegant regex replace.
Lastly, we need a couple of extension methods for serialization that utilize our contract resolver.
The REST Client
You'll note that the API uses basic auth, which is just a base64 encoded username:password - the username is the API key and the password is blank in this case.
The send method uses our 2 new extension methods to convert into API friendly JSON and back again, and the response is returned.
Ordinarily you might call this in a controller, but for the sake of simplicity, I'm just adding it to Startup.cs - this is my "Configure" method:
That's it! It's not a full implementation but it is a good indication of how easy it is to write a JSON client, and then integrate into your .net core solution.