SharePoint 2010 Custom Timer Job - Send an Email
1. Open Visual Studio 2010 and goto FILE -> New Project -> Empty SharePoint Project.
2. Select SharePoint 2010 under Installed Templates under left Navigation.
3. Select Deploy as Farm Solution Option and replace https://<<ServerName>>/ with proper URL of the SharePoint site.
4. Right Click on the Project and Create a New Item
5. Select Code from Installed Templates of left Navigation and name the file as "NotificationTimerJob.cs"
6. Paste the following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using System.Net.Mail;
namespace NotificationCustomTimerJob
{
public class NotificationTimerJob : Microsoft.SharePoint.Administration.SPJobDefinition
{
/// <summary>
/// Default Consructor
/// </summary>
public NotificationTimerJob()
: base()
{
}
/// <summary>
/// Parameterized Constructor
/// </summary>
/// <param name="jobName">Name of Job to display in central admin</param>
/// <param name="service">SharePoint Service </param>
/// <param name="server">Name of the server</param>
/// <param name="targetType">job type is for content db or job</param>
public NotificationTimerJob(string jobName, SPService service, SPServer server, SPJobLockType targetType)
: base(jobName, service, server, targetType)
{
}
/// <summary>
/// Parameterized Constructor
/// </summary>
/// <param name="jobName"></param>
/// <param name="webApplication"></param>
public NotificationTimerJob(string jobName, SPWebApplication webApplication)
: base(jobName, webApplication, null, SPJobLockType.ContentDatabase)
{
this.Title = "Email Notification Job";
}
/// <summary>
/// Execute method called when the timer job starts executing. It runs on "DB News Announcements" list which checks for all
/// approved annoucements and sends out an email to all users for all approved news.
/// </summary>
/// <param name="contentDbId"></param>
public override void Execute(Guid contentDbId)
{
string from = string.Empty;
string smtpAddress = string.Empty;
string to = "someone@somecompany.com";
string subject = "Email Notification";
string body = "<h1> Email Sending from Email Notification Job </h1>";
SPSecurity.RunWithElevatedPrivileges(delegate()
{
// get a reference to the current site collection's content database
SPWebApplication webApplication = this.Parent as SPWebApplication;
SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];
// get a reference to the "Tasks" list in the RootWeb of the first site collection in the content database
SPWeb rootWeb = contentDb.Sites[0].RootWeb;
// Get the DB News Announcements List
SPList listjob = rootWeb.Lists.TryGetList("Tasks");
// Get sender address from web application settings
from = rootWeb.Site.WebApplication.OutboundMailSenderAddress;
// Get SMTP address from web application settings
smtpAddress = rootWeb.Site.WebApplication.OutboundMailServiceInstance.Server.Address;
// Send an email if the news is approved
bool emailSent = SendMail(smtpAddress, subject, body, true, from, to, null, null);
if (listjob != null && emailSent)
{
SPListItem newListItem = listjob.Items.Add();
newListItem["Title"] = string.Concat("Email Notification Sent at : ", DateTime.Now.ToString());
newListItem.Update();
}
});
}
/// <summary>
/// Send an email to indented users
/// </summary>
/// <param name="smtpAddress">SMTP address to sending email</param>
/// <param name="subject">subject of email</param>
/// <param name="body">body of email</param>
/// <param name="isBodyHtml">whether body is html or text</param>
/// <param name="from">from address</param>
/// <param name="to">to users(multiple email address can be seperated by comma(,) )</param>
/// <param name="cc">cc users</param>
/// <param name="bcc">bcc users</param>
/// <returns>Status whether email successfully sent or not</returns>
public bool SendMail(string smtpAddress, string subject, string body, bool isBodyHtml, string from, string to, string cc, string bcc)
{
bool mailSent = false;
SmtpClient smtpClient = null;
try
{
// Assign SMTP address
smtpClient = new SmtpClient();
smtpClient.Host = smtpAddress;
//Create an email message
MailMessage mailMessage = new MailMessage(from, to, subject, body);
if (!String.IsNullOrEmpty(cc))
{
MailAddress CCAddress = new MailAddress(cc);
mailMessage.CC.Add(CCAddress);
}
if (!String.IsNullOrEmpty(bcc))
{
MailAddress BCCAddress = new MailAddress(bcc);
mailMessage.Bcc.Add(BCCAddress);
}
mailMessage.IsBodyHtml = isBodyHtml;
// Send the email
smtpClient.Send(mailMessage);
mailSent = true;
}
catch (Exception)
{
mailSent = false;
}
return mailSent;
}
}
}
7. Now add a new feature
Rename the feature to NotificationTimerJobFeature and add add an event receiver for registering the timer job and scheduling it for every 5 minutes. Change the scope to Site
9. Paste the below code snippet in event receiver for Feature activation and deactivation.
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using System.Linq;
namespace NotificationCustomTimerJob.Features.NotificationTimerJobFeature
{
/// <summary>
/// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
/// </summary>
/// <remarks>
/// The GUID attached to this class may be used during packaging and should not be modified.
/// </remarks>
[Guid("67388410-1290-41d2-8645-5a1203b27bc4")]
public class NotificationTimerJobFeatureEventReceiver : SPFeatureReceiver
{
// Name of the Timer Job, but not the Title which is displayed in central admin
private const string List_JOB_NAME = "NotificationTimerJob";
// Uncomment the method below to handle the event raised after a feature has been activated.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPSite site = properties.Feature.Parent as SPSite;
// make sure the job isn't already registered
site.WebApplication.JobDefinitions.Where(t => t.Name.Equals(List_JOB_NAME)).ToList().ForEach(j => j.Delete());
// install the job
NotificationTimerJob listLoggerJob = new NotificationTimerJob(List_JOB_NAME, site.WebApplication);
SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 59;
schedule.Interval = 5;
listLoggerJob.Schedule = schedule;
listLoggerJob.Update();
});
}
// Uncomment the method below to handle the event raised before a feature is deactivated.
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPSite site = properties.Feature.Parent as SPSite;
// delete the job
site.WebApplication.JobDefinitions.Where(t => t.Name.Equals(List_JOB_NAME)).ToList().ForEach(j => j.Delete());
});
}
// Uncomment the method below to handle the event raised after a feature has been installed.
//public override void FeatureInstalled(SPFeatureReceiverProperties properties)
//{
//}
// Uncomment the method below to handle the event raised before a feature is uninstalled.
//public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
//{
//}
// Uncomment the method below to handle the event raised when a feature is upgrading.
//public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
//{
//}
}
}
10. Deploy the feature by right click on the project and deploy.
11. Now navigate to Central Administration -> Monitoring -> Review Job Definitions under Timer Jobs section.
12. Administrator can change the settings of the timer job schedule. Now this job sends an email and adds a Task in the task list.
Comments
Anonymous
February 07, 2012
I'm trying to create a job that will send an email every time it runs. i used you code to create it and I made some changes. It seems as it is not working at all when it is not connected to the Tasks list. Can you please help?Anonymous
February 08, 2012
What error you are getting? Are you able to debug it?Anonymous
March 04, 2012
Can't see NotificationTimerJob class from Event Receiver The type or namespace name 'NotificationTimerJob' could not be found (are you missing a using directive or an assembly reference?) C:VSProjectMyProject2MyProject2FeaturesNotificationTimerJobFeatureNotificationTimerJobFeature.EventReceiver.cs 35 17 MyProject2Anonymous
March 04, 2012
Never mind. Wrong namespace. How to deploy to another server? Thanks.Anonymous
March 12, 2012
It is a WSP package, SharePoint automatically propogates wsp deployment to all serversAnonymous
May 08, 2012
I've just seen this linked from the Technet forums. Good work, I'll be making use of this I suspect. Thanks for the contribution.Anonymous
May 10, 2012
I got this error message Error 3 Error occurred in deployment step 'Add Solution': Failed to create receiver object from assembly "NotificationCustomTimerJob, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bd543d68a922f01a", class "$SharePoint.Type.ab8160cd-5f1d-4021-8636-64008c6b0c8b.FullName$" for feature "NotificationCustomTimerJob_NotificationTimerJobFeature" (ID: f4c6159e-d292-403c-b5fc-fab3c39508b9).: System.ArgumentNullException: Value cannot be null. Parameter name: type at System.Activator.CreateInstance(Type type, Boolean nonPublic) at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_ReceiverObject() 0 0 NotificationCustomTimerJobAnonymous
June 04, 2012
I need to send a weekly email for changes made to a site's lists. One email listing changes made to multiple lists. Is this possible?Anonymous
June 21, 2012
hi, all are configured well,mail not sendAnonymous
July 31, 2012
LAkshitha I get the same error, were you able to fix it?Anonymous
February 11, 2013
The comment has been removedAnonymous
February 25, 2013
Hi Vicky, You need to configure out bound email settings.Anonymous
May 16, 2013
Could you please show how to implement looping through all items and sending the item urls through an e-mail of the custom timer job? Pls! Pls!Anonymous
July 18, 2013
thx very usefulAnonymous
December 30, 2013
excellent postAnonymous
March 12, 2014
Hey LAkshitha and Guru I got this error class "$SharePoint.Type.ab8160cd-5f1d-4021-8636-64008c6b0c8b.FullName$" for feature "NotificationCustomTimerJob_NotificationTimerJobFeature" (ID: f4c6159e-d292-403c-b5fc-fab3c39508b9).: System.ArgumentNullException: Value cannot be null. Parameter name: type at System.Activator.CreateInstance(Type type, Boolean nonPublic) at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_ReceiverObject() 0 0 NotificationCustomTimerJob *************could you tell me ... how to resolve this error pls ?Anonymous
March 18, 2014
Thanks, nice tutorial :))Anonymous
September 05, 2014
This is working well, but I'm having a problem where, if I make a change to the class NotificationTimerJob.cs, and redeploy, the job on SharePoint keeps running with the old version of the class. This happens if retract the solution in VS or SharePoint, or if reset IIS. How can I fix that?Anonymous
September 05, 2014
Never mind. I figured it out: you have to restart the SharePoint timer service every time you redeploy it.Anonymous
February 02, 2015
Hi I couldnot find the timerjob under jobdefination location, can anybody please help me?Anonymous
February 04, 2015
The comment has been removedAnonymous
August 19, 2015
Error 1 Error occurred in deployment step 'Add Solution': Failed to create receiver object from assembly "NotificationCustomTimerjob, Version=1.0.0.0, Culture=neutral, PublicKeyToken=69905e0c452e3fa8", class "$SharePoint.Type.d4ce3f92-a1f4-412d-8726-074963e5521c.FullName$" for feature "NotificationCustomTimerjob_NotificationTimerJobFeature" (ID: 4859ce7e-8d19-4f25-a2ec-66ef20f35d52).: System.ArgumentNullException: Value cannot be null. Parameter name: type at System.Activator.CreateInstance(Type type, Boolean nonPublic) at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_ReceiverObject() 0 0 NotificationCustomTimerjob I got this error. can you please tell me how to fix this?Anonymous
January 22, 2016
Error 1 Error occurred in deployment step 'Add Solution': Failed to create receiver object from assembly "NotificationCustomTimerJob, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4b2d4f410c722ce9", class "$SharePoint.Type.b4691825-aea1-477b-a02e-a3bcc1afb334.FullName$" for feature "NotificationCustomTimerJob_NotificationTimerJobFeature" (ID: 11b9f856-d878-421a-b89b-3f8d0aac9027).: System.ArgumentNullException: Value cannot be null. Parameter name: type at System.Activator.CreateInstance(Type type, Boolean nonPublic) at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_ReceiverObject() 0 0 NotificationCustomTimerJob Please help me to fix this error.Anonymous
January 22, 2016
The comment has been removed