Surendra Sharma

Surendra Sharma

Search This Blog

Showing posts with label MVC. Show all posts
Showing posts with label MVC. Show all posts

Thursday, September 13, 2018

Manage Facebook feeds from Sitecore

We all know the importance of social media for product branding. Almost all websites showing their organization or products related messages to their website.

Manage Facebook feeds from Sitecore
Manage Facebook feeds from Sitecore


There are lots of 3rd party components to make this job easier. But how to implement it programmatically and customize as per requirement where we need to show top 8 feeds (where the number of feeds can be manageable from Sitecore.)

This is a series of 3 articles where I will show how you control Facebook, Twitter and Youtube feeds from Sitecore and display it on your web page.

In this post, we will check how to access FaceBook feeds by using FaceBook Graph API. 

For this you need Facebook long lived token which you can generate from https://developers.facebook.com/tools/explorer/

Create Sitecore template having fields like

Sitecore fields for Facebook feeds
Sitecore fields for Facebook feeds


Code

First we need to create Template mapping class for this Facebook fields as

namespace Sitecore.Feature.Social
{
    using Sitecore.Data;

    public struct Templates
    {
        public struct SocialFeedsManager
        {
            public static ID ID = new ID("{B1959961-A315-468D-8D03-CA50CB790C86}");
            public static ID ContentItemID = new ID("{EC8578D8-4C0F-413E-83F2-C9BA5B249E85}");


            public struct Fields
            {
            
                public static readonly ID FacebookPageId = new ID("{716153BE-170F-4959-B0BE-F27FFE2EAB59}");
                public static readonly ID FacebookPermanentAccessToken = new ID("{A30C9CBF-6D5A-4E47-B75F-703C7F2EBD05}");
                public static readonly ID FacebookPlatformName = new ID("{38EF4F1D-A77F-49DC-BDB6-0E7C2401CF59}");
                public static readonly ID FacebookMaxFeedsInAll = new ID("{B3D21390-1D1A-4D43-B41F-246E32602C8D}");
                public static readonly ID FacebookMaxFeeds = new ID("{FE3DFD2E-350A-4C89-9C80-F21FDC62C131}");
                public static readonly ID FacebookFeedRequestUrl = new ID("{428FDCDF-4BAB-492E-A7F5-C1C8AF397F95}");
                public static readonly ID FacebookIsActive = new ID("{404F4369-8A01-46D3-82E7-B365EAF0C31F}");

            }
        }


    }
}

Create Model classes to holds values of Sitecore item fields values and JSON data return by FaceBook for feeds as

·         ChannelName – Enum for different social channel
·         SocialFeedsManagerModel – Get Sitecore item values for FaceBook
·         FBPostsModel – Hold FaceBook JSON feeds to objects
·         SocialMediaFeed – Class to hold single feed values from Json data

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Sitecore.Data.Items;
using Sitecore.Foundation.SitecoreExtensions.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using static Sitecore.Feature.Social.Templates;

namespace Sitecore.Feature.Social.Models
{
    public enum ChannelName
    {
        All,
        Facebook,
        Twitter,
        Instagram,
        Youtube
    }

    /// <summary>
    /// Social Feeds Model for getting Sitecore fields data
    /// </summary>
    public class SocialFeedsManagerModel
    {

        //Facebook
        public string FacebookPageId { get; set; }
        public string FacebookPermanentAccessToken { get; set; }
        public string FacebookFeedRequestUrl { get; set; }
        public string FacebookPlatformName { get; set; }
        public int FacebookMaxFeedsInAll { get; set; }
        public int FacebookMaxFeeds { get; set; }
        public bool FacebookIsActive { get; set; }

        public SocialFeedsManagerModel() { }

        public void InitializeData(Item dataSourceItem, ChannelName channelName)
        {
            if (channelName == ChannelName.Facebook || channelName == ChannelName.All)
            {
                //Facebook
                this.FacebookIsActive = dataSourceItem.Fields[SocialFeedsManager.Fields.FacebookIsActive].IsChecked();
                if (this.FacebookIsActive)
                {
                    this.FacebookMaxFeeds = System.Convert.ToInt32(dataSourceItem[SocialFeedsManager.Fields.FacebookMaxFeeds]);
                    this.FacebookMaxFeedsInAll = System.Convert.ToInt32(dataSourceItem[SocialFeedsManager.Fields.FacebookMaxFeedsInAll]);
                    this.FacebookPageId = dataSourceItem[SocialFeedsManager.Fields.FacebookPageId];
                    this.FacebookPermanentAccessToken = dataSourceItem[SocialFeedsManager.Fields.FacebookPermanentAccessToken];
                    this.FacebookPlatformName = dataSourceItem[SocialFeedsManager.Fields.FacebookPlatformName];
                    this.FacebookFeedRequestUrl = dataSourceItem[SocialFeedsManager.Fields.FacebookFeedRequestUrl];
                }
            }


        }
    }

    /// <summary>
    /// Model for Social Media Feeds returning as JSON
    /// </summary>
    public class SocialMediaFeed
    {
        public string FeedID { get; set; }
        public string PlatformName { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public string ImageURL { get; set; }
        public string FeedURL { get; set; }
        public DateTime Timestamp { get; set; }
        public string From { get; set; }
    }
    /// <summary>
    /// Convert Facebook JSON feeds to object
    /// </summary>
    public class FBPostsModel
    {
        public Datum[] data { get; set; }
        public Paging paging { get; set; }
    }

    public class Paging
    {
        public Cursors cursors { get; set; }
        public string next { get; set; }
    }

    public class Cursors
    {
        public string before { get; set; }
        public string after { get; set; }
    }

    public class Datum
    {
        public DateTime created_time { get; set; }
        public string message { get; set; }
        public string id { get; set; }
        public From from { get; set; }
        public string picture { get; set; }
        public string link { get; set; }
    }

    public class From
    {
        public string name { get; set; }
        public string id { get; set; }
    }

}

Below is Controller code for fetching feeds from FaceBook and then as per settings in Sitecore item, return JSONResult of FaceBook Feeds which finally received by AJAX request to show it on page.

namespace Sitecore.Feature.Social.Controllers
{
    using Newtonsoft.Json;
    using Sitecore.Data.Items;
    using Sitecore.Feature.Social.Models;
    using Sitecore.Foundation.SitecoreExtensions.Extensions;
    using Sitecore.Mvc.Presentation;
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Security.Cryptography;
    using System.Text;
    using System.Web.Mvc;
    using System.Web.Script.Serialization;
    using static Sitecore.Feature.Social.Templates;

    public class SocialController : Controller
    {
        private List<SocialMediaFeed> lstSocialFeeds = null;

        public ActionResult GetSocialFeeds(string channelName, string token)
        {
            string result = "Error - ";

            if (string.IsNullOrEmpty(channelName) || string.IsNullOrEmpty(token) || !token.Equals("accesstoken"))
            {
                result += "Unauthorized request!!!";
            }


            channelName = channelName ?? "all";
            result = CollectSocialFeeds(channelName, result);

            if (lstSocialFeeds != null && lstSocialFeeds.Count > 0)
            {
                return Json(new { success = true, responseResult = lstSocialFeeds }, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(new { success = false, responseResult = result }, JsonRequestBehavior.AllowGet);
            }

        }

        /// <summary>
        /// Collect all feeds in list
        /// </summary>
        /// <param name="channelName"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private string CollectSocialFeeds(string channelName, string result)
        {
            try
            {
                SocialFeedsManagerModel _SocialFeedsManagerModel = new SocialFeedsManagerModel();

                Item dataSourceItem = null;

                if (RenderingContext.CurrentOrNull != null)
                {
                    var dataSourceId = RenderingContext.CurrentOrNull.Rendering.DataSource;
                    dataSourceItem = Sitecore.Context.Database.GetItem(dataSourceId);
                }

                if (!dataSourceItem?.IsDerived(Templates.SocialFeedsManager.ID) ?? true)
                {
                    dataSourceItem = Context.Database.GetItem(SocialFeedsManager.ContentItemID);
                }

                lstSocialFeeds = new List<SocialMediaFeed>();

                switch (channelName.ToLower())
                {                   
                    case "facebook":
                        {
                            _SocialFeedsManagerModel.InitializeData(dataSourceItem, ChannelName.Facebook);

                            if (_SocialFeedsManagerModel.FacebookIsActive)
                            {

                                lstSocialFeeds = GetFacebookFeeds(_SocialFeedsManagerModel.FacebookPageId, _SocialFeedsManagerModel.FacebookPermanentAccessToken,
                                    _SocialFeedsManagerModel.FacebookFeedRequestUrl, _SocialFeedsManagerModel.FacebookPlatformName,
                                    _SocialFeedsManagerModel.FacebookMaxFeeds);
                            }
                            else
                            {
                                result += " Facebook feeds are disabled.";
                            }
                            break;
                        }
                   
                    default:
                        {
                            result += " Invalid Social Media.";
                            lstSocialFeeds = null;
                            break;
                        }
                }
            }
            catch (Exception ex)
            {
                result += " Occurred." + ex.Message;
                lstSocialFeeds = null;
                string str = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// Get Facebook Feeds
        /// </summary>
        /// <param name="PageId"></param>
        /// <param name="AccessToken"></param>
        /// <param name="APIUrl"></param>
        /// <param name="PlatformName"></param>
        /// <param name="maxResult"></param>
        /// <returns></returns>
        private List<SocialMediaFeed> GetFacebookFeeds(string PageId, string AccessToken, string APIUrl, string PlatformName = "Facebook", int maxResult = 2)
        {
            FBPostsModel posts;
            string FeedRequestUrl = APIUrl.Replace("{PageId}", PageId).Replace("{limit}", maxResult.ToString()).Replace("{access_token}", AccessToken);
            HttpWebRequest feedRequest = (HttpWebRequest)WebRequest.Create(FeedRequestUrl);
            feedRequest.Method = "GET";
            feedRequest.Accept = "application/json";
            feedRequest.ContentType = "application/json; charset=utf-8";
            WebResponse feedResponse = (HttpWebResponse)feedRequest.GetResponse();

            List<SocialMediaFeed> lstFacebookFeeds = null;

            using (feedResponse)
            {
                using (var reader = new StreamReader(feedResponse.GetResponseStream()))
                {
                    posts = JsonConvert.DeserializeObject<FBPostsModel>(reader.ReadToEnd());

                    lstFacebookFeeds = posts.data.Select(x => new SocialMediaFeed
                    {
                        FeedID = x.id,
                        PlatformName = PlatformName, // "Facebook",
                        Title = "",
                        Description = Server.HtmlEncode(x.message),
                        ImageURL = x.picture,
                        FeedURL = x.link,
                        From = x.from.name,
                        Timestamp = x.created_time
                    }).ToList();
                }
            }

            return lstFacebookFeeds;
        }
    }
}

Write AJAX script and view in HTML to load the feeds

@model Sitecore.Feature.Social.Models.JSONOutput

<div id="SocialFeedsDiv">


    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <script>


        $(document).ready(function () {
            var b = null;
            $("#all").click(function () {
                loadfeeds("All")
            });

            $("#Facebook").click(function () {
                loadfeeds("Facebook")
            });

            $("#Twitter").click(function () {
                loadfeeds("Twitter")
            });

            $("#Youtube").click(function () {
                loadfeeds("Youtube")
            });

            $("#Instagram").click(function () {
                loadfeeds("Instagram")
            });


            function loadfeeds(channelName) {
                $.get("/api/sitecore/social/GetSocialFeeds?channelName=" + channelName + "&token=accesstoken", function (data, status) {
                    var index = 1;
                    $("#feedlist").html("");
                    $.each(data.responseResult, function (i, field) {
                        var imageurl = "";
                        if (field.ImageURL !="" || field.ImageURL != null) {
                            imageurl = "ImageURL : <a href='" + field.FeedURL + "' ><img src='" + field.ImageURL + "' alt='" + field.Title + "' /> </a> <br>";
                        }
                        $("#feedlist").append(
                            "<li>Sr No :" + index + "<br>" +
                            "FeedID :" + field.FeedID + "<br>" +
                            "PlatformName :" + field.PlatformName + "<br>" +
                            "Title :" + field.Title + "<br>" +
                            "Description :" + field.Description + "<br>" + imageurl
                            +
                            "FeedURL :" + field.FeedURL + "<br>" +
                            "Timestamp :" + field.Timestamp + "<br>" +
                            "From :" + field.From + "<br><br><br>" + "</li>"
                        );
                        index++;
                    });
                });
            }
        });

    </script>

     <br />
    <a href="javascript:void(0)" id="all">All</a><br />
    <a href="javascript:void(0)" id="Facebook">Facebook</a><br />
    <a href="javascript:void(0)" id="Twitter">Twitter</a><br />
    <a href="javascript:void(0)" id="Youtube">Youtube</a><br />
    <a href="javascript:void(0)" id="Instagram">Instagram</a><br />

    <div id="feed">

    </div>

    <br />
    <br />

    <div id="HTMLfeed">
        <ul id="feedlist"></ul>


    </div>

</div>

We can access this action method from URL AJAX as

This will return JSON result which include individual feeds
{
    "success": true,
    "responseResult": [
        {
            "FeedID": "111111111_2222222",
            "PlatformName": "Facebook",
            "Title": "",
            "Description": "This photo is awarded as one of the best modern art picture which represent circles of LIFE.",
            "ImageURL": "https://scontent.xx.fbcdn.net/v/t1.0-0/s130x130/1111_1111111_6614517049093783552_n.jpg?_nc_cat=0&oh=981dd7810118a398f731a9d8f46593d2&oe=11111",
            "FeedURL": "https://www.facebook.com/photo.php?fbid=11111111&set=a.111111.1111.100002081603101&type=3",
            "Timestamp": "/Date(1529734494000)/",
            "From": "Alex Sharma"
        }
    ]
}

Once we have JSON, we can show it in page in any desired HTML format.


That’s it.

I hope you enjoy this Sitecore article. Stay tuned for more Sitecore related articles.

Till that happy Sitecoring :)

Please leave your comments or share this article if it’s useful for you.