Skip to content

Commit

Permalink
Added support for utm tagging links in emails
Browse files Browse the repository at this point in the history
Premailer 1.4 has this support. If you add a UtmCampaign string property
to your email page, you will get utm tagging on all outgoing links.
  • Loading branch information
evest committed Mar 4, 2016
1 parent 3a5dfa8 commit 744f060
Show file tree
Hide file tree
Showing 16 changed files with 145 additions and 754 deletions.
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Newsletter for EPiServer #
A free module for sending newsletters from your EPiServer CMS or Commerce site. You can send the content from pages based on one or more newsletter pagetypes to multiple recipients, using a cloud service or your own SMTP server.
An open source module for sending newsletters from your EPiServer CMS or Commerce site. You can send the content from pages based on one or more newsletter pagetypes to multiple recipients, using a cloud service or your own SMTP server.

>This is a port of the old EPiSendMail (BV Network Newsletter) module from EPiCode, rewritten to support EPiServer CMS and Commerce 7.5 and newer (including CMS 8 and 9).
>This is a port of the old EPiSendMail (BV Network Newsletter) module from EPiCode, rewritten to support EPiServer CMS and Commerce 7.5 and newer (including 8 and 9).
## Features ##
* Create newsletters as pages in EPiServer
Expand Down
2 changes: 1 addition & 1 deletion src/Examples/MVC/EPiCode.Newsletter.Examples.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<iconUrl>http://www.coderesort.com/favicon.ico</iconUrl>
<dependencies>
<dependency id="EPiCode.Newsletter"
version="4.1.2" />
version="4.3.0" />
</dependencies>
</metadata>
<files>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<description>The Commerce package for the EPiCode Newsletter module adds a work item provider for public contact lists in Commerce.</description>
<dependencies>
<dependency id="EPiCode.Newsletter"
version="4.1.2" />
version="4.3.0" />
<dependency id="EPiServer.Commerce.Core" version="[9.0, 10.0)" />
</dependencies>
</metadata>
Expand Down
2 changes: 1 addition & 1 deletion src/Newsletter.SendGrid/EPiCode.Newsletter.SendGrid.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<description>The SendGrid package for the EPiCode Newsletter module allows you to send newsletters using SendGrid (http://www.sendgrid.com)</description>
<dependencies>
<dependency id="EPiCode.Newsletter"
version="4.1.2" />
version="4.3.0" />
<dependency id="Sendgrid"
version="5.1.0" />
<dependency id="SendGrid.SmtpApi"
Expand Down
1 change: 0 additions & 1 deletion src/Newsletter.SendGrid/MailSenderSendGrid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public class SendGridSettings
public string Password { get; set; }
}


/// <summary>
/// Send mail to mailreceivers using SendGrid REST API
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Newsletter/EPiCode.Newsletter.Core.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
</references>

<dependencies>
<dependency id="PreMailer.Net" version="1.2.6" />
<dependency id="PreMailer.Net" version="[1.4.3, 1.5)" />
<dependency id="Microsoft.AspNet.WebApi" version="5.1.2" />
<dependency id="RestSharp" version="104.4.0" />
<dependency id="RestSharp" version="105.2.3" />
<dependency id="EPiServer.CMS.UI.Core" version="[9.0, 10.0)" />
<dependency id="EPiServer.Framework" version="[9.0, 10.0)" />
<dependency id="EPiServer.Logging.Log4Net" version="2.0.0" />
Expand Down
11 changes: 6 additions & 5 deletions src/Newsletter/EPiCode.Newsletter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,12 @@
<HintPath>..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="PreMailer.Net, Version=1.2.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\PreMailer.Net.1.2.7\lib\net40\PreMailer.Net.dll</HintPath>
<Reference Include="PreMailer.Net, Version=1.4.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\PreMailer.Net.1.4.3\lib\net40\PreMailer.Net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="RestSharp, Version=104.4.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.104.4.0\lib\net4\RestSharp.dll</HintPath>
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="StructureMap, Version=3.1.6.186, Culture=neutral, PublicKeyToken=e60ad81abae3c223, processorArchitecture=MSIL">
Expand Down Expand Up @@ -352,6 +352,7 @@
</Compile>
<Compile Include="Initialization\InitializeNewsletterEvents.cs" />
<Compile Include="Library\NewsletterBase.cs" />
<Compile Include="Library\UtmCode.cs" />
<Compile Include="Models\NewsletterListModel.cs" />
<Compile Include="Plugin\Admin\AdminSettingsModel.cs" />
<Compile Include="Plugin\Admin\AdminSettingsRepository.cs" />
Expand Down Expand Up @@ -752,7 +753,7 @@
<ZipDirectory InputPath="$(TmpOutDir)\content" OutputFileName="$(OutDir)\$(ProjectName).zip" OverwriteExistingFile="true" />
<!-- Create the package -->
<Exec Command="$(NugetCommand)" />
<Exec Command="$(CoreNugetCommand)" />
<Exec Command="$(CoreNugetCommand)" />
<!-- Cleanup -->
<RemoveDir Directories="$(TmpOutDir)" />
</Target>
Expand Down
4 changes: 2 additions & 2 deletions src/Newsletter/EPiCode.Newsletter.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
</references>

<dependencies>
<dependency id="PreMailer.Net" version="1.2.6" />
<dependency id="PreMailer.Net" version="[1.4.3, 1.5)" />
<dependency id="Microsoft.AspNet.WebApi" version="5.1.2" />
<dependency id="RestSharp" version="104.4.0" />
<dependency id="RestSharp" version="105.2.3" />
<dependency id="EPiServer.CMS.UI.Core" version="[9.0, 10.0)" />
<dependency id="EPiServer.Framework" version="[9.0, 10.0)" />
<dependency id="EPiServer.Logging.Log4Net" version="2.0.0" />
Expand Down
7 changes: 6 additions & 1 deletion src/Newsletter/Library/MailInformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public class MailInformation
public MailInformation()
{
EnableTracking = true;
}
Utm = new UtmCode();

}

public MailInformation(string from, string subject, string bodyText, string bodyHtml)
{
Expand Down Expand Up @@ -89,5 +91,8 @@ public Dictionary<string, object> CustomProperties
get { return _customProperties; }
set { _customProperties = value; }
}

public UtmCode Utm { get; set; }

}
}
19 changes: 19 additions & 0 deletions src/Newsletter/Library/MailSenderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public virtual MailInformation GetMailMetaData(PageData mailPage)
// Sender address
mailInfo.From = GetMailSender(mailPage);

// Campaign data
mailInfo.Utm.Campaign = GetCampaign(mailPage);

return mailInfo;
}

Expand Down Expand Up @@ -85,6 +88,22 @@ public virtual string GetMailSubject(PageData page)
return subject;
}

/// <summary>
/// Looks for a UtmCampaign property on the page and uses that for Utm tracking
/// </summary>
/// <returns>The campaign name if it exists</returns>
public virtual string GetCampaign(PageData page)
{
string campaign = null;
if (page != null)
{
if (page["UtmCampaign"] != null)
campaign = page["UtmCampaign"].ToString();
}

return campaign;
}

/// <summary>
/// Gets the sender email address.
/// </summary>
Expand Down
12 changes: 9 additions & 3 deletions src/Newsletter/Library/MailSenderBatchBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,15 @@ public override SendMailLog SendEmail(MailInformation mailInfo, JobWorkItems rec
throw new ArgumentNullException("mailInfo", "Missing from address.");
}

// Inline all css
InlineResult cssInline = PreMailer.Net.PreMailer.MoveCssInline(mailInfo.BodyHtml);
mailInfo.BodyHtml = cssInline.Html;
// Inline all css
PreMailer.Net.PreMailer preMailer = new PreMailer.Net.PreMailer(mailInfo.BodyHtml);
if (mailInfo.Utm.HasValidUtmCode)
{
preMailer.AddAnalyticsTags(mailInfo.Utm.Source, mailInfo.Utm.Medium, mailInfo.Utm.Campaign,
mailInfo.Utm.Content);
}
InlineResult cssInline = preMailer.MoveCssInline();
mailInfo.BodyHtml = cssInline.Html;

// Log any messages, debug is only detected
// if we have an HttpContext.
Expand Down
32 changes: 21 additions & 11 deletions src/Newsletter/Library/MailSenderMailgun.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using EPiServer.Logging;
using PreMailer.Net;
using RestSharp;
using RestSharp.Authenticators;
using RestSharp.Deserializers;
// ReSharper disable PossibleMultipleEnumeration

Expand Down Expand Up @@ -101,7 +102,7 @@ public override bool SendMailBatch(MailInformation mail, IEnumerable<JobWorkItem
throw new ArgumentOutOfRangeException("recipients", "Mailgun supports maximum 1000 recipients per batch send.");

RestClient client = new RestClient();
client.BaseUrl = "https://api.mailgun.net/v2";
client.BaseUrl = new Uri("https://api.mailgun.net/v2");
client.Authenticator = new HttpBasicAuthenticator("api", settings.ApiKey);

if(string.IsNullOrEmpty(settings.ProxyAddress) == false)
Expand Down Expand Up @@ -236,16 +237,25 @@ public override MailInformation GetMailInformation(PageData mailPage)
IPopulateCustomProperties customPropertiesProvider = mailPage as IPopulateCustomProperties;
if (customPropertiesProvider == null)
{
// The base class will add custom properties if the page type
// implements that - if NOT, we'll try to add them ourselves
// by looking for special property names relevant to Mailgun
if (mailPage[MAILGUN_CAMPAIGN_PROPERTYNAME] != null)
{
mailInformation.CustomProperties.Add("o:campaign",
mailPage[MAILGUN_CAMPAIGN_PROPERTYNAME]);
}
// The base class will add custom properties if the page type
// implements that - if NOT, we'll try to add them ourselves
// by looking for special property names relevant to Mailgun
var campaign = mailPage[MAILGUN_CAMPAIGN_PROPERTYNAME];
if (campaign != null)
{
mailInformation.Utm.Campaign = campaign.ToString();

}

// Since the Utm Campaign can be set independently, we check if it
// is set, and use it as a Mailgun campaign too
if(string.IsNullOrEmpty(mailInformation.Utm.Campaign) == false)
{
mailInformation.CustomProperties.Add("o:campaign", campaign);
}


if (mailPage[MAILGUN_TAG_PROPERTYNAME] != null)
if (mailPage[MAILGUN_TAG_PROPERTYNAME] != null)
{
mailInformation.CustomProperties.Add("o:tag", mailPage[MAILGUN_TAG_PROPERTYNAME]);
}
Expand Down Expand Up @@ -313,7 +323,7 @@ public List<string> ValidateRecipientList(List<EmailAddress> recipientAddresses,

MailgunSettings settings = GetSettings();
RestClient client = new RestClient();
client.BaseUrl = "https://api.mailgun.net/v2";
client.BaseUrl = new Uri("https://api.mailgun.net/v2");
client.Authenticator = new HttpBasicAuthenticator("api", settings.PublicKey);

if (string.IsNullOrEmpty(settings.ProxyAddress) == false)
Expand Down
71 changes: 71 additions & 0 deletions src/Newsletter/Library/UtmCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
namespace BVNetwork.EPiSendMail.Library
{
public class UtmCode
{
/*
From: https://support.google.com/analytics/answer/1033867?hl=en
*/

public UtmCode()
{
Source = "newsletter";
Medium = "email";
Content = "textlink";
}

public bool HasValidUtmCode
{
get
{
// Requires both source, medium, campaign and content
if(string.IsNullOrEmpty(Source) == false &&
string.IsNullOrEmpty(Medium) == false &&
string.IsNullOrEmpty(Content) == false &&
string.IsNullOrEmpty(Campaign) == false)
{
return true;
}
return false;
}
}


/// <summary>
/// Campaign Source (utm_source)
/// Required. Use utm_source to identify a search engine, newsletter name, or other source.
/// Example: utm_source=google
/// </summary>
public string Source { get; set; }

/// <summary>
/// Campaign Medium(utm_medium)
/// Required.Use utm_medium to identify a medium such as email or cost-per- click.
/// Example: utm_medium=cpc
/// </summary>
public string Medium { get; set; }

/// <summary>
/// Campaign Name(utm_campaign)
/// Required.Used for keyword analysis.Use utm_campaign to identify a specific product promotion or strategic campaign.
/// Example: utm_campaign= spring_sale
/// </summary>
public string Campaign { get; set; }

/// <summary>
/// Campaign Content(utm_content)
/// Used for A/B testing and content-targeted ads.Use utm_content to differentiate ads or links that point to the same URL.
/// Examples: utm_content= logolink or utm_content = textlink
/// </summary>
public string Content { get; set; }

/// <summary>
/// Not used
/// Campaign Term(utm_term)
/// Used for paid search.Use utm_term to note the keywords for this ad.
/// Example: utm_term= running + shoes
/// </summary>
public string Term { get; set; }


}
}
Loading

0 comments on commit 744f060

Please sign in to comment.