Getting started locally with a basic O365 Word Add-In (no web hosting)

In this article I will demonstrate how to add a local shared drive to your Trust center which will facilitate developing basic Add-In functionality locally. This will not works for Add-Ins which require internet access (c:\local cannot call https) but for testing out your Word API skills this is perfect.

Introduction

Using the example set out on Word Add Ins (https://github.com/OfficeDev/office-js-docs/blob/master/word/word-add-ins.md) I was able to start playing with the Word JavaScript API locally. But at times I did not have a network share to map my add in with. With a little searching though I found that you can map a local file with \\localhost.

Taking from the example (which you should read first) I am going to modify the section about adding a trust center with an example.

My files are located at c:\Users\mroden\WebstormProjects\Azure\xomino365\localWordDev

Adding the Trust Center

Within Word 2016 select

  • File
  • Options
  • Trust Center
  • Click the Trust Center Setting Button
  • Select the Trust Center Add-Ins option on the left

In the Catalog URL bar I add \\localhost\C$\Users\mroden\WebstormProjects\Azure\xomino365\localWordDev and “Add Catalog”

w5

The Catalog is added as a network share

w6

make sure you check the “Show in Menu” option and restart Word

Using the example manifest

Using the example manifest provided in the Github Project (link again) and my own GUID I was able to create a manifest to my local files like this

 

<?xml version="1.0" encoding="UTF-8"?>
    <OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="TaskPaneApp">
        <Id>0646c7a1-c876-482b-9119-e0f25c30b610</Id>
        <Version>1.0.0.0</Version>
        <ProviderName>Microsoft</ProviderName>
        <DefaultLocale>en-US</DefaultLocale>
        <DisplayName DefaultValue="Boilerplate content" />
        <Description DefaultValue="Insert boilerplate content into a Word document." />
        <Hosts>
            <Host Name="Document"/>
        </Hosts>
        <DefaultSettings>
            <SourceLocation DefaultValue="c:\Users\mroden\WebstormProjects\Azure\xomino365\localWordDev\App\Home\home.html" />
        </DefaultSettings>
        <Permissions>ReadWriteDocument</Permissions>
    </OfficeApp>

Using that I was then able to run the example code. There were a couple of warning though to accept to get this to work.

w1

w2

w3

There we have it – the locally hosted example working.

w4

Using the technique to add firebuglite to the Add-In I was then able to start to copy an paste example code from Microsoft examples and start to learn the Word API and its nuances.

I am also found this Office Snippets site which was GREAT to get started as well

http://officesnippetexplorer.azurewebsites.net/#/add-in/word

Conclusion

Being able to map a localhost as a “network drive” allowed me to get started without the need to constantly check code into my local Git repository and sync it with Azure

Productive !!!

Advertisements

Limitations of Internet Explorer when considering using Cookies with O365 Add-Ins

In this article I will demonstrate some of the limitations of Internet Explorer’s cookie handling and how we need to architect out Office Add-Ins to prevent overload thereof.

Introduction

In a previous article I demonstrated how we could cache data within an O365 Add-In using document.cookie. The logical extension of this would be to use it to cache OAuth tokens from Azure AD. In that way users would not have to re-authorize every time then opened the Add-In.

An OAuth token in the O365 environment is typically around 1500 characters in length !

c1

Blowing up cookies in Internet Explorer(11)

In Internet Explorer there is a finite limit to the total size of the cookies on any one page. Those cookies are built up of all the cookies valid for that path.

We can easily demonstrate how to blow this up by successively adding more and more data to a cookie as you can see below. As we add the same OAuth token over and over again we successively increase the length of the cookie until we cross 10,000 bytes and it blows up to zero.

c2

The implications of this are stark; if we cache an OAuth token for more than six O365 Add-Ins (even if they all get a different name) in the same path, we could destroy all of them without the user even knowing. This is not acceptable and we need a more elegant solution.

Cookie Pathing

When creating a cookie, the path is an optional variable and if it is not added the “path” it defaults to the current location.

;path=path (e.g., ‘/‘, ‘/mydir‘) If not specified, defaults to the current path of the current document location.” – From Mozilla’s documentation

Using smart deployment architecture of Add-Ins

The implication therefore it to ensure that all of the Add-Ins are hosted in different directories (if they are in fact all deployed on the same server). Without setting a path the cookie will be created with the path to the current location.href directory

In the following example we set a cookie in one directory, and it is unavailable in the second directory.

c3

c4

Conclusions

Although this is probably not a significant issue in the wild (because most people are not going to put all their Add-Ins in the same folder for deployment), it is something good to be aware of. There is a finite limit to the size of any single cookie in Internet Explorer, don’t blow it.

 

Office Add-In problem solved: Internet Explorer by default does not allow CORS

In this article I will highlight an issue you may come across when you are trying to deploy an Office Add-In pulling data from a different domain.

Introduction

As my adventure into Office Add-Ins has continued I began to look at integrating data from outside of the O365 environment, into Office Add-Ins. In this example specifically pulling data from an external source into an Excel spreadsheet.  I followed the example code from the Build your first Excel add-in site and as I showed in the Firebug Lite post I was able to take the example code and make it work in an Add-In. I then wanted to prove to myself that I could pull it from a real data source.

The Data Source

The data source was a Domino web service which I was able to duplicate the data feed from. As you can see from the response headers I am adding everything necessary to allow CORS. I was hosting the Add-In at napacloudapp.com and looking to pull the data from copper.xomino.com

d1

But every time I ran the code I had an error which told me that the data could not be pulled from copper. For the life of me I could not figure out how until I came across a post on stackoverflow (which I cant find to reference now) which pointed me in the direction of IE security settings.

By Default CORS is turned off in Internet Explorer !

This is a setting which goes WAY back to the start of Cross Site Scripting issues and way before CORS itself was even a standard. This was actually something Microsoft did right with old IE !

If you go to Tool – Internet options – Security and look inside the Custom Settings option for Internet sites you will find that accessing data across domains is Disabled! So CORS isn;t even an options – cross domain data retrieval is off.

d2

The solution – Trusted sites

You can change this for Internet sites in IE10 or IE11 because both of those browsers have CORS built in to protect you – not so much in IE9.

In a business environment though you should be using Trusted Sites. If your Add-In HOST website (www.napacloudapp.com in my case) is added to Trusted Sites then the Access data across domain options is set to “Enable” and the problem is fixed.

Conclusion

This was something I first encountered way way back over 10 years ago when I was messing with XML Islands back in IE5 ! I knew it was there but had never really though about it in this context.

Because the client based Add-In experience is basically an embedded Internet Explorer instance, all the browser settings are carried into the experience with it.

As is often the case, once you understand the problem, the solution is relatively simple – it’s just getting there which is bothersome 🙂

 

 

 

 

Caching data across disparate O365 Add-Ins (and across client types)

In this article I will show how data can be cached between O365 office Add-Ins. This also includes different clients (Outlook, Excel etc, even Internet Explorer)

Introduction 

In the previous article we looked at how we are able to cache data within an Office Add-In using the browser’s document.cookie capability. In this article I will demonstrate how flexible this capability is and how it will even work across different Add-Ins and different applications.

Creating a Cookie

Cookies can be created and be stored within a specific domain/path and this is critical for this example to work. If you do not add a path variable to the cookie when creating it, it will not be available outside of the specific URL from whence it was created.

Going back to the setCookie code I used before:

function setCookie(name, value, duration) { 
  var now = new Date();
  var time = now.getTime();
  var expireTime = time + 1000*duration;
  now.setTime(expireTime);
  document.cookie = name+'='+value+';expires='+now.toGMTString()+';path=/';
}

We can see that there is a path=/ variable added in the creation. This statement means that this cookie is available to all web pages within the domain. Without it, the cookie is tied to the exact URL it was created from. Ideally you would not use the whole domain and you would be more specific to a single directory path. For the sake of this example though it makes life easier 🙂

What this means for us though is that we are able to create a cookie from one Add-In (URL Host) and as long as it is in the same domain, we can access that cookie value in another.

Creating the cookie in one Add-in

In the example below we are setting the cookie in the Outlook Add-in. The location.href  (which is the host page for the Add-In) is https://copper.xomino.com/xomino/extjs.nsf/O365Token/index.html. You can see from the Firebug Lite console that Outlook has appended the client name to the end of the URL.

c6

Using the setCookie function we create the “EXAMPLEToken” cookie and make it valid for 120 seconds.

We then open Excel and look at an Add-In I created there. As you can see from the example below the location.href for the hosted Add-In file is https://copper.xomino.com/xomino/O365.nsf/index.html. While the path is not exactly the same as the Outlook example – the hosting domain is (copper.xomino.com).

c7

The example above uses a getCookie function to get the value of the “EXAMPLEToken” and our value “xomino365” is returned successfully.

After two minutes a subsequent attempt to get the cookie fails because it has expired

c8

And it is as simple as that.

Conclusion

Adding a path variable to the cookie creation has allowed us to create the cookie within on Add-In (Outlook in this case) and access it from within another Add-In (Excel in the second case).

Caveat

Be aware that you need to have control and consideration about how much data you load into a cookie. Any Internet Explorer cookie for a given domain cannot be more than 10234 chars.

Addendum

What is actually interesting to find out is that even though the embedded client Add-In used Internet Explorer – any cookies created within the client are actually available within the stand alone Internet Explorer – and Vice Versa!

The cookie created in outlook before – is available in full Internet Explorer as well.

c9

This has to raise some fascinating potential for a truly immersive experience between users in the outlook clients and their web browsing. Here it is being set in IE and being read in the Excel Add-In

c10

 

 

Caching data in O365 Add-ins using document.cookie

In this article we will look at a technique for caching data (ultimately an OAuth token) within an Office Add-in.

Introduction

In previous articles I have discussed how to create an Authorization token in an Office Add-in and created the O365Token project on Github. These set up the possibility for using only JavaScript (no C#) to generate an Azure AD Authorization token which can then be used to interact with the O365 environment.

The only drawback so far is that every time the Add-In loads, a new window pops up to collect the token. It would be a much more elegant solution to be able to cache the token somehow and then re-use it. In this article we will look at using cookies for “caching” tokens in both the Outlook Client and the O365 web mail experience.

 

Cookies

Cookies have been around for almost as long as web browsers. They can be set to hold a value for a finite amount of time (permanent) or fixed to only this browser session (session).

Using the FireBug Lite technique previous described we are able to take a look at cookies and how they are stored within the browser.

Within Outlook itself we can see the cookies using document.cookie

c1

and we can set a cookie like this

c2

Setting an expire date

So that’s all well and good but if we actually want to store an OAuth token we want the cookie to be valid for no longer than the token itself. So then we have to set an expire date when we create the cookie. This is achieved like this:

function setCookie(value, duration) { 
  var now = new Date();
  var time = now.getTime();
  var expireTime = time + 1000*duration;
  now.setTime(expireTime);
  document.cookie = 'OAuthToken='+value+';expires='+now.toGMTString()+';path=/';
}

And in FireBug we can see this in action – in this case we set the cookie for 10 seconds, and immediately log it to the console

c3

and then more than 10 seconds later we just test the document.cookie and the OAuthToken is gone

c4

OAuth token generation

When requesting the OAuth token for O365, the token returned is valid for 3600 seconds (an hour). So if we cache the cookie for an hour it will be a good indication (by its existence) that it is still valid. If there is no cookie – we have to get a new token.

Conclusion

In this article we have seen how through the use of the browser’s cookies, we are able to potentially store data. In a future article we will look at how to store and reuse an OAuthToken

 

 

Significant productivity enhancer: Debugging and Developing O365 Add-Ins using Firebug Lite

In this article I will show you how to add a web based console capability Firebug Lite to your Office Add-Ins. This is particularly helpful when debugging Client Side applications.

Introduction

Firebug is a Firefox plugin and was one of the original developer tools of actual use and power. It has since been superseded by all the powerful work the Chrome Dev team have put into Chrome developer tools, but I still like it (old habits die hard).

Firebug Lite is a browser agnostic JavaScript version of this and provides a subset of functionality, directly in the browser.

This is especially helpful in the case of Client based Add-Ins. Client based Add-Ins use an embedded Internet Explorer experience and the Developer Tools are unavailable. There are ways to debug Add-Ins through Visual Studio, but seeing as I have no intention of writing a line of C#, that does not help me.

Firebug Lite

Adding Firebug Lite to your Office Add-in could not be simpler. Add the following to your application (be warned there are some issues with using it in conjunction with AngularJS).

The Firebug Lite console itself is 300px tall so ideally you need to make your Add-In 450px tall to be able to see it working

    <script type="text/javascript" src="https://getfirebug.com/firebug-lite.js">
        {
            overrideConsole: false,
            startInNewWindow: true,
            startOpened: true,
            enableTrace: true
        }
    </script>

That’s it. !

The JSON parameters are optional and not necessary if you are working in Outlook or OWA. They are necessary in the Word/Excel/PowerPoint clients though as the F12 key have an assigned function. These extra parameters open the Firebug Lite client in a new browser window. Still works, just not embedded directly inside of the Add-In.

From the documentation (Feb 2016 – Firebug 1.4 is live)

1.3. What’s Not in Lite?

Some features are not included in Firebug Lite 1.3, but due the new core that supports code sharing from Firebug, are likely to be included in the Firebug Lite 1.4 version:

  • Live editing for all panels
  • Layout Side Panel
  • Context menu options
  • Tooltips (to show colors and images)
  • Search feature

Other features though are too dependent in browser internals and will not be supported (at least in a near future*), such as:

  • Javascript debugger / Javascript profiler
  • Net panel / HTTP and XHR monitor
  • Access to restricted URI resources
  • Highlight HTML changes

*Discussions about remote debugging indicates that should be possible to support JavaScript debugging in browsers like Google Chrome and Opera in the future.

Looking at the Add-In

I used the basic example from napacloudapp and a stripped out the HTML on the front page – this gave me the ability to still run the Office.initialize in the app.js (necessary to deploy an Office Add-In). Initializing this Office object also gives me programmatic context to the rest of the “host”, be in Outlook or Excel.

f12

Having a console inside of the Add-In gives us a significant amount of flexibility for testing and seeing what is going on. To activate it – focus on the Add-In and hit F12. If you are outside of the Add-In in the browser this will trigger the normal browser developer tools.

In the browser:

f1

In the Outlook client

f2

In Excel

f3

Developing Add-Ins using Firebug Lite?

Oh Yes! Let’s be honest – we are all lazy and would rather not have to go back and forth deploying Add-Ins to test our code – with Firebug Lite now we can start to write the code which will ultimately be deployed as part of our applications. For example:

Got to the Office JavaScript API model page – https://msdn.microsoft.com/en-us/library/office/fp160953.aspx and open the API model on ZoomIt

f4

We can start to see the semblance of the document model for adding data to an excel cell. Let’s see if those objects exist – I can see from the ZoomIt that we can go:

  • Office
  • context
  • document

In the Firebug Lite console (in Excel) type out Office.context.document – and we can see an object exists

f5

type in any old crap and you get just that 🙂

f6

In this manner, not only can we start to test that our code works, we can also do it without having to keep redeploying the Add-In. Once we are comfortable with the code, we can move it to the real code base – this is a real productivity enhancer, especially when you are just getting into Office Add-In JavaScript development.

Building your first Excel Add-In example without deploying anything

Looking at the Build your own first Excel Add-In page we can use some of their code directly inside of the Firebug Lite console.

Click on the enlarge box in the console top right

f7

Then the Up Arrow bottom right – this will give us a pop-up window with a console we can actually read and use

f9

Copy the code from the Excel.run part of the code from the Excel page example and paste it into the right hand Firebug Lite pane

f10

and “Run” (or use CTRL-Enter)

f11

How freaking cool is that !!!!!!!! And we never had to deploy an Add-In to test that out.

Conclusion

Adding Firebug Lite to your Add-Ins during development will be an enormous time saver for you. It will allow you to initially develop you code without having to go through repeated deployments. It will also allow you to debug your code (more on that in later articles) by manipulating your JavaScript functions once they are actually deployed.

In another life I have been using Firebug Lite embedded inside of XULRunner browser, running inside of Eclipse (don’t ask) and it is very cool – more to come on that soon