Working with Social Hashtags, Search, and the SharePoint 2013 CSOM

December 14, 2012 00:31 by keithkaragan

The Microsoft.SharePoint.Client.Social.SocialFollowingManager class is used to retrieve the Tags a user is following, but there is no correlation inherent in the result between the returned Tags (they are returned as an array of Microsoft.SharePoint.Client.Social.SocialActor objects) and any social posts tagged that contain the tag. The only reasonable way to get a collection of social posts containing the tag that I could find was to utilize the search conversations source.

To get a result set with posts containing the tag, I can do the following:

KeywordQuery keywordQuery = new KeywordQuery(clientContext);

keywordQuery.QueryText = TagName;

keywordQuery.SourceId = SearchConversationsSourceId;

Where the KeywordQuery’s QueryText property is the Tag (ex: #Foo), and the KeywordQuery’s SourceId is set to the value of the Source Id for the Conversations Source (in my case: 459dd1b7-216f-4386-9709-287d5d22f568).

The ResultRows from the query have many properties in a default install. The following properties are the ones we’re interested in:

·         FullPostBody – The full text of the post

·         RootPostOwnerID – The Actor that owns the root post. In site feeds, this is the site itself. The format is something like: 8.36ff160c09d440ee9eb12b0249b8ab44.05878c50960e41fe859fce493
5c4b8b2.36ff160c09d440ee9eb12b0249b8ab44.0c37852b34d0418e91
c62ac25af4be5b

·         RootPostUniqueID – A unique identifier for the root post for the post in the result (since the result may not be a root post, it may be a reply). The format is something like: e6337cfd50a5489da51234c19954b556

·         MicroBlogType – There may be other values, but I’ve only seen 2 (for Root Posts), and 4 (Replies).

·         RootPostID – An integer identifying the Root Post for the post in the result.

·         ListItemID – The Item Id for the result post in the list where the post is stored.

OK, so what do we want all this for – well, notice that there is not a property returned that is in exactly the same format that maps to the ID of a Thread in the SocialFeedManager. The ID of a thread you would see in a SocialFeed looks like:

8.36ff160c09d440ee9eb12b0249b8ab44.05878c50960e41fe859fce4935c4b8b2.36ff
160c09d440ee9eb12b0249b8ab44.0c37852b34d0418e91c62ac25af4be5b
.75604b38
9c4f4c4b9f7bb3262aac30dc.5.6.1
[The bolded area is the difference from the RootPostUniqueID returned from search, and the ID you would see in a SocialFeed object]

The RootPostOwnerID is common for posts in this feed source (for a site feed). If we want to reconstruct the thread for a post returned in the search, we’ll need to fetch the feed using the SocialFeedManager, and then use the SocialFeedManager’s GetFullThread() method to pull out the particular thread we want – but to do that we need to determine the correct Thread ID to provide the method. This lent itself to a lot of head scratching for me, but perhaps you’ve already deduced the formula. If not I’ll lay out what I came up with (noting that it might be incomplete, or just wrong – but it seems to be working for me right now).

For site feed items returned from the conversations source in search, I first look at the MicroBlogType property to determine if it is the original post (MicroBlogType = 2), or a reply (MicroBlogType = 4). For replies, I constructed the Thread ID for its root post by taking the RootPostOwnerID property and adding several of the properties mentioned earlier to it – separated by periods, then adding a suffix of “.1” to the end of the string (without the curly brackets):

{RootPostOwnerID}.{RootPostUniqueID}.{RootPostID}.{ListItemID}.1

Ex:
8.36ff160c09d440ee9eb12b0249b8ab44.05878c50960e41fe859fce4935c4b8b2.36ff160
c09d440ee9eb12b0249b8ab44.0c37852b34d0418e91c62ac25af4be5b.36a3f70ae4be4c
a0bf169a5bf26318d5
.5.6.1

(remember that this ID is for the post that this reply, but it needs to reference up to its root post in the RootPostUniqueID and RootPostID positions – the ListItemId position is the self-reference)

This is similar for the original post (which would be a ‘root thread’ in a SocialFeed object), except that the ListItemID is also used for the RootPostID spot in the string, as the post is at the root of the conversation.

{RootPostOwnerID}.{RootPostUniqueID}.{ListItemID}.{ListItemID}.1

Ex:
8.36ff160c09d440ee9eb12b0249b8ab44.05878c50960e41fe859fce4935c4b8b2.36ff160c0
9d440ee9eb12b0249b8ab44.0c37852b34d0418e91c62ac25af4be5b.e6337cfd50a5489da5
1234c19954b556
.5.5.1

(remember that this ID is for the post that this reply, but it needs to reference up to its root post in the RootPostUniqueID position – the ListItemId value is used in both the RootPostID and ListItemId positions for the self-reference)

Feeding this constructed value into the SocialFeedManager.GetFullThread() method will return the full thread that contains the post containing the tag.

context.Load(context.Web);

SocialFeedManager sfm = new SocialFeedManager(context);

SocialFeedOptions sfOpt = new SocialFeedOptions();
sfOpt.MaxThreadCount = 5;
sfOpt.SortOrder =
SocialFeedSortOrder.ByModifiedTime;
ClientResult<SocialFeed> feed = sfm.GetFeedFor(SiteName, sfOpt);
context.ExecuteQuery();

 

ClientResult<SocialThread> sThd = sfm.GetFullThread(_threadID);

context.ExecuteQuery();

foreach (SocialPost p in sThd.Value.Replies)

{

Console.WriteLine(“ID: “+p.Id+” | Post Text:”+p.Text);

}

 

Where the _threadID is your constructed identifier.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 2.0 by 6 people

  • Currently 2/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5