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]

Comments

  • Anonymous
    February 24, 2015
    So you are about to start developing with the Yammer REST API? You probably have a lot of questions and
  • Anonymous
    July 31, 2015
    So you want to add multiple users to a yammer group via the API? You are not alone!
    This question
  • Anonymous
    September 28, 2015
    Can you please provide a code where one can view posts from 'All Company' Feed using the above mode of authentication i.e. with Bearer Token
  • Anonymous
    September 28, 2015
    Deepali, You may access the "All Company" feed using https://api.yammer.com/api/v1/messages/general.json

    So from the sample code I provided, change "users.json" to "messages/general.json". Also, change the ng placeholders in the curly brackets to match the JSON response objects.

    That said, it looks like the general.json endpoint is undocumented as such the yammer team reserve the right to change the workings of that endpoint without notice. Although it's being around and untouched for ages :)
  • Anonymous
    September 28, 2015
    Hi Israel, Thanks for the response. I was able to view the messages. But with Javascript the messages are returned in plain text and it will be a burden to give them proper look and feel as provided by Yammer Embed. Is there a way in which we can use Yammer Embed to do the same above task.
  • Anonymous
    September 29, 2015
    No, Yammer embed is not customizable. You'd need to build your custom UI if you must use the APIs.
  • Anonymous
    September 29, 2015
    I don't need to customize the feed. I just want to display the feed to all the users who are not even part of Yammer using Yammer Embed.
  • Anonymous
    October 14, 2015
    Hi,

    Good demo, however, using the Bearer token from the yammer site in my app does not work for me. It only works when I follow the proper documentation for how to obtain the Bearer token.
  • Anonymous
    October 15, 2015
    The comment has been removed
  • Anonymous
    October 20, 2015
    Hi Israel, I cannot find source code. Can you please update url for same?
  • Anonymous
    November 03, 2015
    Sorry for the delay, MichaelOHanlon. I've being preoccupied of late. I just committed the source code into a github repo and have updated the blog.https://github.com/iogbole/yam_ng. Let me know if you have any questions.
  • Anonymous
    November 04, 2015
    Hi Israel, Can we get the OAuth token pragmatically without open yammer login popup window?
  • Anonymous
    November 28, 2015
    The comment has been removed
  • Anonymous
    January 18, 2016
    The short cut to acquiring a test token is great for dev purpose. Thanks
  • Anonymous
    February 03, 2016
    Great post. How do I update the Javascript origin with the host name of your application. Thank you.
  • Anonymous
    August 03, 2016
    Hi, Your post is Very helpful..But I am facing CORS issue. I added headers in angular but still nothing changed.Here is my error:MLHttpRequest cannot load https://api.yammer.com/api/v1/messages/my_feed.json. Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.Please help me with this
    • Anonymous
      August 04, 2016
      @Indu Gupta - Did you update the Javascript origin in yammer with your application's host name?
      • Anonymous
        September 18, 2016
        Thank for your reply..Yeah, I added. then its working:)