easyEws Updated to 1.0.20

This was more than a patch this time. It was a minor update to two functions:

  • sendMailItem
  • sendPlainTextEmailWithAttachment

There was an issue reported (#12) where the sendMailItem function was not working in IE11. This was because it was created to take an inline object (ES6). Well on IE11 (which only supports ES5), it broke.

So, I fixed sendMailItem to support ES5 and also took the opportunity to add two often requested features of this function:

  • It will now allow you to submit HTML body content or Text. It will also parse the HTML for you if you submit it as is.
  • It will also now allow you to send both file attachment (new), and mail item attachments (original).

Please see the documentation for more information on the updates to this function: https://github.com/davecra/easyEWS#sendMailItem

Also I updated the sendPlainTextEmailWithAttachment function. Under the covers this uses the sendMailItem function. So I had to update it to use the new format so it would work as well. There was no change to it’s features/functionality however.

I did not get to the last item I have had requests for:

  • ability to specify recipients as To/CC/BCC. I will update this at some future date. Also, please let me know if you would like to see this.

Overall, the goal is to have the sendMailItem() function be a full multi-purpose function at some point. It is almost there, but please keep the suggestions coming.

easyEws v1.0.19 Released

There were a couple small bug fixes in the splitGroupsRecursivelyAsync() function. Thank you to Jack for making me aware of the issue as it has now been corrected.

The CDN to the latest versioned instance of the library:

https://cdn.jsdelivr.net/npm/easyews/easyEws1.0.19.js

Here is a link to my GitHub:

https://github.com/davecra/easyEWS

And it is also able to be installed from NPM with the command:

npm install easyews

OfficeJS: Get the current user’s Username

While working on a customers proof of concept, we determined that we needed to know who the current user opening the add-in is. In most scenarios where there is a Store Add-in, you have the user log in. But we are in a enterprise environment, have an embedded taskpane and did not want to nag the user every single time they opened the document.

Outside of the BETA API set, there actually is not a way to do this in Word, Excel and PowerPoint. In the current BETA API (soon to be released), is the new Single sign-on (SSO) API. Detailed here:

https://docs.microsoft.com/en-us/office/dev/add-ins/develop/sso-in-office-add-ins

I know, I know… you do not want to have to have the user sign-on and neither did we. But actually you do not need to. You make a call to getAccessToken() – after you have gone through the rather complex process of setting up your application in Azure AD – and in the returned token is the user information. Here is all you need for code to get to the username:

export async function getUserName() {
try {
let tokenData = await OfficeRuntime.auth.getAccessToken({ allowSignInPrompt: false, forMSGraphAccess: true });
var parts = tokenData.split(".");
var token = JSON.parse(atob(parts[1]));
return token.preferred_username;
}
catch (exception) {
console.log(exception.message);
}
}
view raw getUsername.js hosted with ❤ by GitHub

easyEws Updated to v1.0.17

There is one major change and one fix in this update:

  1. The library no longer has any dependencies on jQuery. As such all parsing is done with DOMParser and all loops are traditional (for, versus $.each()).

    NOTE: This is a fairly major change as it touches the core asyncEws call, which is at the very core over every call in the library. If you have an issue with this build, please point to the previous build of the library directly. See more below…
  2. The sendPlainTextEmailWithAttachment() function was fixed to submit parameters as a Object versus individually.

The GitHub repository has all previous versions. For example, to access the primary CDN, go to:

https://cdn.jsdelivr.net/gh/davecra/easyEws/easyEws.js

If you need to access a specific version (like the last one):

https://cdn.jsdelivr.net/gh/davecra/easyEws/easyEws1.0.16.js

Please let me know if you have any questions or issues.

Office Web Add-in Debugging in VS Code

Another recent announcement that has me excited is the ability to debug Office Web Add-ins directly from VS Code. Before this recent announcement, it was a hit or miss proposition. There was Visual Studio 2019, that did a pretty good job. But I liked the lightweight simplicity of VS Code. Visual Studio 2019 seemed too too heavy-weight. It’s hard to put my finger on how or why, but I really enjoy VS Code for Web Add-in development so much better. Except for debugging…

So, to debug, I actually did most of my dev/test in the web versions of Office (Excel online, Outlook online, etc.). Then came the Edge Developer Tools Preview which helped debug task pane add-ins in the full clients. But that did not help with things like the On Send event in Outlook or other UI-less functions. So, it was a struggle at times.

Now that has all changed!!!

The process is a tad more complicated than I like, but it does work. Essentially, you need to:

  1. Run VS Code as administrator
  2. Install the extension in VS Code by pressing CTRL + SHIFT + X and searching for the “Microsoft Office Add-in Debugger”
  3. Add the following code to the .vscode\launch.json file to enable Office Debugging in your project. You will need to update line #7, and replace the uppercase HOST text with the host application for your Office add-in.
{ 
   "type": "office-addin", 
   "request": "attach", 
   "name": "Attach to Office Add-ins", 
   "port": 9222, 
   "trace": "verbose", 
   "url": "https://localhost:3000/taskpane.html?_host_Info=HOST$Win32$16.01$en-US$$$$0", "webRoot": "${workspaceFolder}", 
   "timeout": 45000 
}

NOTE: If you create a new Office project with Yeoman, you will not need to add this line, it will be part of the default template going forward.

  1. Press CTRL+SHIFT+D to then open the Debug pane, select Attach to Office Add-in option from the drop down list at the top of the pane, and press F5 to start debugging.
  2. You can now set breakpoints, see variable values, etc.
Attach to Office Add-ins menu option

Script Lab for Outlook. Yeah!

OMG! This is a day I have been waiting for.

I do a LOT of Outlook Web Add-in development. A lot. I have made the move from Visual Studio to Visual Studio Code, from C# to JavaScript and have not looked back. However, there are a few things that make development in this new area difficult and that is rapid prototyping.

For C#, I could always go into VBA and see how the object model would behave when I needed to test a hypothesis. I was able to use VBA as a laboratory for ideas before I codified them into solid C# code in a VSTO Add-in. But there was no such laboratory in the JavaScript web add-in world, until now…

…Script Lab for Outlook has been released. And the best part, it is available in Outlook on Windows, Outlook on Mac and Outlook on the web!

Script Lab in Outlook for Windows
Script Lab for OWA

If you do a lot of Outlook development this will be a godsend. You will now be able to go into Script Lab and test your code ideas before you add them to your more complex add-in.

Open Outlook, go into the Office Store and type “Script Lab” and Script Lab for Outlook should come up in your list. Select and install it. Then open a message in Outlook and you should see the Script Lab items on the Home tab.

Happy coding!

Communication between Office Web Add-ins

Sometimes you have multiple add-ins and you need to facilitate communication between them. For example, a common scenario I have heard is that you have:

  • A Content Add-in that displays something like a graph or an organization chart.
  • A Taskpane app that allows you to manipulate settings, upload and download data from a backend web service.

You need to be able to facilitate communication between the two so that when updates happen to one add-in, the other receives those updates. I recently worked on a proof of concept that helped prove how this can be done.

The solution is to use the Document as a communication medium. In the particular case we used CustomXMLParts in the document. Here is how it would work:

  • One add-in would need to send an update to the other, so it would write a CustomXMLPart with a specific namespace and a “context” (basically, I am the TaskPane communicating) to the document.
  • Both add-ins will have a window.setInterval() thread running to check the documents for CustomXMLParts in that given namespace.
  • The timer on the Content Add-in would fire, find the new customXMLPart from the taskpane, read the contents and then update itself as needed and finally, delete the CustomXMLPart.

Here is the code for the Content Add-in to look for the message from the TaskPane:

Office.initialize = function(reason) {
// background thread checker
window.setInterval(() => { checkForPart(); }, 1000);
}
const ns = "http://pfe.microsoft.com/excelpoc/1.0";
const xml = "<message xmlns='http://pfe.microsoft.com/excelpoc/1.0'>&quot; +
"<sentby>[who]</sentby>" +
"<info>[data]</info>" +
"</message>";
const from_tp = "TASKPANE ADD-IN";
function checkForPart() {
Excel.run(function(context) {
/**@type {Excel.CustomXmlPartScopedCollection} */
var customXmlParts = context.workbook.customXmlParts.getByNamespace(ns);
customXmlParts.load();
return context.sync().then(function () {
if(customXmlParts.items.length > 0) {
/**@type {OfficeExtension.ClientResult<string>} */
var xmlData = customXmlParts.items[0].getXml();
context.sync().then(function() {
/**@type {DOMParser} */
var parser = new window.DOMParser();
/**@type {Document} */
var xmlDoc = parser.parseFromString(xmlData.value, "text/xml");
/**@type {Element} */
var who = xmlDoc.getElementsByTagName("sentby")[0];
/**@type {Element} */
var data = xmlDoc.getElementsByTagName("info")[0];
document.getElementById("message").innerText = who.innerHTML;
if(who.innerHTML == from_tp) {
// write tot he pane
var dt = new Date();
var currentTime = pad(dt.getHours(),2) + ":" + pad(dt.getMinutes(),2) + ":" + pad(dt.getSeconds(),2);
// update a DIV on the page
document.getElementById("message").innerHTML = "<p>Message sent on " +
currentTime +
" by " + who.innerHTML +
" and the message is " + data.innerHTML;
// now we delete the part
customXmlParts.items[0].delete();
return context.sync();
}
});
}
});
});
}

Next, here is the code in the Task Pane Add-in that will send the message for the content add-in to read:

const ns = "http://pfe.microsoft.com/excelpoc/1.0&quot;;
const xml = "<message xmlns='http://pfe.microsoft.com/excelpoc/1.0'>&quot; +
"<sentby>[who]</sentby>" +
"<info>[data]</info>" +
"</message>";
const from_tp = "TASKPANE ADD-IN";
function sendMessage() {
Excel.run(function(context) {
var data = xml.replace("[who]", from_tp).replace("[data]", "This message is coming from the taskpane.");
const customXmlPart = context.workbook.customXmlParts.add(data);
customXmlPart.load();
return context.sync().then();
});
}

Getting Started with OfficeJS

If you are just getting started with OfficeJS, then this post is for you. I will assume you have some understanding of what Office Web Add-ins are. However, there is one very basic point I will demonstrate in this tutorial:

  • An Office Web Add-In is simply a web site and an XML “description” file. I detailed this in this blog post. And we are going to build on that.

So, you are brand new to OfficeJS, and want to get started. The first thing you need to do is get your development environment up and running. There is a script for that:

Microsoft Office Development Environment Script

NOTE: For more information on this script, please read my blog post.

Next, you will need to pull down the Web Add-in Side Loader tool. Keep this ZIP on your desktop. This will be used later in the steps below to make it really easy for you to install the Add-in to Excel. However, if you prefer to do the steps manually, see the link below. For more information on this tool, please see my blog post and/or the GitHub repository.

Now that you have the development environment setup, lets build your very first, super basic Excel add-in:

  • Create a folder on your desktop called “MyFirstAddIn”
  • Open Notepad and copy/paste the code from HERE, then click File, Save, name it “manifest.xml”, change the type to “All Files *.*”, browse to folder on your desktop, and click Save.

NOTE: In this step you created the manifest file. This file will be used to “install” the add-in into Excel. Essentially, it will tell Excel where the web page is for the task pane.

  • Close Notepad, then open it again. Copy paste this code HERE, then click File, Save, name it “home.html”, change the type to “All Files *.*”, browse to the folder on your desktop, and click Save.

NOTE: In this step you created the primary file for website. This one file contains both the HTML and JavaScript needed to make the taskpane load in Excel.

  • Now you need to side load the manifest and you do that by first opening the ZIP file on your desktop: Set-WebAddin (v1.0.0.0).zip and extracting the Set-WebAddin.exe to the “MyFirstAddIn” folder.
  • Press Window+R to open the run dialog, and type CMD and press enter.

NOTE: This will open the Windows Command Prompt which you will use to sideload the add-in and run it.

NOTE: The word “sideload” is a fancy way to say install it for only your instance of Excel. It is also known as Developer Sideloading.

  • Change the directory to the folder on your desktop with this command:
cd "%userprofile%\desktop\MyFirstAddIn"
  • Next, type this command:
Set-WebAddin -test -manifestPath "%userprofile%\desktop\myfirstaddin\manifest.xml"

NOTE: In this step you have sideloaded the add-in to Office. This essentially tells Office you have an added an Excel add-in via the information in the manifest file which, when loaded tells Excel everything it needs to know about it, including where to find it. If you prefer to do the sideloading steps manually, you can follow them here.

  • Now you are almost ready. Type this last command (that is a dot/period at the end, very important):
http-server .

NOTE: The above steps start a local the http-server on your computer so that it will serve the webpage in the browser from the folder (.) you are current inside. You can now test this by clicking this link.

  • You are now ready to go. Simply open Excel and a new Blank Workbook. Then on the Insert tab, click the down arrow next to My add-ins and click BasicAddin. It should look like this:
The BasicAddIn in the Developer Add-ins menu
  • Your add-in Task Pane should load.
  • Click in cell A1, type “Hello World!”, and then in your Task Pane, click the “Click here” button and you should see “Hello World!” in the bottom of the page.
  • Once you are done, you can press CTRL+C in the command prompt window to shutdown the server and then to uninstall the add-in you can use this command:
Set-WebAddin -cleanup -manifestPath "%userprofile%\desktop\myfirstaddin\manifest.xml"

And that is it. There are three things to note here:

  • You created your first web add-in.
  • You did not use VSCode or any Integrated Development Environment. You did this only with Notepad.
  • But as an added bonus – you have also installed VSCode and the tools you need to start doing more complex things with Office Web Add-ins.

JavaScript, HTML, Web, CSS, front-end, back-end, web server, ports, local hosts… some, if not all of these are new terms if you are just getting into this new world of the Web and Web add-ins. But it does not have to be that complicated. As I referred to earlier, the following posts should be your next two stops on your journey:

Getting started as an OfficeJS Developer

Start Developing in OfficeJS Today with ScriptLab

If you have any questions, please reach out to me.

easyEws v1.0.15 Released

In this latest release I have incorporated my first community pull. A big thank you to Vijay Samtani for adding the sendMailItem. This new addition allows you to create a message to multiple recipients and with zero to many attachments.

Here is a link to the repository: https://github.com/davecra/easyEWS

You can references it in your code:

<script type="text/javascript" src="node_modules/easyews/easyews.min.js"></script>

And you can allow pull it down from NPM:

npm install easyEws