SharePoint 2013: Deep integration of Yammer - Organizational chart for My Site


Introduction

Yammer! I have explained briefly about the Yammer in my article. I explained how you can integrate Yammer with SharePoint(2010, 2013) with available options. In my another article I explained how to integrate Yammer search  with SharePoint 2013 search. We will continue our Yammer journey and will see how to create Yammer Organizational chart on the My Site page of SharePoint 2013. Organizational chart is a famous widget on the enterprise social networks. It helps to get hierarchy of user quickly. Yammer provides Organizational chart and if you want to see your  Organizational chart on Yammer site then navigate to Home ->Edit Profile ->Org Chart. On Org chart page you can see the manager(s) you are reporting and your colleagues and those members who Reports to you. Now if you want to see Organizational chart of other users then you need to go on their page(profile page).


Problem Statement

Your organization do have a SharePoint 2013 portal site and uses it for all activities. Now they want to use social capabilities on this portal with the help of Yammer. And part of this requirement  they want to put Organizational chart on the My site page. The information of Organizational chart should come from the Yammer itself. Now when you will get this requirement you will start looking at the Yammer web part for SharePoint, but web part does not support this feature. So you have to turn towards Yammer REST API.


Organizational Chart REST API

REST APIs are endpoints opened for the developer to develop custom features. With help of these REST APIs you can fetch information from the Yammer and also can post information to the Yammer. REST APIs are easy to use. You can find complete list of REST APIs here. In this article we will focus only on Organization REST API which is knows relationships API.
Endpoint for the API:  

GET https://www.yammer.com/api/v1/relationships.json

You can also provide user id as a parameter so that you can also get organization chart /relationship of other members. Parameter is: user_id. Remember by default it picks current user if you don’t provide user_id.
If you want to add member in your organization chart then use below endpoint:

POST https://www.yammer.com/api/v1/relationships.json
Parameters: 
    User_id: Id of user which you want to add in  your chart/relationship.
    Use [ subordinate | superior | colleague ] to create the relationship.

If you want to remove any member from your chart/relationship then use below endpoint:

DELETE https://www.yammer.com/api/v1/relationships/[:id].json?type=[relationship_type]

Parameters applicable (taken from yammer site):
user_id - To view or edit the relationships for a user other than the logged-in user.
[ subordinate | superior | colleague ]=email_address - Pass email addresses as the value of the subordinate, superior or colleague parameters to add them to your org chart. All three can be passed in one request, and each can be passed multiple times.
id - The user ID whose relationship you’re removing from your org chart. Must be combined with type.
type=relationship_type - One of subordinate, superior, colleague. Used in DELETE requests to indicate which type of relationship you’re removing from your org chart.

You can use this endpoint to implement the above requirement. 


Solution to Problem Statement

We learned above how Org chart/Relationship REST API works. Now we will use it to fetch the organization chart/relationships of current user. In this example I have used current user for reference. To start writing this widget you need appId. You can create appId using Yammer site, refer Yammer API link for more information. Once you get it add below line as first line inside <script> tag :

 

yam.config({appId: "[Your AppID]"});

Don’t forget to add your appId. Now use above Org chart/relationship API to fetch information. The block would be like:

yam.getLoginStatus( function(response) {
        if (response.authResponse) {
      
            yam.request(
              {
url: "https://www.yammer.com/api/v1/relationships.json"
              , method: "GET"
              , data: {  }
              , success: function (msg) {          
            DisplayRelationship(msg);
              
            }
              , error: function (msg) { alert("Error..." + msg); }
              }
            )
        }
}

Once this block gets executed; it returns information as shown in fig. 1 . Response gets with three categories:  Colleagues  , Subordinates, Superiors. Each of these array contains information of member like – id, Full name, web_url and Role, etc.

 
fig.1

The next step is using JavaScript create the html with above response and write it on to page to display Organization chart as per design of your html.  I have used Google chrome to get above screenshot.

So in this way you can fulfill the requirement. Refer below complete script for displaying Organization chart.  If you want to show more information about the members on mouser-hover event or on mouse click then use below REST API which returns complete information about a member/user.  

https://www.yammer.com/api/v1/users/" + [User_id ]+".json.

 


Organization chart script:

 

<style type="text/css">
.orgChartDiv {
    height: 850px;
    width: 500px;
    float: left;
    overflow: auto;
    overflow-x: hidden;
    background: #A9E2F3;
}
 
.userDiv
{
    background: #D8D8D8;
    margin:15px;
    padding:15px;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
    border-radius: 10px;
    border: 1 solid #ffffff;
}
</style>
 
<script src="https://assets.yammer.com/platform/yam.js"></script>
<script src="./jquery-1.7.1.min.js"></script>
    <script type="text/javascript">
    yam.config({appId: "[appId]"});
 
var relativeUsersdata="";
function GetUserOrganizationChart()
{
 
yam.getLoginStatus( function(response) {
        if (response.authResponse) {
     
            yam.request(
              { url: "https://www.yammer.com/api/v1/relationships.json"
              , method: "GET"
              , data: {  }
              , success: function (msg) {           
            DisplayRelationship(msg);
             
            }
              , error: function (msg) { alert("Error..." + msg); }
              }
            )
     
        } else {
            yam.login( function (response) {
              if (!response.authResponse) {
                yam.request(
                  { url: "https://www.yammer.com/api/v1/relationships.json"
                  , method: "GET"
                  , data: { }
                  , success: function (msg) {  }
                  , error: function (msg) { alert("Error..." + msg); }
                  }
                );
              }
            });
        }
    });
 
}
 
function DisplayRelationship(resp)
{    
    var html="";
     
    var superiors = resp.superiors;
    var colleagues = resp.colleagues;
    var subordinates = resp.subordinates;
    html = html + "<div style='border:1px solid black;margin:15px;'><b>Your Superiors</b>";
    for(var i=0; i<superiors.length; i++)
    {
        var htmsp = "<div class='userDiv'><table width='100%'><tr><td>" + "<p>Full Name: <a href='" + superiors[i].web_url + "'>" + superiors[i].full_name  + "</a></p>" + "<p>Job Title: " + superiors[i].job_title  + "</p></td><td><div id='" + superiors[i].id + "'><table width='100%'><tr><td align='right'><img src='" + superiors[i].mugshot_url_template.replace("{width}x{height}","100x100") + "'/></td></tr></table></div>" +"</td></tr></table></div>";
         
        htmsp = htmsp.replace("null","Not Available");      
 
        html = html + htmsp;
    }
    html = html + "</div>";
 
    html = html + "<div style='border:1px solid black;margin:15px;'><b>Your Colleagues</b>";    
    for(var i=0; i<colleagues.length; i++)
    {
 
        var htmclg = "<div class='userDiv'><table width='100%'><tr><td>" + "<p>Full Name: <a href='" + colleagues[i].web_url + "'>" + colleagues[i].full_name  + "</a></p>" + "<p>Job Title: " + colleagues[i].job_title  + "</p></td><td><div id='" + colleagues[i].id + "'><table width='100%'><tr><td align='right'><img src='"+ colleagues[i].mugshot_url_template.replace("{width}x{height}","100x100") +"'/></td></tr></table></div>" +"</td></tr></table></div>";
 
        htmclg = htmclg.replace("null","Not Available");                
 
        html = html + htmclg;
    }
    html = html + "</div>";
 
    html = html + "<div style='border:1px solid black;margin:15px;'><b>Your Subordinates</b>";  
    for(var i=0; i<subordinates.length; i++)
    {
        var htmsub = "<div class='userDiv'><table width='100%'><tr><td>" + "<p>Full Name: <a href='" + subordinates[i].web_url + "'>" + subordinates[i].full_name  + "</a></p>" + "<p>Job Title: " + subordinates[i].job_title  + "</p></td><td><div id='" + subordinates[i].id + "'><table width='100%'><tr><td align='right'><img src='" + subordinates[i].mugshot_url_template.replace("{width}x{height}","100x100") +"'/></td></tr></table></div>" +"</td></tr></table></div>";
         
        htmsub = htmsub.replace("null","Not Available");        
 
        html = html + htmsub;
    }
    if(subordinates == "null" || subordinates.length ==0)
    {
        html = html + " not available.";
    }
 
    html = html + "</div>";
 
    var obj = document.getElementById("orgChartDiv");
    obj.innerHTML =  obj.innerHTML + html;
 
}
 
GetUserOrganizationChart();
</script>
<div id="orgChartDiv" class="orgChartDiv">
</div>


Organization chart script walkthrough:

The script contains GetUserOrganizationChart() function which fetches information from the Yammer. It always checks whether user has logged in to Yammer or not by executing if-block :        if (response.authResponse) {

If user is not logged in then pop up window for login gets opened by executing block:  yam.login( function (response) .
Once response comes back then script calls function DisplayRelationship(resp).  This function actually prepares the Organization chart HTML. It has three main for loops which iterates through arrays: resp.superiors, resp.colleagues and resp.subordinates. It generates complete html and then set that html to the div “orgChartDiv”.

Remember, never forget to put this line in script:  yam.config({appId: "[appId]"});
**
**


Screen Shots:

 


    

References


Upgrading To The Latest Yammer Embed

There is one update here! As of 7th April 2014, JS SDK has been updated with new security features. Now onwards you need to use below line:

<script type="text/javascript" data-app-id="YOUR-APP-CLIENT-ID" src="https://assets.yammer.com/assets/platform_js_sdk.js"></script>

The change in above code will be: the line "<script src="https://assets.yammer.com/platform/yam.js"></script>" will get replaced by "<script type="text/javascript" data-app-id="YOUR-APP-CLIENT-ID" src="https://assets.yammer.com/assets/platform_js_sdk.js"></script>". And no need to give APP ID explicitly. 
For more information refer this: https://developer.yammer.com/upgrading-to-the-new-yammer-js-sdk/