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:
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", "firstname.lastname@example.org");
go.Activity.Message = "Hey can we finally get this crazy write stuff working??";
go.Activity.Users.Add(new YammerActor("Anne Wallace", "email@example.com"));
go.Activity.Users.Add(new YammerActor("Garth Fort", "firstname.lastname@example.org"));
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. :-)
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.
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?
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.
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...
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.
Just downloaded your updated code and so far all seems to be running smoothly again :)
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?