October 01, 2008

How to create SharePoint alerts for lists or list items programmatically

This article will explain how to create SharePoint alert like in the following SharePoint Alert Me page. The illustrated page is the page displayed for a list. In the case of a list item, it's exactly same except that there are no Change Type and Send Alerts for These Changes sections.



Let's imagine a little console application to play the trick...

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
 
namespace UsageInformation
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite mySiteCollection = new SPSite("http://myserver/myspsite"))
            {
                using (SPWeb mySite = mySiteCollection.OpenWeb(mySiteCollection.RootWeb.ID))
                {
                    //Code will be put here
                }
            }
        }
    }
}

The first thing to create the alert is to use the Add method of the Alerts property of the SPUser class. This method return an instance of the SPAlert class.

string myUserLogin = @"MyDomain\MyUser";
SPUser myUser = mySite.Users[myUserLogin];
SPAlert newAlert = myUser.Alerts.Add();

To set the title of the alert, you have to use the Title property of the SPAlert class.

newAlert.Title = "My Title";

The following part of the screen corresponds to the Title property.



If the alert is an alert for a list, you have to specify it in using the AlertType property (enumeration) and to set the List property which must be an instance of the SPList class.

SPList myList = mySite.Lists["My List Name"];
newAlert.AlertType = SPAlertType.List;
newAlert.List = myList;

If the alert is an a alert for a list item, you have to specify it in using the AlertType property (enumeration) and to set the Item property must be an instance of the SPListItem class.

SPListItem myListItem = mySite.Lists["My List Name"].Items.GetItemById(1);
newAlert.AlertType = SPAlertType.Item;
newAlert.Item = myListItem;

Now you have to set the AlertTemplate property. This property must be an instance of the SPAlertTemplate class. Typically, you have to set this property with the template of the list (alert for a list) or with the template of the list containing the list item (alert for a list item).

newAlert.AlertTemplate = myList.AlertTemplate;

or

newAlert.AlertTemplate = myListItem.ParentList.AlertTemplate;

The next property to set is the EventType property (enumeration). This property correspond to Change Type section.

newAlert.EventType = SPEventType.All;

or

newAlert.EventType = SPEventType.Add;

or

newAlert.EventType = SPEventType.Modify;

or

newAlert.EventType = SPEventType.Delete;

or

newAlert.EventType = SPEventType.Discussion;

The following part of the screen corresponds to the EventType property.



The next property to set is the Filter property. This property corresponds to the Send Alerts for These Changes section. In fact, this is string which must be a CAML query.

If Anything change is selected:

newAlert.Filter = string.Empty;

If Someone else changes an item is selected:

newAlert.Filter = string.Format("<Query><Neq><Value type=\"string\">{0}</Value><FieldRef Name=\"Editor/New\"/></Neq></Query>", myUser.Name.ToLower());

If Someone else changes an item created by me is selected:

newAlert.Filter = string.Format("<Query><And><Or><Eq><Value type=\"string\">{0}</Value><FieldRef Name=\"Author/New\"/></Eq><Eq><Value type=\"string\">{0}</Value><FieldRef Name=\"Author/Old\"/></Eq></Or><Neq><Value type=\"string\">{0}</Value><FieldRef Name=\"Editor/New\"/></Neq></And></Query>", myUser.Name.ToLower());

If Someone else changes an item last modified by me is selected:

newAlert.Filter = string.Format("<Query><And><Eq><Value type=\"string\">{0}</Value><FieldRef Name=\"Editor/Old\"/></Eq><Neq><Value type=\"string\">{0}</Value><FieldRef Name=\"Editor/New\"/></Neq></And></Query>", myUser.Name.ToLower());

The following part of the screen corresponds to the Filter property.



The last properties to set are the AlertFrequency and the AlertTime. Note that the AlertTime must be set only if the AlertFrequency is different than Immediate. The AlertTime property is the next time the alert will be executed and the AlertFrequency is the frequence (enumeration): Immediate, Daily or Weekly. These properties correspond to the When to Send Alerts section.

Immediate:

newAlert.AlertFrequency = SPAlertFrequency.Immediate;

Daily and the wanted hour (e.g. 10) is > hour of today:

newAlert.AlertFrequency = SPAlertFrequency.Daily;
newAlert.AlertTime = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 10, 0, 0);

Daily and the wanted hour (e.g. 10) is <= hour of today:

newAlert.AlertFrequency = SPAlertFrequency.Daily;
newAlert.AlertTime = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 10, 0, 0);
newAlert.AlertTime = newAlert.AlertTime.AddDays(1);

Weekly and the wanted day (e.g. friday) is = today and the wanted hour (e.g. 10) is > hour of today:

newAlert.AlertFrequency = SPAlertFrequency.Weekly;
newAlert.AlertTime = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 10, 0, 0);

Weekly and the wanted day (e.g. friday) is = today and the wanted hour (e.g. 10) is <= hour of today:

newAlert.AlertFrequency = SPAlertFrequency.Weekly;
newAlert.AlertTime = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 10, 0, 0);
newAlert.AlertTime = newAlert.AlertTime.AddDays(7);

Weekly and the wanted day (e.g. sunday) is > today (e.g. friday):

newAlert.AlertFrequency = SPAlertFrequency.Weekly;
newAlert.AlertTime = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 10, 0, 0);
newAlert.AlertTime = newAlert.AlertTime.AddDays(2);

Weekly and the wanted day (e.g. wednesday) is < today

newAlert.AlertFrequency = SPAlertFrequency.Weekly;
newAlert.AlertTime = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 10, 0, 0);
newAlert.AlertTime = newAlert.AlertTime.AddDays(5);

The following part of screen corresponds to these properties.



To finish, you have to call the Update method of the instance of SPAlert.

newAlert.Update(true);

6 comments:

Pam said...

Thanks for this great post, Jay.
I am trying to implement automated alerts in discussion boards.
I got this working perfectly at list level.
At item level, I got it working in that the alert is created and an alert email is sent when the item is created or updated. However no alert email is sent when a reply to an item is posted. (When you create an item alert manually, an alert email is generated after a reply is posted).

A couple of interesting things I’ve noticed (? relevance)
1.If you create an item alert with your code, the values in the ImmedSubscriptions table in the content SQL db differ from an item alert created manually.

SQL field.......Code generated alert
ItemID...........Populated
ListUrl...........Blank
ListTitle.........Blank
ListServer
Template........0
AlertType........1073741825 (i.e. item)
Filter............Blank
Properties.......Blank


SQL field.......Manually created alert
Item ID..........Null
ListUrl...........Populated
ListTitle.........Populated
ListServer
Template........108
AlertType........0 (i.e. list)
Filter.............Populated
Properties.......Populated

So when you create an item alert manually, it looks like it’s created a list level alert, with a filter referencing the item. (I tried to implement the automated alert in this way too, but it did not work).
(Having said that, the automatically created list level alert and manually created list level alert had different values in the content db, but it still worked!)

2.When you create an item alert manually, the record in the ImmedSubscriptions table in the content SQL db is not what I would expect – ie. AlertType is List and no ItemID.

Do you have any ideas as to how I can make alerts work on replies?

Thanks
Pam

Jay said...

Dear Pam,

I've post an new article based on your comment which shows How to create an alert for a Discussion Board list item programmatically: http://sharepointlive.blogspot.com/2009/01/how-to-create-sharepoint-alerts-for.html

I hope it will answer your question...

Kind regards,
Jay

JoseLuisO said...

Hello Jay.
I’m working with a site of two ways, intranet and extranet.
I have a problem when WSS insert the URL inside alert’s emails to send the users.
When I create an alert manually WSS detect if I am at intranet o extranet so it work very well, but when I create an alert by code it doesn’t. Always when sent the email insert de URL of extranet.
Have you any idea?

Thanks
Pepe

PS: I’m sorry for my English.

mkamoski said...

This is really nice because it is the only place that I have been able to find any good details on setting the "Alert Filter" property with CAML. I did what you said in the article but, unfortunately, when the alert is viewed manually it does NOT show the correct filter setting property but when I use the object model and view the alert the Alert.Filter property IS set to the CAML as expected. am talking about SP 2007 BTW. Is there a way to set the CAML and at the same time have the correct option shown when manually viewing the Alert???

ninel246 said...

Is there any way to set this up for multiple lists on a site? One email to be sent out for changes pertaining to multiple lists?

themahg said...

Hello Jérôme,
thaks for this post; I have a question about.
I want to know how can I use this code if my alert concern not a SPList but a SocialComent?