Saturday 19 January 2013

Creating Custom Activity Type - Part 1


SharePoint 2010 provides us with an excellent feature in the Mysites where we can see our most recent activities using the Recent Activities webpart and the activities of our colleagues by using the NewsFeed webpart. Now the point of interest here is that OOB we can only see feeds for the activity types that SharePoint provides us. The activity feed available OOB collects data from two areas

First is the User Profile changes such as Job Title , Colleague Changes, Birthdays etc and the second is around the social feedback events like tags, new blog posts etc.


We have a scheduled Timer Job which generates new activity events for an individual which are broadcasted to individual's colleagues.

SharePoint 2010 provides two OOB webparts, one shows the consolidated feed in My NewsFeed page which displays all the colleague activity events that I have subscribed to and the other is my published feed that appears in MyProfile page in my Recent Activities.

What if we want to have our own custom type here. I faced this requirement in my current project where I was supposed to show an event in the feed when a user changes a theme. In other words, if my colleague changes some theme , then I should be notified the same in my activity feed and vice versa.


To handle this scenario, we need to create a custom activity type in our newsfeed settings. But how this can be achieved?

I hope by now you must be clear of the exact requirement. To shorten up the long conversation, lets dive directly into the steps that will achieve the desired result.

In this series of blogs I will be explaining how to create a custom activity type, what happens behind the scenes in the Database and what challenges do we face when creating the feed.

To start with, we firstly need to create a custom ActivityApplication for our custom ActivityType.

Create a feature and add an event receiver that will create your custom ActivityApplication on the Feature activation.

SPServiceContext context = SPServiceContext.GetContext(elevatedSite);
UserProfileManager profileManger = new UserProfileManager(context);
UserProfile currentProfile = null;
Microsoft.Office.Server.ActivityFeed.ActivityManager actManager = null;

try
{
      if (profileManger != null)
           currentProfile = profileManger.GetUserProfile(WindowsIdentity.GetCurrent().Name);
}
catch (Exception ex)
{
}
try
{
     if (currentProfile == null)
    {
          if(web.CurrentUser.IsSiteAdmin)
                  currentProfile = profileManger.GetUserProfile(web.CurrentUser.LoginName);
     }
 }
 catch (Exception ex)
 {
  }
 if (currentProfile != null)
    actManager = new Microsoft.Office.Server.ActivityFeed.ActivityManager(currentProfile,context);
if (actManager != null)
{
     ActivityApplication actApplication = EnsureActivityApplication(actManager);
    if (actApplication != null)
    {
         ActivityType customActivityType = actApplication.ActivityTypes["ActivityThemeType"];
        if (customActivityType == null)
        {
             customActivityType = actApplication.ActivityTypes.Create("ActivityThemeType");
             customActivityType.ActivityTypeNameLocStringResourceFile = "CustomActivityType";
             customActivityType.ActivityTypeNameLocStringName = "ActivityName";
             customActivityType.IsPublished = true;
             customActivityType.IsConsolidated = true;
             customActivityType.AllowRollup = true;
             customActivityType.Commit();
             customActivityType.Refresh(true);
         }
         ActivityTemplate customActTemplate = customActivityType.ActivityTemplates[ActivityTemplatesCollection.CreateKey(false)];

        if (customActTemplate == null)
        {
            customActTemplate = customActivityType.ActivityTemplates.Create(false);
            customActTemplate.TitleFormatLocStringResourceFile = "CustomActivityType";
            customActTemplate.TitleFormatLocStringName = "Activity_Created";
            customActTemplate.Commit();
            customActTemplate.Refresh(true);
        }
    }
}
public ActivityApplication EnsureActivityApplication ( Microsoft.Office.Server.ActivityFeed.ActivityManager activityManager)
        {
            ActivityApplication app = null;
            if (activityManager != null)
            {
                //Check to see that the current user has permissions to access the social data 
                if (activityManager.PrepareToAllowSchemaChanges())
                {
                    app = activityManager.ActivityApplications["ActivityThemeApplication"];
                    if (app == null)
                    {
                        app = activityManager.ActivityApplications.Create("ActivityThemeApplication");
                        app.Commit();
                        app.Refresh(true);
                    }
                    return app;
                }
                else
                {
                    try
                    {
                        //The process user doesn’t have access to profiles service as manage social data role 
                        return activityManager.ActivityApplications["ActivityThemeApplication"];
                    }
                    catch (ActivityFeedPermissionDeniedException ex)
                    {
                     }
                }
            }
            return app;
        }

In the above code snippet , we are first fetching the UserProfile and then creating an instance of ActivityManager. After that we check whether ActivityApplication exists or not and if it does not exist then we create a new ActivityApplication for our custom activity type. After that we create a custom activity type and custom activity template. You need to make sure that you are using the correct permissions to perform the above operation so as to avoid Access Denied issue.

You can also see the Resource files that I have been using above. It basically helps you in setting the name and message for your custom Activity Type.




Now, a custom activity type with the name Theme Change will appear in our NewsFeed Settings page and the message that will appear will be as {Publisher} changed theme to {Value} where the {Publisher} will be replaced by the colleague account name and in {Value} we will populate the name of the Theme.

So, in this way, we can create a new custom Activity type in our newsfeed setting page. But this is not enough. We still need to implement the logic to create an event for the same so that it can be made available in the newsfeed.

Stay Tuned for the next part where I will explain you the logic to create activity events. :)


No comments:

Post a Comment