Per Nergård
Jan 17, 2013
  4024
(1 votes)

Programmatically add recipients to an EPiServer Mail recipient list.

I’ve been tinkering a bit with EPiServer Mail recently and the customer wanted the site visitors to be able to subscribe to the site newsletter using the standard built in source.

As you may or may not know the standard mail recipient source only have support for importing recipients from a csv or xml file.

Lucky for me the standard source have some nice methods but on the other side most are private so I used reflector to extract what I needed.

You need to create a Recipient list through importing at least one dummy recipient. The name given to the list is the one we will use to identify it in code.

Below is a code snippet with some comments. I’ve removed the AddSubscriber method in the snippet but it’s included in the complete example user control you can download from the code section. See link at the bottom of this post. In the example you can also see how you can unsubscribe a recipient.

Snippet:

1 //Instantiate a source object 2 EPiServer.Mail.Sources.Internal.Source store = new EPiServer.Mail.Sources.Internal.Source(); 3 4 //From the source we can get the recipientcontainer by name. 5 RecipientContainer container = store.GetRecipientContainer("Recipientlist"); 6 7 //If we don't do a dupe check it's possible to add the same address several times to the same recipientlist. 8 RecipientCollection collection = container.GetRecipients(); 9 var rcp = collection.FirstOrDefault<Recipient>(p => p.Email == textBoxEmail.Text); 10 if (rcp == null) 11 { 12 //Create a new recipent with the given email address. 13 //It's possible to add attributes ie surname, lastname etc to the recipient using 14 //EPiServer.Mail.Core.Attribute. These attributes can be used to personalize the email. 15 Recipient subscriber = new Recipient(textBoxEmail.Text.Trim(), false, null); 16 AddRecipient(subscriber, container, null); 17 }
Code section link:

Example at the code section

Jan 17, 2013

Comments

Jan 17, 2013 07:49 PM

It's nice to see a blog on customizing and extending Mail!

Mar 17, 2013 01:59 PM

Very nice Per. This might just be what I have been looking for!

Mar 17, 2013 02:39 PM

its a shame the example isnt for epimail 7. Im hoping its not too difficult to tweak it to make it work.

Jonathan Roberts
Jonathan Roberts Apr 16, 2013 03:18 PM

Im using Episerver 6 R2 and I cant see how I would add a user to a subscription list and set up pages to subscribe to. I have seen a blog talking about EPSUBSCRIBE but I have no idea what this is and where to set it to TRUE. Do you know of any step by step guides regarding Subscriptions using the CMS? Thanks Jonathan

Apr 22, 2013 08:29 AM

Jonathan: You can read this link http://world.episerver.com/Documentation/Items/Tech-Notes/EPiServer-CMS-6/EPiServer-CMS-60/Subscription---Configuration/.

If I were you I would install a clean demo site and have a look at the demo subscription type.

Don't forget to activate the scheduledjob aswell.

Note that EPiServer subscriptions (not the same as EPi mail) by default only works for logged in users. This is because all subscription info is added to the logged in users profile.

Neil Perry
Neil Perry Apr 30, 2013 11:16 AM

Thanks for this, I am having difficulty adding attributes, would I need to call the store procedures

spEPiServerMailAddAttribute
spEPiServerMailAddAttributeValue

Or is there an API method? I have the Recipient, RecipientContainer and an AttributeCollection but want to add the AttributeCollection values into the database against the Recipient???

or should I implement custom IRecipientSource, the standard gives me everything I need if I can add the Attributes

Apr 30, 2013 01:56 PM

EPiDev: I don't have access to the machine that I did this on. But I think you should be able to do it through an API call.
I think that it should be possible through either when you create the new Recipient. or Add the recipient.

Check the null parameters for what could go in there.

Neil Perry
Neil Perry Apr 30, 2013 02:05 PM

Thanks - Yes, I have now coded a working solution and run some basic tests.

example call e.g Newsletter (RegisterFormModel not shown)

-------------------------------------------

///


/// Add to Newsletter Subscription List
///

///
private void NewsletterSubscription(RegisterFormModel formModel)
{
// Create Attributes
AttributeCollection ac = new AttributeCollection();
ac.Add(new EPiServer.Mail.Core.Attribute("Title", formModel.Title);
ac.Add(new EPiServer.Mail.Core.Attribute("Givenname", formModel.FirstName);
ac.Add(new EPiServer.Mail.Core.Attribute("Surname", formModel.Surname);

// Get recipient list to add to
RecipientLists recipientList = new RecipientLists();
recipientList.Email = formModel.Email;
recipientList.AttributeCollection = ac;
recipientList.Container = "Newsletter"; // example hard coded as named stored in global and RecipientList created using IInitializableModule

// Subscribe to recipient list
recipientList.Subscribe();

}

------------------------------------------- RecipientLists class -------------------------------------------
public class RecipientLists
{
///
/// Subscribers email address
///

public string Email { get; set; }
///
/// Subscribers extended attributes
///

public AttributeCollection AttributeCollection { get; set; }
///
/// Recipient List Container name
///

public string Container { get; set; }


///
/// Recipient Lists
///

public RecipientLists()
{
}

#region Public Methods

public void Subscribe()
{

// Instantiate a source object
Source store = new Source();

// From the source we can get the recipientcontainer by name.
RecipientContainer container = store.GetRecipientContainer(this.Container);

// If we don't do a dupe check it's possible to add the same address several times to the same recipientlist.
if (container != null)
{
RecipientCollection collection = container.GetRecipients();
var rcp = collection.FirstOrDefault(p => p.Email == this.Email);
if (rcp == null)
{
// Create a new recipent with the given email address.
Recipient subscriber = new Recipient(this.Email.Trim(), false, this.AttributeCollection);
AddRecipient(subscriber, container, subscriber.Attributes);
}
}

}

#endregion

#region Private Methods
///
/// Add a Recipient
///

///
///
///
private void AddRecipient(Recipient recipient, RecipientContainer recipientContainer, AttributeCollection attributes)
{

var databaseHandler = ServiceLocator.Current.GetInstance();

databaseHandler.ExecuteTransaction(() =>
{
Guid recipientId = (Guid)databaseHandler.GetScalar("spEPiServerMailAddRecipient", new object[] { recipient.Email, recipient.IsUnsubscribed, recipientContainer.ID });

// Update Number Of Recipients
if (recipientId != null)
{
databaseHandler.GetScalar("spEPiServerMailUpdateRecipientContainer", new object[] { recipientContainer.ID, recipientContainer.Name, recipientContainer.NumOfRecipients + 1 });
}

// Add Attribute Values
AddAttributeValues(recipientId, recipient.Attributes, recipientContainer, databaseHandler);
});

}

///
/// Add Attribute Values to recipient Container and add recipients value for an attribute
///

///
///
///
///
private void AddAttributeValues(Guid recipientId, AttributeCollection attributes, RecipientContainer recipientContainer, IDatabaseHandler databaseHandler)
{

List containerAttributes = new List();

// Populate container Attributes
using (IDataReader dr = databaseHandler.GetReader("spEPiServerMailGetAttributeNamesByContainer", new object[] { recipientContainer.ID }))
{
while (dr.Read())
{
ContainerAttribute containerAttribute = new ContainerAttribute();
containerAttribute.ID = dr.GetInt32(dr.GetOrdinal("intID"));
containerAttribute.Name = dr.GetString(dr.GetOrdinal("strName"));
containerAttributes.Add(containerAttribute);
}
}

var index = 1;
foreach (EPiServer.Mail.Core.Attribute attribute in attributes)
{
int attributeId;

// Check if attribute exists in Container List
var containerAttribute = containerAttributes.FirstOrDefault(x => x.Name == attribute.Name);
if (containerAttribute != null)
{
attributeId = containerAttribute.ID;
}
else
{
// Adds an attribute to a recipient container
attributeId = Convert.ToInt32(databaseHandler.GetScalar("spEPiServerMailAddAttribute", new object[] { attribute.Name, index, recipientContainer.ID }));
}

// Check if attributeId has been set
if (attributeId != 0)
{
// Adds a recipients value for an attribute
databaseHandler.GetScalar("spEPiServerMailAddAttributeValue", new object[] { attributeId, recipientId, attribute.Value });
}

index++;

}
}
#endregion


#region Private
///
/// Container Attribute
///

private class ContainerAttribute
{
public int ID { get; set; }
public string Name { get; set; }
}
#endregion
}

Marcus Andersson
Marcus Andersson Mar 27, 2014 11:03 AM

Per's solution works for EPiServer Mail 5, but does anyone know if it can be done in a similar way when using EPiServer Mail 7?

The reason I ask is because we want to be able to send multiple (unique) mails to a single recipient.

Please login to comment.
Latest blogs
Optimizely Forms: You cannot submit this form because an administrator has turned off data storage.

Do not let this error message scare you, the solution is quite simple!

Tomas Hensrud Gulla | Oct 4, 2024 | Syndicated blog

Add your own tools to the Optimizely CMS 12 admin menu

The menus in Optimizely CMS can be extended using a MenuProvider, and using the path parameter you decide what menu you want to add additional menu...

Tomas Hensrud Gulla | Oct 3, 2024 | Syndicated blog

Integrating Optimizely DAM with Your Website

This article is the second in a series about integrating Optimizely DAM with websites. It discusses how to install the necessary package and code t...

Andrew Markham | Sep 28, 2024 | Syndicated blog

Opticon 2024 - highlights

I went to Opticon in Stockholm and here are my brief highlights based on the demos, presentations and roadmaps  Optimizely CMS SaaS will start to...

Daniel Ovaska | Sep 27, 2024

Required fields support in Optimizely Graph

It's been possible to have "required" properties (value must be entered) in the CMS for a long time. The required metadata haven't been reflected i...

Jonas Bergqvist | Sep 25, 2024

How to write a bespoke notification management system

Websites can be the perfect vehicle for notifying customers of important information quickly, whether it’s the latest offer, an operational message...

Nicole Drath | Sep 25, 2024