Skip to content

Instantly share code, notes, and snippets.

@brianly
Last active March 23, 2017 20:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brianly/5670410 to your computer and use it in GitHub Desktop.
Save brianly/5670410 to your computer and use it in GitHub Desktop.
Example OAuth client for Yammer using DotNetOpenAuth. You'll need to generate some model classes with http://json2csharp.com after poking around with the API endpoints. These are needed to handle the JSON returned when the OAuth dance is finished, and when user properties are requested.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using DotNetOpenAuth.AspNet.Clients;
using DotNetOpenAuth.Messaging;
using Newtonsoft.Json;
using YammerAuthentication.Yammer.Models.User;
namespace YammerAuthentication.Yammer
{
/// <summary>
/// An OAuth2 client for Yammer. Handles a lot of yucky stuff.
/// </summary>
public class YammerClient : OAuth2Client
{
#region Constants and Fields
/// <summary>
/// The authorization endpoint.
/// </summary>
private const string AuthorizationEndpoint = "https://www.yammer.com/dialog/oauth";
/// <summary>
/// The token endpoint.
/// </summary>
private const string TokenEndpoint = "https://www.yammer.com/oauth2/access_token.json";
/// <summary>
/// The user endpoint.
/// </summary>
private const string CurrentUserEndpoint = "https://www.yammer.com/api/v1/users/current.json";
/// <summary>
/// The _app id.
/// </summary>
private readonly string _appId;
/// <summary>
/// The _app secret.
/// </summary>
private readonly string _appSecret;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="YammerClient"/> class.
/// </summary>
/// <param name="appId">
/// The app id.
/// </param>
/// <param name="appSecret">
/// The app secret.
/// </param>
public YammerClient(string appId, string appSecret)
: this("yammer", appId, appSecret)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="YammerClient"/> class.
/// </summary>
/// <param name="providerName">The provider name.</param>
/// <param name="appId">The app id.</param>
/// <param name="appSecret">The app secret.</param>
protected YammerClient(string providerName, string appId, string appSecret)
: base(providerName)
{
_appId = appId;
_appSecret = appSecret;
}
#endregion
/// <summary>
/// Gets the identifier for this client registered with Yammer.
/// </summary>
protected string AppId
{
get { return _appId; }
}
#region Methods
/// <summary>
/// Gets the full URL pointing to the login page for this client.
/// </summary>
/// <param name="returnUrl">The return URL.</param>
/// <returns>
/// An absolute URL.
/// </returns>
protected override Uri GetServiceLoginUrl(Uri returnUrl)
{
var b = new UriBuilder(AuthorizationEndpoint);
b.AppendQueryArgument("client_id", _appId);
b.AppendQueryArgument("redirect_uri", returnUrl.AbsoluteUri);
return b.Uri;
}
/// <summary>
/// Queries the access token from the specified authorization code to complete the OAuth2 dance.
/// </summary>
/// <param name="returnUrl">
/// The return URL.
/// </param>
/// <param name="authorizationCode">
/// The authorization code.
/// </param>
/// <returns>
/// The query access token.
/// </returns>
protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
{
var b = new UriBuilder(TokenEndpoint);
b.AppendQueryArgument("client_id", _appId);
b.AppendQueryArgument("client_secret", _appSecret);
b.AppendQueryArgument("code", authorizationCode);
var tokenRequest = WebRequest.Create(b.ToString());
var tokenResponse = (HttpWebResponse)tokenRequest.GetResponse();
if (tokenResponse.StatusCode == HttpStatusCode.OK)
{
using (var responseStream = tokenResponse.GetResponseStream())
{
if (responseStream != null)
{
var reader = new StreamReader(responseStream);
var responseJson = reader.ReadToEnd();
var deserializedProduct = JsonConvert.DeserializeObject<YammerToken>(responseJson);
Debug.WriteLine("QueryAccessToken() returned {0}", deserializedProduct.access_token.token);
return deserializedProduct.access_token.token;
}
}
}
return null;
}
/// <summary>
/// Given the access token, gets the logged-in user's data. The returned dictionary must include two keys 'id', and 'username'.
/// </summary>
/// <param name="accessToken">
/// The access token of the current user.
/// </param>
/// <returns>
/// A dictionary contains key-value pairs of user data
/// </returns>
protected override IDictionary<string, string> GetUserData(string accessToken)
{
var b = new UriBuilder(CurrentUserEndpoint);
var tokenRequest = WebRequest.Create(b.ToString());
tokenRequest.Headers.Add(HttpRequestHeader.Authorization, string.Format(CultureInfo.InvariantCulture, "Bearer {0}", accessToken));
var tokenResponse = (HttpWebResponse)tokenRequest.GetResponse();
if (tokenResponse.StatusCode == HttpStatusCode.OK)
{
using (Stream responseStream = tokenResponse.GetResponseStream())
{
if (responseStream != null)
{
var reader = new StreamReader(responseStream);
var responseJson = reader.ReadToEnd();
var user = JsonConvert.DeserializeObject<YammerUser>(responseJson);
var data = new Dictionary<string, string>();
data.Add("id", user.id.ToString());
data.Add("name", user.full_name);
data.Add("email", user.contact.email_addresses[0].address);
data.Add("jobTitle", user.job_title);
data.Add("location", user.location);
data.Add("mugshot", user.mugshot_url);
data.Add("network", user.network_name);
data.Add("profile", user.web_url);
return data;
}
}
}
return null;
}
#endregion
}
}
@EdCharbeneau
Copy link

The new version of Yammer API requires that the access token be sent in the requests header as Bearer
You should add this to line 161 and remove line 158.
tokenRequest.Headers.Add(HttpRequestHeader.Authorization, string.Format(CultureInfo.InvariantCulture, "Bearer {0}", accessToken));

@kermed4
Copy link

kermed4 commented May 15, 2014

It seems that the YammerToken and YammerUser classes are missed, where can i find them.

@sudheer3041
Copy link

can you please post the remaining piece of code??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment