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:
- 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);
- 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).
- 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.
- 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
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);
YammerMessages newMsg = YammerMessages.GetInstanceFromJson(response);
Console.WriteLine("message sent: " + newMsg.Messages.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", "email@example.com");
go.Activity.Message = "Hey can we finally get this crazy write stuff working??";
go.Activity.Users.Add(new YammerActor("Anne Wallace", "firstname.lastname@example.org"));
go.Activity.Users.Add(new YammerActor("Garth Fort", "email@example.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. 🙂