Send email via SparkPost and C#

SparkPost is yet another email service. It is easy to work with, seems robust, and it will be fairly easy on your client’s budget, as you get 100.000 emails per month for free (as per jan 2017).

A SparkPost email is set up using a template where you specify replacement tokens using a {{tokenname}} syntax:

Sparkpost Template with token replacements

Sparkpost Template with token replacements

Sending an email is done by calling the SparkPost API endpoint. You submit a JSON document containing the recipient email address plus the replacement tokens of your choice.

So let’s send an email.

First I will create a class that can generate the JSON string containing the data to send to SparkPost. The real coder would create objects that get serialized, but for this example, a StringBuilder will do the trick. To send an email we need at least a template name (the name of the SparkPost template), a campaignID (when tracking the emails afterwards) and an email address. The rest is dynamic data (and there is much more to do than just replacing strings but let’s keep it simple):

public byte[] CreateJsonBody(string templateName, string campaignID, string email, string firstName, string lastName)
{
  StringBuilder sb = new StringBuilder();
  sb.Append(@"{");
  sb.AppendFormat(@"  ""campaign_id"": ""{0}"",", campaignID);
  sb.Append(@"  ""recipients"": [");
  sb.Append(@"    {");
  sb.AppendFormat(@"      ""address"": ""{0}"",", email);
  sb.Append(@"      ""substitution_data"": {");
  sb.AppendFormat(@"        ""email"": ""{0}"",", email);
  sb.AppendFormat(@"        ""firstname"": ""{0}"",", firstName);
  sb.AppendFormat(@"        ""lastname"": ""{0}""", lastName);
  sb.Append(@"      }");
  sb.Append(@"    }");
  sb.Append(@"  ],");
  sb.Append(@"  ""content"": {");
  sb.AppendFormat(@"    ""template_id"": ""{0}""", templateName);
  sb.Append(@"  }");
  sb.Append(@"}");

  byte[] body = Encoding.UTF8.GetBytes(sb.ToString());
  return body;
}

Next step is to create a Service that will post the data to the SparkPost service:

using System;
using System.IO;
using System.Net;
using System.Text;

namespace MyNamespace
{
  public class SparkPostService
  {
    private readonly string _SPARKPOSTURL = "https://api.sparkpost.com/api/v1/transmissions?num_rcpt_errors=3";
    private readonly string _sparkPostAuthorizationKey;

    public SparkPostService(string sparkPostAuthorizationKey)
    {
      _sparkPostAuthorizationKey = sparkPostAuthorizationKey;
    }

    public string SendEmail(byte[] jsonBody, out string contentType)
    {
      try
      {
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(_SPARKPOSTURL);

        webRequest.KeepAlive = false;
        webRequest.ServicePoint.ConnectionLimit = 24;
        webRequest.Headers.Add("UserAgent", "MyUserAgent");
        webRequest.ProtocolVersion = HttpVersion.Version10;

        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

        webRequest.ContentType = "application/json";
        webRequest.Accept = "application/json";
        webRequest.Headers.Add("Authorization", _sparkPostAuthorizationKey);
        webRequest.Method = WebRequestMethods.Http.Post;
        webRequest.ContentLength = jsonBody.Length;
        Stream dataStream = webRequest.GetRequestStream();
        dataStream.Write(jsonBody, 0, jsonBody.Length);
        dataStream.Close();
        byte[] bytes;
        using (WebResponse webResponse = webRequest.GetResponse())
        {
          contentType = webResponse.ContentType;
          using (Stream stream = webResponse.GetResponseStream())
          {
            using (MemoryStream memoryStream = new MemoryStream())
            {
              byte[] buffer = new byte[0x1000];
              int bytesRead;
              while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
              {
                memoryStream.Write(buffer, 0, bytesRead);
              }
              bytes = memoryStream.ToArray();
            }
          }
        }
        return Encoding.UTF8.GetString(bytes);
      }
      catch (Exception ex)
      {
        throw new Exception(GetType() + "Failed to retrieve data from '" + _SPARKPOSTURL + "': " + ex.Message, ex);
      }
    }


  }
}

To send an email I can now do the following:

string sparkPostKey = (found in SparkPost);
string contentType;

SparkPostService service = new SparkPostService(sparkPostKey);
string result = service.SendEmail(CreateJsonBody("my-first-email", "myCampaign", "bp@pentia.dk", "Brian", "Pedersen"), out contentType);

The SparkPost authorization key is created inside SparkPost.

SparkPost will now send an email where my name and email is substituted:

Sparkpost Email

Sparkpost Email

MORE TO READ:

About briancaos

Developer at Pentia A/S since 2003. Have developed Web Applications using Sitecore Since Sitecore 4.1.
This entry was posted in c#, General .NET and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s