Local Music – Plan your night from Outlook

This was an experiment to build a local-data app using ElmCity, Bing, Azure, Office 365, and ASP.Net. None of which I had any previous experience with – here’s how I made it work.

What is an Office App?

Add-In’s vs. Apps

Office supports two kinds of developer plugins, known as Add-In’s and Apps.  Add-In’s have been around for longer, and behave like a more powerful macro within office. Key features of Add-In’s include:

  • Written in a .Net language (As opposed to VB-Script for macros)
  • Accessed via buttons and hooks in the Office UI
  • Runs entirely on the client machine

As Office moves to the cloud with Office-365, they created Office Apps. These Apps differ from Add-In’s in that they function as a web page rendered within Office, with JavaScript API hooks to perform office functions. This means:

  • The app behaves the same in both Desktop Office & Office-365
  • The app is written in HTML / Javascript
  • The app binaries are sourced outside of the client desktop (and runs as a website/service)

At the moment, these Apps may only be created for Outlook and SharePoint. I will focus on Outlook Apps.

While running Office Add-In’s on the client only is fairly simple, running App’s from a web-service offers new advantages. These advantages are most obvious in Outlook, where the App is managed within Exchange.

  • Everyone is on the same version. Fix a bug in your app and update the web-service, everyone gets the new experience.
  • Exchange Admin’s can give everyone the App within their Outlook experience automatically.
  • Your app selections roam with your exchange account automatically to all desktop instances, and Outlook-365 instances.
How do Outlook Apps work?

These Outlook Apps are made up of three components – a web site / service to be rendered within a portion of the Outlook UI, the space within the UI itself where the page is displayed along with the API’s to allow it to communicate with Outlook, and a Manifest file that tells Outlook what website to load in what UI location.

This Manifest is the ‘App’, which is added to your Exchange account via the Admin or the Office App Store, and then roams with your account through Exchange. Here’s an example of what the manifest looks like, these are mostly auto generated by the Visual Studio wizard and are included in your project.

  <OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MailApp">
    <DisplayName DefaultValue="LocalMusic" />
    <Description DefaultValue="LocalMusic Description"/>
      <Capability Name="Mailbox" />
      <SourceLocation DefaultValue="https://localmusic.cloudapp.net/Web/App/Home.aspx" />
    <Rule xsi:type="ItemIs" ItemType="Appointment" />

In order to create App’s for Office 2013, you’ll need the Office 365 Development Tools for Visual Studio.

Local Music & ElmCity

Jon Udell is a Evangelist within Microsoft who has been working on the ElmCity project. Paraphrasing Jon’s FAQ, ElmCity:

Collects online calendar events for geographic or topical communities, by Merging information from many sources. It does not store events in a centralized database, but rather operates as a hub, merging and reformatting these event feeds. Operates as a web-service on the Windows Azure platform.

The goal was to take Jon’s ElmCity feed and make it accessible from within Outlook, simplifying the task of organizing a night out by bringing the things that you can do in your local area into your Outlook meeting invite.

The App

The app was created as a Website, which would load a list of events by making an AJAX call to the ElmCity JSON feed. One of the first problems I hit was that the Outlook App framework won’t let you make cross-domain AJAX calls. This is for security reasons.

This means I had to relay the ElmCity feed through my Web URL. I created a WCF Web Service that when called would request the feed from ElmCity, clean up the data and then relay it down to my web page running in the Office App container. Fortunately, WCF makes it really easy to setup a JSON feed. More information about doing this can be found here, but my basic setup looked similar to below:

    MusicEvent[] GetEvents(string start, string end);

This is the parent container of the service interface that returns MusicEvent entities. These look like:

public class MusicEvent
    private string _title;
    private Location _location = null;
    private string _description = null;

    public string Hash { get; private set; }

    public string Title
        get { return _title; }
            _title = value;
            Hash = Utils.Hash(value);

    public Location Location
        get { return _location ?? (_location = new Location()); }
        set { _location = value; }

    public String Venue { get; set; }

    public Schedule Schedule { get; set; }

    public String Description
        get { return _description ?? "None Provided."; }
        set { _description = value; }
IIS Endpoints

Running these together required configuring both the Webservice and WebSite endpoints in IIS. In order to render it in Outlook and facilitate local debugging, this needed to be both HTTP and HTTPS endpoints. I set this up like so:

  <!-- system.serviceModel/behaviors: setup web binding for Restful URL handling -->
    <behavior name="restBehavior">
      <webHttp />
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>

  <!-- system.serviceModel: setup both HTTP and HTTPS bindings -->
    <add binding="basicHttpBinding" scheme="http"/>
    <add binding="basicHttpsBinding" scheme="https"/>

  <!-- service.systemModel/bindings: setup HTTP and HTTPS bindings for the website -->
    <binding name="secureWebHttp">
      <security mode="Transport" />
    <binding name="webHttp">
      <security mode="None" />

  <!-- system.serviceModel/services: bind both HTTP and HTTPS to the service -->
  <service name="LocalMusic.Web.ElmCityMusicService">
    <endpoint name="RestEndpoint" contract="LocalMusic.Web.IElmCityMusicService"
              binding="webHttpBinding" bindingConfiguration="secureWebHttp"
              address="" behaviorConfiguration="restBehavior" />
    <endpoint name="RestEndpoint" contract="LocalMusic.Web.IElmCityMusicService"
              binding="webHttpBinding" bindingConfiguration="webHttp"
              address="" behaviorConfiguration="restBehavior" />
Using Azure

In keeping with my keep-it-simple mindset, I decided to try to host this through Azure. Excluding a few HTTPS hangups, this turned out to be a really easy process, far easier than I anticipated. More detailed information can be found here, but the basic process was:

  1. Go to Azure and create an account, download the Visual Studio SDK’s and install them.
  2. Create a certificate and upload it to Azure following these processes.
  3. Add a project to your web-service solution, select “Cloud > Windows Azure Cloud Service”
  4. Add the Web Role, and in Configuration tab, check both HTTP and HTTPS endpoints.
  5. Under EndPoints, add both HTTP and HTTPS Endpoints as Input, adding the cert you created to the HTTPS endpoint.
  6. Right click the Azure project, select Publish, enter your account details and viola!

Your service definition file should look something like this:

  <WebRole name="LocalMusic.Web" vmsize="ExtraSmall">
      <Certificate name="LocalMusic"
                   storeName="CA" />
      <Site name="Web">
          <Binding name="HttpIn" endpointName="HttpIn" />
          <Binding name="HttpsIn" endpointName="HttpsIn" />
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
      <InputEndpoint name="HttpsIn" protocol="https" port="443"
                     certificate="LocalMusic" />

This is a work in progress, the next section will highlight the process of using the Office API’s, and the Exchange SOAP API’s.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: