Share-n-dipity

SharePoint serendipity is the effect by which one accidentally discovers something fortunate, especially while looking for something else entirely. In this case, it is the occassional musings, observations, and Ouija board readings about the phabulously

Using the Yammer API in a .NET Client Application

Using the Yammer API in a .NET Client Application

  • Comments 53
  • Likes

UPDATE 12/17/2013:  The authentication process Yammer uses to issue an access code changed recently.  If you have been getting a 404 error when executing the 3rd line of code previously described below to get the token, then read the updated step 3 below and/or grab the updated code attached to this post.

Recently I’ve been doing some work with the Yammer API from a console application.  The Yammer API does not have ton of documentation right now, and what is there is primarily targeted at using the API from a browser-based application.  But what about a classic scheduled task type application?  For example, suppose you wanted to write an application that would go through once a day and post the current leaders in a sales contest you’re having.  Imagine having your app read the data from SQL and then posting the information into the feed.  There just isn’t a lot of details on using it from server side code, and virtually none using .NET so I figured I would share and spread the joy.  Brian on the Yammer team was good enough to get me through a few of the rough spots so thank you Brian.  I also am attaching my console app to this post so that you have sample code to see for yourself.

To begin with, you should take a look at http://developer.yammer.com.  You’ll find the documentation there on the Yammer API and a sprinkling of samples throughout.  The most important part of this process (assuming you have a Yammer network to work in already) is that you need to register a Yammer application.  When you do that you will get a client ID and secret, and you will tell Yammer where token requests for your application should be returned.  This process is explained in the Yammer developer documentation here:  http://developer.yammer.com/introduction/#gs-registerapp.

Once you have your application registered you can start working on your code to call the Yammer APIs.  The first thing you need in order to do anything useful is an access token.  Obtaining an access token in Yammer is very much like getting an OAuth access token for a SharePoint App (and many other apps).  If you’re in the browser, a user would get a prompt where they would be informed that your application would like to access their Yammer information, and the user can allow it or not.  Once you get an access token it is good for a very, very, long time (“years” according to the Yammer documentation) so you don’t need to worry about doing this every time for every user – you can save your access token for a user and reuse it later.

This is important to remember, especially when you are just experimenting, because the Yammer documentation also describes how you can obtain an access token through the browser and then use that for your application.  If you go to http://developer.yammer.com/authentication/, scroll down to the bottom of the page and read the section titled Generate a test access token for instructions on how to do this.

Now in my case, I didn’t want to go that route because I want something a little more hands off and sustainable.  So what I did is go through the process once through the browser, trace everything with Fiddler, and then write some code to simulate a person going through that process.  The flip side of taking this approach is that it does require you to have the credentials of the user you want to simulate granting the application rights to data, so neither option is really perfect.   If you look at the code in my console app you go through this process to get an access token:

  1. Make a request to the oath endpoint in Yammer like this:  https://www.yammer.com/dialog/oauth?client_id=" + CLIENT_ID + "&redirect_uri=" + REDIR_URL.  In this case, “CLIENT_ID” is the client ID you got when you registered your app, and “REDIR_URL” is the Uri that the response from Yammer should return to when it’s finished.  It’s important to remember that if you test on different machines or in different environments, if you change where the response is going back to you MUST go update your application configuration in Yammer.  If your redirect_uri does not match the configuration of your application, then Yammer will just give you an error.  When you do get a response, there’s an “authenticity” token that you’ll need to extract out of the body and use on your next request.  Fortunately I’ve written wrapper code for making a request and extracting this token so it’s really just two lines of code:  response = MakeGetRequest(permUrl); and then string authToken = GetAuthenticityToken(response);
  2. Next you’re going to take the authenticity token and do an HTTP POST back to Yammer along with the credentials for the user.  When you do that there are also two cookies that you need to start sending along that were created when you made the first request:  yamtrak_id and _workfeed_session_id.  You’ll post that to https://www.yammer.com/session to create a session with Yammer.  Again, I’ve wrapped up the POST and extracting and resubmitting the cookies so you are just making one method call:  postResults = MakePostRequest(postBody, authUrl1).
  3. UPDATE:  This process changes right here as of December 2013.  Yammer has changed the authentication process, so here's what we do on this step now:  you just need to make the same exact request that you made in step 1, with one difference.  When you make the request, you need to include the Yammer tracking ID and session ID cookie.  I made this all very easy for you by just adding one additional optional parameter to the MakeGetRequest method - AddCookies.  So to make this final request you just need one line of code:  response = MakeGetRequest(permUrl, string.Empty, true);  You should get an access code in the return query string just as you did with the previous code.
  4. Now that you have an access code you can make a request to https://www.yammer.com/oauth2/access_token.json?client_id=" + CLIENT_ID + "&client_secret=" + CLIENT_SECRET + "&code=" + accessCode.  Just like before, “CLIENT_ID” and “CLIENT_SECRET” are what you got from Yammer when you registered your app; “accessCode” is the access code we got from step 3.  If this works, you’ll get a whole bunch of JSON In return that includes information about the current user, as well as the access token that you’ll need to include in all of your subsequent requests to read or write data into Yammer.

Now things get a lot more fun.  Since we’ll regularly be working with JSON when using the Yammer API, I’ve written a bunch of .NET classes that we can use to serialize and deserialize back and forth.  For example, when you get the access token back you can create an instance of one of my classes with code like this:  YammerAccessToken yat = YammerAccessToken.GetInstanceFromJson(response).  Once you do that you can easily refer to all the JSON goo in a .NET world.  So for example, to get the access token you can just refer to yat.TokenResponse.Token.  That is in fact how you will pass your access token to all subsequent requests that require it.

Now let’s start playing with the data.  Suppose you want to read the “All Messages” posts for a user?  It becomes a pretty trivial piece of code:

//make the request to Yammer for messages

response = MakeGetRequest("https://www.yammer.com/api/v1/messages.json", yat.TokenResponse.Token);

 

//serialize the JSON that’s returned into one of Steve’s Yammer objects

YammerMessages yms = YammerMessages.GetInstanceFromJson(response);

 

//enumerate each message and do something

foreach (YammerMessage ym in yms.Messages)

{

Console.WriteLine("Message:  " + ym.MessageContent.PlainText);

}

 

If you look at the class I created for messages you’ll see that you can get things like the message ID, sender ID, message type, sender type, Url, thread ID, language, plain text, rich text, attachments, likes, etc.  All of these are simple to retrieve using this custom class.

Now suppose you just want to get information about a particular user?  Again, two lines of code gets you there:

response = MakeGetRequest(currentUserUrl, yat.TokenResponse.Token);

YammerUser yu = YammerUser.GetInstanceFromJson(response);

 

Once you have the YammerUser you can get at things like name, department, job title, photo Url, contact information (like email), network settings, and the list of feeds and groups that they belong to.  The last couple of items are important, because each feed and group contains an identifier, and you have to use that identifier when posting to it.

 

Posting a message to a feed is done via a FORM post, so we can again reuse some of the other code we’ve written.  When you post a new message, Yammer actually returns a message collection back to you containing one message, and you can use the same method described above to serialize it into a class to view the results.  Since this is just sample code, here’s an example of how I let the user running the console app just type in the message that they want posted to the newsfeed:

 

bool broadcastToAll = false;

Console.WriteLine("Type in the message you want posted to the Yammer IT Group then press enter:");

string myMessage = Console.ReadLine();

 

//it.GroupID is a group that I got for my user in one of the previous code samples

//the complete list of form variables that you can submit and their definition can

//be found at http://developer.yammer.com/restapi/ in the Manipulating

//Messages section

string msg = "body=" + myMessage + "&group_id=" + it.GroupID + "&broadcast=" + broadcastToAll.ToString();

 

//try adding the message

response = MakePostRequest(msg, ("https://www.yammer.com/api/v1/messages.json", yat.TokenResponse.Token);

 

if (!string.IsNullOrEmpty(response))

{

YammerMessages newMsg = YammerMessages.GetInstanceFromJson(response);

Console.WriteLine("message sent: " + newMsg.Messages[0].MessageContent.PlainText);

}

 

Posting to a Yammer App page can be done using Yammer’s Open Graph API; they’ve documented it here:  http://developer.yammer.com/opengraph/.  You submit a multi-level chunk of JSON to create an entry using Open Graph, but again, I’ve created a custom object to make it easy for you.  Here’s an example of using my object that wraps the JSON needed for Open Graph:

 

YammerGraphObject go = new YammerGraphObject();

go.Activity.Action = "create";

go.Activity.Actor = new YammerActor("Steve Peschka", "speschka@www.northwinds.com");

go.Activity.Message = "Hey can we finally get this crazy write stuff working??";

 

go.Activity.Users.Add(new YammerActor("Anne Wallace", "annew@www.northwinds.com"));

go.Activity.Users.Add(new YammerActor("Garth Fort", "garthf@www.northwinds.com"));

 

YammerGraphObjectInstance jo = new YammerGraphObjectInstance();

jo.Url = "http://www.vbtoys.com";

jo.Title = "yammo objectola";

 

go.Activity.Object = jo;

 

//the key is really here – I’ve overridden the ToString() method to return a

//JSON payload that can be used with Yammer

string postData = go.ToString();

 

//now we can just post the data to Yammer to create it

response = MakePostRequest(postData, graphPostUrl, yat.TokenResponse.Token, "application/json");

 

That pretty much wraps it up.  This is far from an exhaustive list of things you can do with Yammer.  What I wanted to do was just to give you a starting point of common tasks and data serialization techniques that you can use to build from.  I think as you look into building with the Yammer API you will be able to use the sample application I’ve attached to this posting as a good starting point and pattern for creating whatever custom Yammer application you like.  Now go get Yammered.   :-)

Attachment: YammerDotNet.zip
Comments
  • Great Post, right now I have to develop an application to get the user for specific yammer group. Quick question, Does the application need .net 4.5, right?

    Thanks in advance

  • Hi @Pablo, it really doesn't need .NET 4.5 because you are using REST calls to retrieve the data.  So even though my samples are written 4.5, you should be able to use as is, or at the very worst, make some very minor modifications to work with previous versions of .NET.  It's not because there's some managed API in there for Yammer that I'm using, it's just because of the WebRequest / WebResponse code I'm using as well as generics and serialization.

  • Hi , i am trying to use the same but it seems id does not work , i think the yammer has changed some API which does not work with console application do you have any idea.

  • Hi Steve,

    I have also been having some problems since last week as I believe something was changed in the Yammer API regarding the access code (in step 3) being returned/passed in a query string.

    I have narrowed down the issue to acquiring the access code, as if we get the code manually (not ideal) and pass this to the authentication step then it can continue as it did before without any issues.

    Have you revisited this at all since the change and if so it would be great to hear how (if) you got it working again?

    Thanks in advance

  • Hi @Pankaj and @Lee. The process to obtain an access code did in fact change. I have figured out how to get it using this new process and updated the post and sample code attached to this post. Give it a try and see if that doesn't resolve your issue.

  • Hi Steve, I tried your updated code but get a "Failed to get access token!". In order to try the sample I did the following: 1. Created a new app (with redirect to https://www.yammer.com) 2. Updated the following variables in the code: CLIENT_ID, CLIENT_SECRET, REDIR_URL, userName, pwd 3. Build the project without errors and ran it from the command line Looking into the code, one of the things I noticed, is that in line 137, "qsCode" doesn't have a "code" block. If you have the time, please advice... Cheers, Martin

  • Hi @Martin, make sure your REDIR_URL points to the hostname of the machine where you code is actually running. That's the most common reason the request fails.

  • @steve thanks for the reply is it possible to use the code in a console applications.

  • Hi Steve, Just downloaded your updated code and so far all seems to be running smoothly again :) Thanks!

  • Hi Steve, great article! I´m also fighting with your sample console app, not sure what REDIR_URL should be used in my console app. As far as I understood, Yammer Redirects to that URL if the authentication process is successful. So what to do in a console app - I always run into the "Failed to get access token!", the code is always emtpy. Thx for tips! Tony.

  • I think my problem in the comment before has been solved - the REDIR_URL is only the URI of the app, correct? So I use REDIR_URL = "http://localhost". When opening my app in the browser with https://www.yammer.com/dialog/oauth?client_id=&redirect_uri=http://localhost I get the resulting code like http://localhost/?code=3vd5... When starting the app here I get... //ADDED 12/17/2013 TO REFLECT CHANGES YAMMER MADE IN AUTH PROCEDURE response = MakeGetRequest(permUrl, String.Empty, true); ...a HTTP 404 and the response is "". So no code=.., no fun. I don´t understand the obtaining of the "code" information. When getting the code in the browser and using this code in the app it works (one time, then the code is no longer valid for new requests, ok for that). For me it seems the app doesn´t get that code, but instead the HTML document from yammer where the user shall allow the app. Steve, do you have a tip for me, what I´m doing wrong? Thx!! Tony

  • Hi steve! How about log out? Do you have any idea how to do that? -mia

  • I want to integrate yammer into my Windows store app, what should be my redirect_uri

  • Hi @Tony, the REDIR_URL is the name of your machine where your code is running. localhost should work because your local machine, where the code is running, will resolve that to the local machine. In my code sample I think it has sppdxwin8 for REDIR_URL because that's where my machine is running. Just remember that whatever value you use for REDIR_URL, you need to use that same value in your Yammer network when you configure your application. Meaning when you go into look at My Apps in in Yammer, the Redirect URI should also be "localhost" if that's what your REDIR_URL is - they need to match.

  • Hey Steve!! Thank a lot. This post helped me a lot! Quick question, how do i include an attachment while posting?

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment