Excel Send to Trello

Well, that was fast. My latest add-in is published. Excel Send to Trello.

As per my previous post, the thing I found most interesting was how Excel full client seems to fail if you configure your server .htaccess file to prevent caching. Well, I found out that my Outlook Send to Trello add-in actually had the same problem too. The Outlook client just happened to refresh this morning and my icon disappeared there too. In Office online it seems to work, but in the full client you cannot seem to force the client to NOT cache. I see my files all pulled down locally in the Wef folder and my concern is that when I update the add-in it will not go get the latest every time… I have actually seem and beat my head over this problem a few times. But the solution there for anyone working on a BETA site for example making changes and all of a sudden the full-client stops refreshing your updates, this is a good article to keep handy.

But when Wef strikes in production, I have found customers are not so excited to blow away this folder and find all their add-ins, preferences, stored cached credentials and other goodies for each and every add-in are gone. Ergo why I added the no-cahce to the .htacess. Oh well. πŸ™

Also, just to share something else as I am delving more and more into publishing add-ins for real. As an Office Developer, in the traditional sense (aka boomer πŸ˜›, VBA/VSTO/COM), there are aspects of living in an HTML web world that I still learning (although this is an old one it comes up now and again because I forget something).

You have to worry about various attack vectors and sanitizing HTML strings. There are LOTS of libraries and solutions out there and Mozilla even has documented a possible standard supported in several browsers, but not all. It is a tricky thing because some sanitizers do too much or not enough, and then you also rely on a dependency which has now burned me more often than just owning things that might be a hundred lines of code for my own common library of goodies.

So, I have created my own based on various library implementations, and found the best option is to escape most of the stuff you find “injected” rather than remove it.

/**
* Sanitizes the string for possible malicious values
* @param {String} string
* @returns {String}
*/
static sanitizeString = (string) => {
try {
string = string.replace(/(javascript:|onerror)/gi, "");
string = string.replace(/undefined/gi, "");
string = string.replace(/<script/gi, "&lt;script");
string = string.replace(/<iframe/gi, "&lt;iframe");
string = string.replace(/<object/gi, "&lt;object");
string = string.replace(/<embed/gi, "&lt;embed");
string = string.replace(/<applet/gi, "&lt;applet");
string = string.replace(/<form/gi, "&lt;form");
string = string.replace(/<meta/gi, "&lt;meta");
string = string.replace(/<link/gi, "&lt;link");
string = string.replace(/<a\s/gi, "&lt;a ");
string = string.replace(/<img\s/gi, "&lt;img ");
string = string.replace(/="/gi, "&#x3D;&#39;");
string = string.replace(/='/gi, "&#x3D;&#39;");
string = string.replace(/=`/gi, "&#x3D;&#x60;");
string = string.replace(/\/>/gi, "&#x2F;&gt;");
return string;
} catch (e) {
return `[[SANITIZED STRING MALFORMED: ${e}]]`;
}
};

The important thing is that in the web world, anytime you take data from one service to another, or take input in a field, or grab input from some element on a page and insert it back into another element in your code, there is a hack waiting to happen if you do not sanitize.

New Excel Add-in & Side Loading

I recently published a new Excel Add-in called “Excel Send to Trello.” It is a pretty nifty add-in that will take an Excel sheet full of names, descriptions, and dates and build a bunch of Trello Cards on a specific list in Trello for you. It is just a start (v1.0) and has many features to come based on popularity.

But when I submitted the add-in to AppSource they came back to me with an issue that I was not seeing. Specifically, that the icon on the Ribbon was showing the default add-ins image and not my icon. I did not see this on my “beta” test site that I was using but had sent them a link to my manifest with was right to my production published version. The issue it turns out after a lot of testing was the .htaccess on my production site and the ONLY difference was this line:

<IfModule mod_headers.c>
    Header set Cache-Control "no-store, no-cache, must-revalidate"
</IfModule>

The problem it turns out is that Excel (full client) cannot read your icon without caching it. This works FINE in Excel Online. Oh well. So, I cannot prevent my add-in JS files from being cached which it turns out is a huge problem when I push an update it can take days/weeks for the Office application to expire its own cache. Unless someone know a way around this…

Anway, the way I discovered this was via sideloading the manifest pointing to my production site. And it also turns out I had forgotten how EASY Outlook makes sideloading. In Excel (full client) it is not that easy, because you do not have the option to point to your own manifest, except in Excel Online. Then I recall some work a colleague Marty Andren and I worked on many, many years ago, called the Web Add-in Side loader. And low and behold, it still works like a charm.

I was able to sideload in Excel using the command line tool, then I saw the problem. That is where I began the file-by-file comparison “Beta” to “Production” and found the difference mentioned above.

Anyway, it was an adventure, with a blast from the past! And keep an eye out, my new Excel Add-in will hopefully be published any day now.

Inline (a)Wait for JavaScript Constructors

I have been working on some new code and found a need to make a series of calls to server-side PHP, where it would process data in a MySQL database, munch on some data and then return a result. I wanted to perform this operation inside a class constructor, so I could essentially do something like this:

const myObj = new MyClassToCallTheServer();
let someValue = myObj.doSomegthingWithTheServerData();
view raw inline1.js hosted with ❤ by GitHub

The problem is that a constructor in JavaScript cannot be declared async and you cannot place an await on your server call. So, something like this fails:

export default class MyClassToCallTheServer {
#internvalValue = null;
constrcutor() {
// this.#internalValue = await this.#callTheServer(); <– the await will fail to compile
this.#internalValue = this.#callTheServer();
}
doSomethingWithTheServerData = () => {
// the #internalValue is still null becasue we could not await in the constructor
return this.#internalValue;
}
#callTheServer = async() => {
// imagine some code here with a fetch command…
return serverData;
}
}
view raw inline2.js hosted with ❤ by GitHub

To get around this, I learned a new trick, so I thought I would share:

export default class MyClassToCallTheServer {
#internvalValue = null;
#loading = false;
constrcutor() {
this.#internalValue = this.#callTheServer();
}
doSomethingWithTheServerData = async () => {
while(this.#loading) await new Promise(resolve => setTimeout(resolve, 10));
// the #internalValue is not null because we waited
return this.#internalValue;
}
#callTheServer = async() => {
this.#loading = true;
// imagine some code here with a fetch command…
this.#loading = false;
return serverData;
}
}
view raw inline3.js hosted with ❤ by GitHub

Small modification to the original code above and done:

const myObj = new MyClassToCallTheServer();
let someValue = await myObj.doSomegthingWithTheServerData();
view raw inline4.js hosted with ❤ by GitHub

I threw post this together fairly quickly, but hopefully it makes sense. ☺️

Determine MIME type from base64

In writing my new Outlook Add-in (Send to Trello), I got stuck on attachments. The first version did not include an attachments option because of two unique problems that compounded each other:

  1. The Office Add-in API no longer provides a Media Type/MIME Type with an attachment request. I am able to get the “blob()” from Office, but other than the file extension there is not a way to determine the type. But sometimes a file does not have an extension, or the extension is wrong, etc.
  2. The Trello API will not let you upload without supplying a MIME type, you cannot just give it a Base64 string as an attachment and let them figure it out.

So, I found out something interesting while researching a workaround. Most every base64 string of a specific file type starts with the same “prolog” of text. Using this, combined with the fallback of the file extensions, I was able to get attachments to work (for the attachment types supported by Trello). So, v1.02 will now include attachments.

Anway, as for the workaround I found, this might be ugly, but wanted to share it anyway:

/**
* Returns the data type based on the base64 string
* @param {String} base64String
* @param {String} fileName
* @returns {String}
*/
detectMimeType(base64String, fileName) {
var ext = fileName.substring(fileName.lastIndexOf(".") + 1);
if (ext === undefined || ext === null || ext === "") ext = "bin";
ext = ext.toLowerCase();
const signatures = {
JVBERi0: "application/pdf",
R0lGODdh: "image/gif",
R0lGODlh: "image/gif",
iVBORw0KGgo: "image/png",
TU0AK: "image/tiff",
"/9j/": "image/jpg",
UEs: "application/vnd.openxmlformats-officedocument.",
PK: "application/zip",
};
for (var s in signatures) {
if (base64String.indexOf(s) === 0) {
var x = signatures[s];
// if an office file format
if (ext.length > 3 && ext.substring(0, 3) === "ppt") {
x += "presentationml.presentation";
} else if (ext.length > 3 && ext.substring(0, 3) === "xls") {
x += "spreadsheetml.sheet";
} else if (ext.length > 3 && ext.substring(0, 3) === "doc") {
x += "wordprocessingml.document";
}
// return
return x;
}
}
// if we are here we can only go off the extensions
const extensions = {
xls: "application/vnd.ms-excel",
ppt: "application/vnd.ms-powerpoint",
doc: "application/msword",
xml: "text/xml",
mpeg: "audio/mpeg",
mpg: "audio/mpeg",
txt: "text/plain",
};
for (var e in extensions) {
if (ext.indexOf(e) === 0) {
var xx = extensions[e];
return xx;
}
}
// if we are here – not sure what type this is
return "unknown";
}

New Outlook Add-in: Send to Trello

I have been using Trello for a while now and one of the features I have found most useful is to take an email I received and turn it into a Kanban item on my backlog to address later. This allows me to archive the email but keeps it on my “Trello radar” as I work at my own pace through my personal backlog.

Recently, Trello removed their add-in from the Microsoft Office store. If you have the add-in installed, you will see this error:

Well, since they say necessity is the mother of all invention and I really had to fill the gap as it is part of my routine, I rolled my own. πŸ€“ To add a degree of difficulty, I wrote this in VS Code in Linux running in Windows Subsystem for Linux (WSL). See my previous post. It was a fun exercise as I am on vacation and using the time tom learn new things, engage in self-improvement and relax (coding is relaxing to me πŸ€“πŸ€“πŸ€“). In the end, I learned something and created something for everyone to enjoy.

Say hello to the recently published: Send to Trello Outlook Add-in.

Give it a try and let me know what you think.

New Trello Power-up: Demote a Card

Continuing to use Trello I found a need to take cards that had been sitting around a while and put them in a place other than Archive (and forget them). What I had been doing was copy/pasting them in checklists in another card and as needed taking the check list items and promoting them back to a card. However, after performing the manual process (which could take a lot of time) enough times, I decided it was time for another Power-Up. So, I created the Demote a Card Power-Up:

https://trello.com/power-ups/630d74e4e1bab6013d6c1160/demote-a-card

Also — while building this Power-Up, I also got a tad frustrated that there was not any IntelliSense code assistance from the Trello Library. So, I build one in JSDOC and will likely be publishing that on GitHub soon. Not sure how many other developers there are out there that write Power-Ups, but my hope is it might be useful.

Trello Writers Block – Browser Extension

I have been in full-bore developer mode of late, trying new things and writing a lot of code. One area I thought I would give a try is browser extensions. I find myself wanting to tag pages so that I can reference them later in something I am writing or working on. And because I like to store information in Trello, I wanted something that combined both. So, here is an extension I created that will do just that. It takes the page you are on and then creates an MLA or APA reference and then adds it to a card in Trello for you.

I published this to both the Microsoft Edge and the Google Chrome store:

The following screen shots show you what it looks like when you are using it:

Extension in action on my website.
The card once it is added to Trello.

This browser extension is useful if you are a student writing a paper (supports MLA and APA formats), an author writing a book, or a blogger or someone doing research and keeping track of references using notecards. Because Trello is a digital version of notecards and it is available everywhere and stored in the cloud, you don’t have to worry about the dog eating your homework. 😱

Add it to your browser and let me know what you think.

OfficeJS.dialogs version 1.0.8

I have recently updated the OfficeJS.dialogs to version 1.0.8. I have also updated the Node Package Manager version as well. You can get it by running the following command in the VSCode Terminal Window:

npm install officejs.dialogs

With this latest version comes a few bug fixes, some cleanup of the code, cleaner JSDoc documentation and a PrintPreview dialog. The PrintPreview started out as a proof of concept but it actually works for me – in the browser anyway. I am not sure how well it will work in any of the full clients as I have not tested it there yet. If anyone has a chance to test it, please let me know if you encounter any issues.

Here is a sample of the PrintPreview dialog:

print

Here is some code to implement it:


// this example takes the currently composed email message in Outlook,
// grabs its body HTML and then displays it in the Print Preview dialog.
var mailItem = Office.cast.item.toItemCompose(Office.context.mailbox.item);
mailItem.saveAsync(function(asyncResult) {
var id = asyncResult.id;
mailItem.body.getAsync(Office.CoercionType.Html, { asyncContext: { var3: 1, var4: 2 } }, function(result) {
var html = result.value;
PrintPreview.Show(html, function() {
Alert.Show("Print cancelled");
});
});
});

view raw

printpreview.js

hosted with ❤ by GitHub

 

Start Developing in OfficeJS Today with Script Lab

Recently, I have been working with a tool from Microsoft Garage which allows you to quickly develop OfficeJS projects in Word, Excel and PowerPoint. It is called Script Lab. You can find more information about it here:

Script Lab

It is also in GitHub project. You can read about it here:

https://github.com/OfficeDev/script-lab

To install Script Lab, open Word, Excel or PowerPoint and on the Insert tab, click Store.

insert

Type “script lab in” the search box and hit enter. Then select Script Lab from the list and click Add.

store

Once added, you will see a new Script Lab tab. From there, you click the Code button to open the task pane.

scriptlab

This tool comes with a lot of options:

  • If you click the hamburger menu you will see an option to Sign Into GitHub. This will allow you to create Gist’s and access and save code snippets to GitHub.
  • You can import Samples from GitHub (with a URL) and access Snippets.
  • There are options to change the color in the editor at the bottom from Dark to Light.
  • And once in your solution, you can change the template (the html page), the CSS Style and any references libraries.

NOTE:Β  You are dealing with a subset of the whole solution here. You cannot create Ribbon buttons or dialogs. You can only develop task pane add-ins. You can work with Script Labs in Word, Excel and PowerPoint, but not Outlook (yet).

Script Lab allows you to test things in a quick fashion. Here is what the code pane looks like:

code.PNG

NOTE: Script Lab defaults to TypeScript. It emits code in JavaScript on Export. There is no option to switch to only JavaScript. If you want to program in JavaScript that does not matter because JavaScript will work just fine as well. But in a shout out to Michael Zlatkovsky – who says Office of TypeScript are a match made in heaven – I look at this as an opportunity to get better at TypeScript.

One of the more difficult part of working in OfficeJS is to be able to quickly test how some feature of function or a block of code will work. In the VSTO and VBA days, I would pop open the Visual Basic Editor in Word, Excel or PowerPoint (ALT+F11), then open the Immediate Window (CTRL+G) and then start typing away to test specific object model items. There was nothing similar to this with OfficeJS, until now.

Script Lab is just that, a laboratory for you to test your ideas, your snippets, your work in progress. It is a way to test something before you put it into your full blown solution. You can then save code snippets as Gist (on GitHub) and export the solution.

And once you have written your code and are ready to test it, you very easily run it in the Taskpane or (my favorite) you can run side-by-side. From the Ribbon click the Run button and then you can still edit your code/html and then refresh and reload it in the side-by-side Run window. This makes developing a solution or just testing ideas VERY easy:

side-by-side.PNG

Once you are running you (kind of) have debugging tools, can see the DOM and see console messages. And my favorite part, is that once you have hacked out a basic add-in concept with buttons and text in the HTML and code in the script file, you can export your solution (Export for publishing). This will create a ZIP which will contain the XML manifest and HTML (with script inline), which is very similar to the minimalist add-in I outlined in a previous blog post:

OfficeJS: Create a (VERY) Basic Add-in for Excel

NOTE: If you do write async/await code the exported result will be very ugly and hard to follow. This is why you might want to export to GitHub if you use async/awat code (TypeScript) so you can keep the original source and then transpile to ES5 later.

However, I really like VS Code and the power of NPM and Browser-Sync, so I worked on converting a Script Lab project into an NPM project. This took quite a lot of work and that will be a topic for a future blog post, but the gist of it is to create a new Office Yeoman (yo office) project for the same application and then gut and Frankenstein it with the Script Lab code.

Bottom line, I love Script Lab.Β wlEmoticon-openmouthedsmile.png If you are working on an OfficeJS project and/or planning on creating an OfficeJS project and/or want to learn how to develop in OfficeJS, this is definitely THE tool to have.

 

easyEws v1.0.7 is now released

This has been slow coming, but I have just released v1.0.7 of easyEws. As per usual, it is on NPM and on GitHub. You can get the latest with the command:

npm update easyews

Or, you can install it into your solution with the command:

npm install easyews

In this version the JSDOC information is now full incorporated so you get great inline help with each command. I enhanced the library so that it works better with inline help and so I changed how the class is setup and exposed. I have updated the README.md on GitHub, but I still am working on examples and such, that will be done later. And I added new functionality, a moveItem command which can be used to move any item from one folder to another. This was a added due to feedback I received on LinkedIn.

Please feel free to reach out to me with any questions or suggestions.