English (United States) English (United Kingdom)
Thursday, March 18, 2010

Oct 27

Written by: Rodney Joyce
10/27/2008

As of UserProfile 4.3.12, any module can now publish event actions to the StoryFeed view (have a look at this profile on PokerDIY (bottom right) if you have not seen the feed). For example, if you had a Gallery module you could publish an event whenever someone uploads a new picture, or if you had a News article you could send an event whenever an article was published or approved. Hopefully by the time this blog is posted the Ventrian News Article module will be published events to the Smart-Thinker UserProfile feed.

 

The text and timing of the action is entirely up to you as the 3rd party module developer. The StoryFeed view does not do any lookups on the data - it purely shows every action for the associated user (which depends on how you have it configured on your site). On PokerDIY the homepage view shows any actions that you or your friends have performed, whereas the view on your profile shows actions by you only (this is based on the Facebook set up).

Lets look at the Smart-Thinker UserGroup module (Gratuitous plug - join the DotNetNuke Group if you have not already!) as an example - it uses the same StoryFeed webservice like any other module would.

These are the actions that I decided would be useful:

  • Create Group
  • Join Group
  • Leave Group   

Out of interest, I decided against Delete Group as Facebook does not seem to do this (but the point is that it is up to you as the calling module what is published). We'll use CreateGroup in this example as it is one of the simplest and most modules have a "create item" method.

Firstly, you will need to have the Smart-Thinker UserProfile module installed. Once this is up and running you will see the StoryFeed webservice - http://localhost/DotNetNuke/DesktopModules/Smart-Thinker%20-%20UserProfile/StoryFeed.asmx  (change "http://localhost/DotNetNuke" to your local dev web server). Add this as a Web Reference to your project so that you can see the Web Service class.

Note: Visual Studio generates a web.config which you can erase. As you will see we set the URL explicitly in the call so you do not need to use settings (of course, this is up to you).

Navigate to the webservice using a browser and you will that it is a very basic - the primary web method is called "AddAction" and basically takes in the following params:

  1. actionType - The ID of the action - in the Smart-Thinker modules I use an enum (StoryActionType in Enumerators.cs). These have to be unique so please check with me before assigning one and I will update the core list to give you a block of actions (if it is a public module). In a later version this process will be easier.
  2. relatedID - The ID of the entity that this action relates to. In our example it is the GroupID. This enables you to put the Feed onto the Groups page and show all the actions for the group - who joined, left etc. Have a look at the bottom of the DotNetNuke group (Group Activity) to see this in action.   
  3. actionText - The actual text/html do be displayed in the feed. It is up to the calling module to decide on the content, style it and put the links in.    In our example, the Smart-Thinker module is a generic module so it grabs a language string called "ActionText.GroupAdd" which is normal text by default. On PokerDIY I want the text to link into the profile and group so I used the core Language Editor to change the string to do this (ask if you need to see some examples).
  4. createdByUserID - Who initiated the action - for example, in CreateGroup it is the person who created it. The StoryFeed module looks at the CreatedBy person when it displays the feed, so if an Administrator created a group on behalf of someone else you would set this to the Owner and not the Admin userID.
  5. key - In the current version the UserProfile module needs to be aware of who is calling the webservice (and hence needs to be recompiled each time a new source/module is integrated with it. This will change in a later version but in the meantime please let us know me would like to be added as a source and I will generate a key for your company. When you make the webservice call it will compare the type and key and ensure that you are authorised to publish actions.

At the most basic level you could merely call these lines of code in your appropriate method:

    StoryFeedWS.StoryFeedWS storyFeed = new StoryFeedWS.StoryFeedWS();
    storyFeed.Url = "http://" + Request.ServerVariables["HTTP_HOST"] + this.ResolveUrl("~/DesktopModules/Smart-Thinker%20-%20UserProfile/StoryFeed.asmx");
    storyFeed.AddAction(storyActionTypeID, entityID, actionText, createdByUserID, myKey);

   
and this would insert a record into the SmartThinker_StoryFeed_Action table in your database. The UserProfile StoryFeed module would then show it depending on your configuration.   

So, using the UserGroup module, lets look at our exact code (if you have a Smart-Thinker Developer Package with the source you can open the UserGroupEdit.cs file in the UserGroups module and search for the "PublishStoryIntegration" method (sorry VBers, it's in C#).

        private void PublishStoryIntegration(StoryActionType storyActionType, SmartThinker_GroupInfo smartThinker_GroupInfo, int createdByUserID)
        {
            int storyFeedIntegration = Settings["StoryFeedIntegration"] == null ? Null.NullInteger : Convert.ToInt32(Settings["StoryFeedIntegration"]);
            //only publish info about Public Groups
            if (storyFeedIntegration == 1 && smartThinker_GroupInfo.PublicGroup)
            {
                string actionText = GetActionText(smartThinker_GroupInfo, createdByUserID);

                StoryFeedWS.StoryFeedWS storyFeed = new StoryFeedWS.StoryFeedWS();
                storyFeed.Url = "http://" + Request.ServerVariables["HTTP_HOST"] + this.ResolveUrl("~/DesktopModules/Smart-Thinker%20-%20UserProfile/StoryFeed.asmx");
                storyFeed.AddAction((int)storyActionType, smartThinker_GroupInfo.GroupID, actionText, createdByUserID, "MyKeyGeneratedBySmart-Thinker");
            }
        }


The first line of code just checks a setting to see if integration is required. This is of course up to you - you may want to be able to turn integration on or off in you module and you may not even be using the StoryFeed module.


This "if" statement then determines IF and WHEN an action should be published. Remember that it is up to you as the calling module to dictate this logic. So in the UserGroup module we do not want to publish any feeds about Private Groups (currently if you navigate to a private group it throws an error but this may change in the future to show a "Private Group" message and this could be changed).

The next line calls the "GetActionText" method to determine the actual event text to publish. It could be really simple or it could be complex based on your module. Have a look at the method below to see this method.

The next 3 lines (starting with StoryFeedWS.StoryFeedWS storyFeed = new StoryFeedWS.StoryFeedWS();) instantiate and call the actual webservice. You need to replace the variables with your own or hardcode them to test it.

Here is the "GetActionText" method we mentioned above - we are using the BaseTokenReplace method from the core to allow the user to template the language string (ie. put UserIDs, names etc into it) but this is entirely up to you). You could just hardcode "MyActionText" for now to make sure the call is working.

        private string GetActionText(SmartThinker_GroupInfo smartThinker_GroupInfo, int createdByUserID)
        {
            UserInfo createdByUserInfo = null;
            if (createdByUserID != this.UserId)
            {
                //the Admin is possibly approving a new group member
                createdByUserInfo = new Utilities().GetUserFromCacheOrDB(this.PortalId, createdByUserID);
            }

            SmartThinker.DNN.Modules.UserGroup.Business.BaseTokenReplace baseTokenReplace = new SmartThinker.DNN.Modules.UserGroup.Business.BaseTokenReplace(createdByUserInfo, smartThinker_GroupInfo);

            string languageString = Localization.GetString("ActionText.GroupAdd", LocalResourceFile);
            return baseTokenReplace.ReplaceGroupTokens(languageString);
        }


That's all there is too it! I suggest you ignore the UserGroup example above and use the simple lines of code above (starting with StoryFeedWS.StoryFeedWS storyFeed = new StoryFeedWS.StoryFeedWS();) until you have events being published to the feed, then refine it to include logic of when and what to publish.

Let me know if you have any questions or if anything is unclear.

Tags:

Re: Integrate your module with the Smart-Thinker UserProfile StoryFeed API and publish events to the feed

As of Smart-Thinker UserProfile version 4.3.14 the Ventrian News Article module now publishes events to the feed. You can read more about it here - http://www.smart-thinker.com/ProductsandModules/UserProfile/LatestUpdates/tabid/255/ctl/ArticleView/mid/780/articleId/91/Default.aspx

By rod on   11/9/2008

Re: Integrate your module with the Smart-Thinker UserProfile StoryFeed API and publish events to the feed

I hv problems integrating ST Groups with storyfeed module...
when i integrate groups module with storyfeed, it gives error on creating groups in the following line

storyFeed.AddAction((int)storyActionType, smartThinker_GroupInfo.GroupID, actionText, createdByUserID, "ST2656456160931683406860");

the actual error is "The request failed with HTTP status 400: Bad Request."

wat shud we do it get rid of this error ??

By shwetha.smruthi on   4/24/2009
© 2008 Smart-Thinker