Remote Event Receivers on existing Lists & Libraries with Azure Service Bus

My first blog post in English -> let’s start wider! Older ones will be translated later.

Let’s imagine that in our SharePoint Online page we have list named Izdelki (in English we call that Products). For that list we want to add Event Receiver which will start on ItemAdded event and send an email about that to some person. Because we want to use SharePoint Online, we can’t use SP Farm Solution with standard Event Receiver. We have to use a Remote Event Receiver. This is kind a trivial if we create new list with an event receiver attached in SharePoint Add-in package. But we want to add an event receiver to an existing list. For that reason we are going to create Provider-Hosted SharePoint Add-in in a connection with an Azure Service Bus.

So, we create new SharePoint Add-in project type in Visual Studio. We named it XnetIzdelkiRER. We connect it with an URL of our SharePoint Online page, where we have list named Izdelki with only one Title field. We choose Provider-hosted option, SharePoint Online version, ASP.NET Web Forms Application type and Windows Azure Access Control Service authentication.

After solution is created we have two projects in there:

  • XnetIzdelkiRER: code for Provider Hosted Add-in
  • XnetIzdelkiRERWeb: code for Remote Web

Next we choose XnetIzdelkiRER project and in Properties Window we set to TRUE next properties:

  • Handle Add-in installed
  • Handle Add-in uninstalling

This thing create a new service class named AppEventReceiver.svc into XnetIzdelkiRERWeb project. Service contains two functions:

  • ProcessEvent which handle app installed/uninstalled/upgraded events and common sync events
  • ProcessOneWayEvent which handle async events (no app events)

Entire code for service class is:

using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.EventReceivers;
using System.ServiceModel;

namespace XnetIzdelkiRERWeb.Services
{
    public class AppEventReceiver : IRemoteEventService
    {
        private string email = "{blank}@{blank}.onmicrosoft.com";

        public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
        {
            SPRemoteEventResult result = new SPRemoteEventResult();

            // when app is istalled
            if (properties.EventType == SPRemoteEventType.AppInstalled)
            {
                // we format path to AppEventReceiver.svc in which we handle ItemAdded events
                string potDoSVC = OperationContext.Current.Channel.LocalAddress.Uri.AbsoluteUri.Substring(0, OperationContext.Current.Channel.LocalAddress.Uri.AbsoluteUri.LastIndexOf("/")) + "/AppEventReceiver.svc";

                using (ClientContext ctx = TokenHelper.CreateAppEventClientContext(properties, useAppWeb: false))
                {
                    // we want to connect to list named Izdelki on page, where we activated App
                    var list = ctx.Web.Lists.GetByTitle("Izdelki");
                    ctx.Load(list);
                    ctx.ExecuteQuery();

                    // new ItemAdded Event receiver (async) added to list, we connect it to svc which handle ItemAdded event
                    EventReceiverDefinitionCreationInformation er = new EventReceiverDefinitionCreationInformation()
                    {
                        EventType = EventReceiverType.ItemAdded,
                        ReceiverName = "IzdelkiER",
                        ReceiverUrl = potDoSVC,
                        SequenceNumber = 1000
                    };

                    list.EventReceivers.Add(er);
                    ctx.ExecuteQuery();
                }
            }
            // when app is uninstalled
            else if (properties.EventType == SPRemoteEventType.AppUninstalling)
            {
                using (ClientContext ctx = TokenHelper.CreateAppEventClientContext(properties, useAppWeb: false))
                {
                    var list = ctx.Web.Lists.GetByTitle("Izdelki");
                    ctx.Load(list);
                    ctx.ExecuteQuery();

                    // we want to delete "IzdelkiER" event receiver
                    foreach (var er in list.EventReceivers)
                    {
                        if (er.ReceiverName.Equals("IzdelkiER"))
                        {
                            er.DeleteObject();
                            ctx.ExecuteQuery();
                        }
                    }
                }
            }

            return result;
        }

        public void ProcessOneWayEvent(SPRemoteEventProperties properties)
        {
            // when ItemAdded event is fired
            if (properties.EventType == SPRemoteEventType.ItemAdded)
            {
                // if event receiver is fired on list named "Izdelki"
                if (properties.ItemEventProperties.ListTitle.Equals("Izdelki"))
                {
                    using (ClientContext ctx = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
                    {
                        // read content of Title field
                        var list = ctx.Web.Lists.GetByTitle("Izdelki");
                        var li = list.GetItemById(properties.ItemEventProperties.ListItemId);
                        ctx.Load(li, item => item["Title"]);
                        ctx.ExecuteQuery();

                        // send email
                        string emailBody = "<b>Dodan nov dogodek</b> </br><table style='border: 1px solid black;'>";
                        emailBody += "<tr style='color:red;'><td><b>" + li["Title"] + "</b></td></tr>";
                        emailBody += "</table>";

                        Microsoft.SharePoint.Client.Utilities.EmailProperties emailProperties = new Microsoft.SharePoint.Client.Utilities.EmailProperties();
                        emailProperties.To = new string[] { email };
                        emailProperties.Subject = "Dodan nov izdelek";
                        emailProperties.Body = emailBody;
                        Microsoft.SharePoint.Client.Utilities.Utility.SendEmail(ctx, emailProperties);

                        ctx.ExecuteQuery();
                    }
                }
            }
        }
    }
}

After that we build and deploy solution. Trust your application when SharePoint ask you about that. Before that it is necessary to Enable debugging via Microsoft Azure Service Bus and define a connection string. More about that in this article.

Test your event receiver on Izdelki list. Add new item and you will get an email as this in image below.

sl8

Cheers!
Gašper Rupnik

{End.}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Powered by WordPress.com.

Up ↑

%d bloggers like this: