Tuesday, July 22, 2014

Umbraco + TweetInvi + JQuery Social Stream Wall

I just spent days to figure out the best Twitter library using OAuth that we can use on our Umbraco websites and a JQuery plugin that could display various social media widgets on a "wall".

Here's the major problem:







  • We don't want to do any custom codes and recompile an Umbraco installation  nor create a package / plugin because we are new to Umbraco and we don't have the time yet to learn how to create Umbraco packages.

  • By searching through the internet forums and doing some code testings, we found out that TweetInvi and JQuery Social Stream could help us achieve our goals. These two libraries are just awesome and it did saved our day!

    But here are more problems:

    • JQuery Social Stream is using a PHP class for the Twitter OAuth as an example and we are using Umbraco (C#)
    • We don't want to create another site just to host the PHP class.
    • TweetInvi returns an IEnumerable rather than a JSON object that can be easily passed to any Javascript library, which means we might have to use another library to convert these objects to JSON
    • I couldn't find any samples on the web that have used both TweetInvi and JQuery Social Stream under an Umbraco website.

    These are all simple problems but not for me as I am not an expert in any of these libraries and Umbraco. So I have to deal with this especially that my company have already purchased a license for JQuery Social Stream.

    Fortunately, Lee Chestnutt (JQuery Social Stream) and Linvi (TweetInvi) have quickly responded to my queries and Linvi's source code is available on GitHub for download in which I could just browse and check if there's any functions available that I could use.

    So far, here are the solutions to these simple problems:

    1. Copy all TweetInvi dlls into the Umbraco installation bin folder
    2. Create a new template under Umbraco
    3. Create a new macro (partial view macro)
    4. Use TweetInvi to authenticate your site to Twitter. You can include this on the Umbraco template or on a macro
    5. Use TweetInvi's function "Tweetinvi.Json.TimelineJson.GetUserTimeline" to retrieve the twitter timeline as json
    6. Render the result as JSON on the Umbraco template
    7. Create a page with the template we just created above
    8. Use JQuery Social Stream on the macro and pass the url (generated from #7) to the twitter option

    Simple isn't it?

    To help other beginners just like me, here's how it was done (through codes):

    Umbraco Template:

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    @using System
    @using System.Collections.Generic
    @using System.Diagnostics
    @using System.IO
    @using System.Linq
    @using Tweetinvi
    @using Tweetinvi.Core.Enum
    @using Tweetinvi.Core.Extensions
    @using Tweetinvi.Core.Interfaces
    @using Tweetinvi.Core.Interfaces.Controllers
    @using Tweetinvi.Core.Interfaces.DTO
    @using Tweetinvi.Core.Interfaces.Models
    @using Tweetinvi.Core.Interfaces.Models.Parameters
    @using Tweetinvi.Core.Interfaces.oAuth
    @using Tweetinvi.Core.Interfaces.Streaminvi
    @using Tweetinvi.Json
    @using Stream = Tweetinvi.Stream
     
    @{
        Layout = null;
     
     string accessToken = (string)CurrentPage.twitterAccessToken;
     string accessTokenSecret = (string)CurrentPage.twitterAccessTokenSecret;
     string consumerKey = (string)CurrentPage.twitterConsumerKey;
     string consumerSecret = (string)CurrentPage.twitterConsumerSecret;
     string screenName = (string)CurrentPage.twitterScreenName;
     int maxTweets;
     Tweetinvi.Core.Interfaces.IUser user;
     
     //authenticate your site to twitter OAuth
     TwitterCredentials.SetCredentials(accessToken, accessTokenSecret, consumerKey, consumerSecret);
        
     if(!Int32.TryParse(CurrentPage.twitterMaxLimit.ToString(),out maxTweets))
     {
      maxTweets = 20;
     }
     
     if(String.IsNullOrEmpty(screenName))
     {
      //get user
      user = Tweetinvi.User.GetLoggedUser();
     }
     else
     {
      //get user from screen name
      user = Tweetinvi.User.GetUserFromScreenName(screenName);
     }
     
     //retrieve the timeline as json
     var tweets = Tweetinvi.Json.TimelineJson.GetUserTimeline(user,maxTweets);
     
     //convert template to return as json
     Response.ContentType = "application/json";
     
     //write result as json
     @Html.Raw(tweets); 
     
    }

    Umbraco Macro:

    @inherits Umbraco.Web.Macros.PartialViewMacroPage
    @using ClientDependency.Core.Mvc
    @using ClientDependency.Core
    @{
     Html.RequiresJs("~/scripts/jquery/plugins/socialstream/js/jquery.social.stream.1.5.4.min.js", 3);
     Html.RequiresJs("~/scripts/jquery/plugins/socialstream/js/jquery.social.stream.wall.1.3.js", 4);
     Html.RequiresCss("~/scripts/jquery/plugins/socialstream/css/dcsns_wall.css");
     
     var startNodeId = (string)Model.MacroParameters["startNodeId"];
     var iconPath = (string)Model.MacroParameters["iconPath"];
     var imagePath = (string)Model.MacroParameters["imagePath"];
     var htmlId = (string)Model.MacroParameters["htmlId"];
     
     var node = Umbraco.Content(startNodeId);
     
     if(node.DocumentTypeAlias == "SocialWall")
     {
      List<string> feeds = new List<string>();
      List<string> options = new List<string>();
      
      if(String.IsNullOrEmpty(htmlId) || htmlId == "null")
      {
       htmlId = "social-stream";
      }
      if(String.IsNullOrEmpty(iconPath) || iconPath == "null")
      {
       iconPath = "/scripts/jquery/plugins/socialstream/images/dcsns-dark-1/";
      }
      if(String.IsNullOrEmpty(imagePath) || imagePath == "null")
      {
       imagePath = "/scripts/jquery/plugins/socialstream/images/dcsns-dark-1/";
      }
      
      //this is where you have to insert the template url
      if(!String.IsNullOrEmpty(node.socialWallTwitter.ToString()))
      {
       var twitterNode = Umbraco.Content(node.socialWallTwitter.ToString());
       
       if(twitterNode != null && !String.IsNullOrEmpty(twitterNode.Name))
       {
        feeds.Add("twitter: { id: '" + twitterNode.twitterScreenName + "', url: '" + twitterNode.Url + "' }");
       }
       
      }
      
       
      if(!String.IsNullOrEmpty(node.socialWallFacebook))
      {
       feeds.Add("facebook: { id: '" + node.socialWallFacebook +"' }");
      }
      
      //do your other stuffs here...
      
      //render the social stream
      <div id="@htmlId"></div>
      <script type="text/javascript">
       $(document).ready(function($){
       $('#@htmlId').dcSocialStream({
         @Html.Raw(String.Join(",",options.ToArray()))
        });
       });
      </script>
     }
    }
    
    
    

    I know this isn't the best solution, but so far this was the fastest and easiest way for us to implement. So if you have a better solution or suggestions, please don't hesitate to comment below or send me an email. Would be really glad if you could help us out. :)



    No comments:

    Post a Comment