Calling Office Graph search via Office 365 APIs

Posted on 1/5/2015 @ 11:33 PM in #SharePoint by | Feedback | 1662 views

You might have heard, Office 365 APIs are out – and well they are good, but quite limited on what they can do. That is because what you have currently is just,

  • Mail
  • Contacts
  • Calendar
  • Discovery
  • FIles

.. and that’s it! In fact, the whole “help” for this is a few links here -

http://msdn.microsoft.com/office/office365/APi/api-catalog

Now, what about that fancy SharePoint REST and CSOM stuff?

So the first thing to understand clearly here is, Office 365 is much bigger than SharePoint. In fact, more and more I see SharePoint being marginalized (and that's okay!). But, one of the really amazing things that recently came out is the Office Graph search, which is like FAST search, except it applies to every Office 365 resource, not just SharePoint files. And the GQL (graph query language) is powerful enough to do very targeted searches too.

The question is, can we use O365 APIs to somehow query Office Graph search? Well, thanks to common consent, and the fact that the refresh token is reusable across all Office365 services, the answer is, Yes! :-)

Also, the GQL search API and URL is quite similar to the on-prem FAST search REST API. So the learning curve is, well more like a pencil less a cucumber.

Anyway here is how,

  1. Your app needs to have access to the Files API, specifically the rights to “Read user’s files”.
  2. Your app needs to first authenticate, get an access token, and query the discovery service, an get a resource URI for files.
  3. Your app then needs to get a fresh access token, with the new resource URI
  4. and then you can call the GQL endpoint with this new access token!

In code, here is how it looks.

   1:  string authority = "https://login.windows.net/winsmartsdev.onmicrosoft.com";
   2:  string resourceURI = "https://api.office.com/discovery/";
   3:  string clientID = "getthisguidefromazuread";
   4:  Uri returnURI = new Uri("getthisredirecturifromazuread");
   5:   
   6:  AuthenticationContext authContext = new AuthenticationContext(authority);
   7:  AuthenticationResult authResult = authContext.AcquireToken(resourceURI, clientID, returnURI);
   8:  string authHeader = authResult.CreateAuthorizationHeader();
   9:   
  10:  // don't do this in prod
  11:  System.Net.ServicePointManager.ServerCertificateValidationCallback =
  12:      ((s, c, c2, se) => true);
  13:   
  14:  HttpClient client = new HttpClient();
  15:  HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://api.office.com/discovery/v1.0/me/services");
  16:  request.Headers.TryAddWithoutValidation("Authorization", authHeader);
  17:  var response = await client.SendAsync(request);
  18:  string responseString = await response.Content.ReadAsStringAsync();
  19:   
  20:  // you can discover the below resourceURI by JSON parsing the above responseString, I've just hardcoded it.
  21:  resourceURI = "https://winsmartsdev.sharepoint.com/";
  22:  authResult = authContext.AcquireToken(resourceURI, clientID, returnURI);
  23:  authHeader = authResult.CreateAuthorizationHeader();
  24:   
  25:  client = new HttpClient();
  26:  request = new HttpRequestMessage(HttpMethod.Get, "https://winsmartsdev.sharepoint.com/_api/search/query?Querytext=%27video%27");
  27:  request.Headers.TryAddWithoutValidation("Authorization", authHeader);
  28:  response = await client.SendAsync(request);
  29:  responseString = await response.Content.ReadAsStringAsync();
  30:   
  31:  MessageBox.Show(responseString);

Have fun!

Sound off but keep it civil:

Older comments..