A FreeMarker Converter in C#

Not long ago, I was asked if SparkPost supported FreeMarker templates. At the time, I had to say no, but I hate saying “no”, so I immediately init’d a new Git project and called it FreeMarker-Converter-in-C-Sharp. You can get to it here if you want to pull a copy.

You may ask “why C#?” and not PHP or NodeJS, or Go, or insert-language-choice-here. Well, why not? In this case, the customer I was speaking with worked in a C# environment, so it made the most sense. I also started on a PHP version and could finish it quickly if the need arose. A conversion tool like this can be ported to virtually any language that supports PCRE. It really does not matter what language you write it in, porting it to the language du jour should be trivial.

What’s a FreeMarker?

First let’s talk about FreeMarker and why you might care. FreeMarker is an open source Apache project that uses Java to link templates and substitution data with data tables to create highly dynamic documents. These documents can be then used for HTML pages, email and other things. In this particular case, the customer was using FreeMarker to create email messages in a similar way to how SparkPost uses templates to create dynamic messages. Unfortunately, the FreeMarker markup language is just different enough that it will not work natively in SparkPost. What is needed is a conversion tool for pre-processing FreeMarker templates into SparkPost templates.

SparkPost includes a full-featured template engine that provides things like data substitutions, conditional branching, and array iteration. FreeMarker has similar functionality, but the substitution language is significantly different. The meat of the project was in matching up the most used FreeMarker functions with corresponding SparkPost functions and then building a process to transform the FreeMarker template into a correct SparkPost template. The final step is to save the new template in a way that it can be used with SparkPost.

Template Transformation

As you take a look through the Git project, you’ll notice a few interesting things. There are FLAGS, INTERPOLATIONS, and COMMENTS to account for. FLAGS are used to tell Java there is an action happening, like an item list or if condition. COMMENTS are just comments in the document that should not be printed or interpreted in any way. INTERPOLATIONS are what SparkPost calls substitutions.

  • FLAGS look like this <#action … > and can be things like <#list …> or <#if …>
  • COMMENTS look like this <#– comment –>
  • INTERPOLATIONS look like this ${variable} or ${Recipient.lead.firstname} or ${Gears.unsubscribe()} or ${Recipient.lead.firstname[0]!””}.

That last one is interesting because the [0]!”” part actually means “only show this if it is a non-blank value”

There are also ASSIGNMENTS which are really just variable declarations.
IE: <#assign countrycontact=Recipient.contact.localname[0]!”” />

In SparkPost, that is equivalent to
“substitution_data” : {“countrycontact” :”Recipient.contact.localname”}

All of the most common FreeMarker functions have SparkPost equivalents, so the code really just has to find them using PCRE and replace them. For instance:

${Recipient.lead.firstname[0]!””} becomes {{Recipient.lead.firstname}}
<#assign myvalue=12 /> becomes “substitution_data” : {“myvalue” :”12″}
<#if> blah </#if> becomes {{if …}} blah {{end}}

This is all done with some fancy PCRE footwork like this:

Then it is all reassembled into a SparkPost formatted transmission template ready to call with the Transmissions API.

The bulk of the transformation logic lives in a single C# file (program.cs), which is 221 lines of C# including comments. The code will create INBOX and OUTBOX folders if they don’t exist and then try to process everything in the INBOX as a FreeMarker template. Put your raw FreeMarker templates in the INBOX and run the code. Your converted SparkPost templates will be placed in the OUTBOX without damaging the originals.

Feel free to fork at will, pull requests welcome, and leave any comments or suggestions in the Github repo.



*Today’s blog is written by Darren Cauthon, community member and original author of the SparkPost C# Library. Thanks for the post, Darren! We hope you enjoy.

How to Use the SparkPost Metrics API with C#

In our first two tutorials on using SparkPost with C#, we learned how to send an email from a C# application and how to manipulate email templates using C# code. You’ll want to start there to get the SparkPost C# library installed via NuGet, it’s all good stuff.

But most of the time when you send an email from your app, you’ll also want to know what happened to that message: was it delivered? Did your user open it or even click on link in the message body? Visibility into message disposition and performance is crucial for many apps.

That’s why the SparkPost C# library includes methods for getting important metrics about the emails that you send. Today, we’re going to look at how they work.

There are two mechanisms for getting these analytics: pushing and pulling. With pushing (via a webhook), you can get your metrics streamed in near real-time as SparkPost posts the information to a web endpoint that you provide. A future tutorial will provide some help on setting up a webhook endpoint in a standard .Net MVC application.

Today, however, we’ll focus on pull-style API-based queries for your metrics via the C# wrapper. You can query the SparkPost API for just about any type of information you’d want about the emails you send within the past few weeks, and the API will return the information you requested.

This tutorial will also provide some insight into the library’s design, and how you can use it for other SparkPost API calls you’d want to make.

A SparkPost Metrics API Quick Start

When using the C# SparkPost library, the first place to check is the SparkPost API documentation. The C# library was written to mirror the SparkPost web API as closely as possible. Naturally, the API docs include specific information about metrics. Look there to see what sorts of metrics you might want to gather.

Let’s try the first method in the docs: Gathering metrics by domain. Let’s build a sample request that will return the number of accepted and bounced emails that were sent to Gmail or Yahoo Mail. Here is C# code that will return your results.

Here are your results:

It’s really that easy. All of the metrics data you want, for this and any of the other API metric methods, will be returned in this form. The only real question is what data you want, so check out the SparkPost API documentation and make the query you want!

How to Keep the SparkPost C# Library Up-To-Date with API Changes

One of the difficulties in using a library for a service like SparkPost is keeping up-to-date with changes. SparkPost is always adding new features to its API, but are those new features reflected in the library? Sometimes there is a lag between when API developers add features and when library authors add support.

The C# library tries to mitigate those issues by allowing you to extend the library, yourself. The example above showed how to use the MetricsQuery, but you can pass any object to use as a query—so long as it matches the style and naming of the SparkPost service.

Here is a concrete example: SparkPost developers added a new API feature, the ability to pass a “limit” to limit the size of your result. That feature was not available when the MetricsQuery class was written, so it does not have Limit available. So does that mean you can’t use Limit in C#? No, that’s still available to you – just have to pass it yourself. Like with an anonymous object:

Another method would be to extend the MetricsQuery and add an “int Limit { get; set; }” property. But the main point to notice is that so long as you stay consistent with the SparkPost documentation and naming, this library can extend itself.

The SparkPost C# Library Is Open Source

I’m the original author of the SparkPost library, but there are more than a dozen developers who have contributed code to this library, like this Metrics library, which was contributed by Aaron Sherber. Each developer on this library was either a SparkPost employee or a customer of SparkPost, all of us with an interest in making this library work well.

As the SparkPost API expands, this library will expand with it. And we’re accepting contributions from anybody who wants to help!

— Darren Cauthon

Any questions for us? Give us a shout on Twitter or in our community slack channel, we’d love to talk C#, Metrics, APIs – whatever’s on your mind.