Consuming Yammer RESTful API with AngularJS for Dummies

This blog is a continuation of the Yammer RESTful API for dummies series. We are going to write a simple AngularJS client that consumes the Yammer users.json RESTful API endpoint. 

The AngularJS client will be accessed by opening the users.html file in your browser, and will consume the Yammer api service accepting requests at:

  https://api.yammer.com/api/v1/users.json  

Note that the Yammer REST API documentation uses https://www.yammer.com as the API endpoint host; you should always remember to change it to https://api.yammer.com.

The users.json API endpoint will respond with a JSON representation of all the users in the Yammer network.

Create an AngularJS Controller

First, let's create a very simple AngularJS controller that will consume the REST service. This can be done with and without user authentication prompt.  

Yammer support often get advisory questions from customers wanting to pull generic non-user specific yammer feeds into their (intranet) websites without authentication. Now, yammer does not support anonymity or public data so a user must be authenticated in one way or the other to be able to get and/or post yammer contents. To achieve this goal, you'd need to create a service account and obtain an access token using the instructions in this documentation.

Considering this is a newbie guide and if the documented process of obtaining yammer token is too complicated for you, you may try the following steps: 

  • Login to Yammer using the service account
  • Inspect the elements on the page
  • Navigate to the network tab
  • Reload the page if necessary
  • Locate any line containing .json originating from www.yammer.com. See screenshot below
  • Click the Request Header section
  • Look out for the line starting with "Authorization: Bearer "
  • Copy the token into a secure place

The above process is an alternative way of obtaining a user access token and it should look like this in Firefox:

The caveat is, tokens that are generated (or copied from browser elements) this way may be short lived or rendered invalid when the user logs out of the browser session. So I'd recommend you generate a token from a registered app for production purpose as they are long lived.  

Next, create a controller.js file then copy and paste this code into it: 

  function YammerGetUserCtrl($scope, $http ) {  
 $http.get('https://api.yammer.com/api/v1/users.json', {headers: {'Authorization': 'Bearer TOKEN_VALUE'}}).  
      success(function(data) {  
       $scope.users = data;  
      console.log($scope.users)  
     });  
 }  

Once that's done, replace TOKEN_VALUE with the access token you obtained.  

This controller module is represented as a simple JavaScript function that is given AngularJS’s $scope and $http components. It uses the $http component to consume the REST service at "/api/v1/users.json". The $http component sends a GET request to the API endpoint with a pre-defined Authorization header; this is one way of consuming Yammer feeds without prompting for authentication. 

If the GET request is successful, it will assign the JSON returned back from the service to $scope.users, effectively setting a model object named "users". By setting that model object, AngularJS can bind it to the application page’s DOM, rendering it for the end user to see. Bear in mind that this could be a lot better but slightly more complex, and I am seriously trying to keep the above implementation as simple as it possibly can because this tutorial is meant for you - newbie.  

Create the HTML Page

Now that you have an AngularJS controller, let's create the HTML page that will load the controller into the user’s web browser. Let's give it users.html as the file name. 

  <!DOCTYPE HTML>  
 <html ng-app>  
   <head>  
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>  
    <script src="controller.js"></script>  
   </head>  
   <body>  
    <hr>  
    <p></p>  
    <h3> Yammer Users</h3>  
    <div ng-controller="YammerGetUserCtrl">  
      <div align="left"> Filter users : <input type="text" ng-model="yamUser"> &nbsp;&nbsp; <br><br> </div>  
      <p ng-show='yamUser.length>0'> ({{yamUser.length}}) </p>  
       <table>  
         <thead valign="top">  
          <tr>  
            <th>userID</th>  
            <th>Full Name</th>  
            <th>NetworkID</th>  
            <th>Activation Date</th>  
            <th>Face</th>  
          </tr>  
         </thead>  
         <tbody>  
          <tr ng-repeat ="user in users | filter:yamUser" ng-class-even="'alt'">  
            <td> {{ user.id}}</td>  
            <td> {{ user.full_name }}</td>  
            <td> {{ user.network_id }}</td>  
            <td> {{ user.activated_at}}</td>  
            <td> <img src= "{{ user.mugshot_url}}"/></td>  
          </tr>  
          <tr ng-if"users.length==0" colspan="4"> No matching results for {{yamUser}} {{user.length}} </tr>  
         </tbody>  
       </table>  
    </div>  
   </body>  
 </html>  

Note the following two script tags within the head section.

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>   
 <script src="controller.js"></script>   

The first script tag loads the minified AngularJS library (angular.min.js) from a content delivery network (CDN) so that you don’t have to download AngularJS and place it in your project. It also loads the controller code (controller.js) from the application’s path.

The AngularJS library enables several custom attributes for use with standard HTML tags. In users.html, four such attributes are in play:

  • The <html> tag has the ng-app attribute to indicate that this page is an AngularJS application.
  • The <div> tag has the ng-controller attribute set to reference YammerGetUserCtrl, the controller module. 
  • The <tr> tag has the ng-repeat directive and it is used to iterate over each element in the users' collection.
  • The same <tr> tag also contains the filter directive and it used to search/filter by the properties of the users.

Also note the five <td> tags which use placeholders (identified by double-curly-braces).

  <td> {{ user.id}}</td>  
 <td> {{ user.full_name }}</td>  
 <td> {{ user.network_id }}</td>  
 <td> {{ user.activated_at}}</td>  
 <td> <img src= "{{ user.mugshot_url}}"/></td>  

The placeholders reference the properties of the JSON objects which will be set upon successfully consuming the REST service. You can easily identify the property names by copying the returned JSON into a JSON viewer - http://jsonviewer.stack.hu/

Running your code

Update the Javascript origin with the host name of your application if you haven't done so to avoid CORS error, something like:

  XMLHttpRequest cannot load https://api.yammer.com/api/v1/users.json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin....  

Lunch your app and navigate to the users.html page. This is how mine looks like - I added some css styles.

Summary

Congratulations! You’ve just developed an AngularJS client that consumes a Yammer RESTful web service.

One important security advice is to never use the access token the way it was described above in a public website. Anyone could impersonate the service-account user if the access token is compromised. You may explore other ideas of storing the access token in a database, or at least try to scramble it using any javascript obfuscation tool. A typical example is javascriptobfuscator.com

Lastly, you'd need to take each user through the authentication flow if you require user specific feed and if the yammer embed feed feature does not meet your requirement. See a sample implementation here

Feel free to download and re-use the source of the implementation that is described in this blog from GitHub

Tweet to @israel_ogbole

[bing_translator]