Code for sending emails from SharePoint

 

A client needed to customize SharePoint email notifications in order to send some activity feeds, plus some alerts coming from a custom list that were targeted to audiences (through a custom Audiences field). Let’s see… what about adding a SPAlert to that list plus an alert handler, finally customize AlertTemplates.xml (better said, copying it to another file, setting that one as the template, etc – never change OOB files!)? Should do it, right?

Should. Such a powerful word.

First, SPAlert.Filter doesn’t seem to support CAML queries predicating over Multichoice fields, and that’s exactly what I needed. (I assume so because, tried to predicate on other fields and worked great.) Second issue, SPAlert.Filter seems to have a limitation on the length of the CAML string. Then, SPAlerts can be set to immediate, daily or weekly frequency. Guess what: client wanted daily, weekly and monthly updates.

Enough.

What about customizing the task? That’s what I ended up doing, and it simply worked like a charm. (Needless to say, it needs templating the body, avoiding hardcoding last run date, wrapping it into a job definition, etc etc, but the core is there.)

Here’s the code:

// build mail body
StringBuilder body = new StringBuilder();

// get items starting after last run of this job
DateTime lastRun = new DateTime(2011, 9, 8);
string lastRunForQuery = SPUtility.CreateISO8601DateTimeFromSystemDateTime(lastRun);

// get items from custom list
string siteUrl = "https://localhost/sites/blank";
using (SPSite site = new SPSite(siteUrl))
{
    string query = @"<Where>
                            <And>
                                <Gt>
                                    <FieldRef Name='Created' />
                                    <Value IncludeTimeValue='TRUE' Type='DateTime'>" + lastRunForQuery + @"</Value>
                                </Gt>
                                <Or>
                                    <Contains>
                                        <FieldRef Name='Audiences' />
                                        <Value Type='MultiChoice'>Audience1</Value>
                                    </Contains>
                                    <Contains>
                                        <FieldRef Name='Audiences' />
                                        <Value Type='MultiChoice'>Audience2</Value>
                                    </Contains>
                                </Or>
                            </And>
                        </Where>";
    SPQuery q = new SPQuery();
    q.Query = query;
    q.RowLimit = 50;// perf: limit # of items
    // perf: set q.ViewFields in order to return only required fields
    SPListItemCollection items = site.RootWeb.Lists["Test"].GetItems(q);
    foreach (SPListItem i in items)
    {
        body.Append(i.Title);
    }

    // get items from user feed
    SPServiceContext sc = SPServiceContext.GetContext(site);
    UserProfileManager upm = new UserProfileManager(sc);
    UserProfile up = upm.GetUserProfile(@"corp\user");
    ActivityManager am = new ActivityManager(up, sc);
    foreach (ActivityEvent e in am.GetActivitiesByUser(up, lastRun))
    {
        body.Append(e.TemplateVariable);
    }

    // send email
    SPUtility.SendEmail(site.RootWeb, false, true, "user@corp.com", "Notifications", body.ToString(), false);
}