How to Turn Outlook Emails into Complete Asana Tasks—not Just Task Comments

Man pointing at computer screen with email and coding windows, appearing stressed

Email frequently marks the beginning of a task, but it rarely contains only a task name.

A customer request may include supporting documents, deadlines, several people who need to follow the work, and a long conversation explaining why it matters. An approval email may need to become a subtask under an existing project. A later reply may need to be added to the same task rather than creating another duplicate.

Asana’s Outlook integration provides a convenient answer when the requirement is straightforward: open an email, create an Asana task, or add the message to an existing task.

For many users, that is enough.

But creating a basic task and converting an email into a complete, maintainable Asana work item are not always the same thing.

I developed Send to Asana for Outlook for the workflows that begin where basic task creation ends.

When the Asana for Outlook add-in is enough

The standard Asana integration is appropriate when you need to:

  • Create a new task from an Outlook email.
  • Copy the email content into Asana.
  • Select a project.
  • Assign the task.
  • Set a due date.
  • Add an email to an existing task as a comment.

That covers a common and useful workflow. There is no reason to add complexity when those are the only capabilities required.

The distinction becomes important when the email itself is part of the business record or when the Asana task requires additional structure.

The email is sometimes more than text

Copying the body of an email into a task description or comment captures the words, but not necessarily the email as an object.

Users may need to preserve:

  • The original message in a recognizable email format.
  • The sender, recipients and original formatting.
  • The complete conversation for audit or reference purposes.
  • A file that can be retained with the task after the email leaves the inbox.
  • A PDF representation that colleagues can open without searching Outlook.

This issue appears repeatedly in Asana’s own community forum.

In one discussion, a user explained that the standard Outlook add-in copied the email thread into a comment, but that long copied conversations were unwieldy. The user wanted the email uploaded as a file attachment instead. Other participants confirmed that attaching the email was different from copying its text, and that the available drag-and-drop workaround was awkward.

Another user described wanting the original email retained so it could later be opened, replied to or forwarded while preserving its formatting and context. The manual alternative was to save the message locally and upload it separately, which undermined the purpose of an Outlook integration.

Send to Asana addresses this by allowing the Outlook message itself to be attached to an Asana task as an .eml file or converted to PDF.

The task can still include the readable email content in its description or comments, but the original message can also remain available as a separate file.

Outlook attachments should not require a detour through the desktop

Many task-creating emails include files that are essential to the work:

  • Contracts
  • Screenshots
  • Proposals
  • Specifications
  • Spreadsheets
  • Approval documents
  • Customer-provided evidence

A user should not have to save every file from Outlook to a local folder and then upload it again to Asana.

This became more visible with New Outlook. A 2026 Asana forum discussion reports that attachments can no longer simply be dragged from New Outlook into an Asana task. The user must first save the attachment and then upload it separately.

Send to Asana reads the attachments from the currently opened Outlook message and allows the user to choose which ones should be sent.

This is deliberate. Sometimes all attachments belong with the task. Sometimes an email includes a company logo, an irrelevant image, an old document or several files that should not be included.

The user can select the relevant files rather than accepting an all-or-nothing transfer. Multiple files can also be combined into a ZIP archive when that is more appropriate.

Creating a task is not always the correct action

An email may represent:

  • A new task.
  • A new subtask under an existing task.
  • Additional information for an existing task.
  • Additional information for an existing subtask.
  • A continuation of a conversation that has already been associated with an Asana item.

Creating a new task for every message can fragment the work and create duplicates.

Send to Asana supports four distinct workflows:

  1. Create a new Asana task.
  2. Create a subtask beneath an existing task.
  3. Add the email to an existing task.
  4. Add the email to an existing subtask.

This allows the user to decide what the email means operationally instead of forcing every message through the same task-creation path.

The correct project is not always specific enough

Selecting the correct project is important, but many Asana projects are organized into sections representing stages, teams, priorities or types of work.

A task placed in the project but not in the correct section may still require someone to reorganize it afterward.

Send to Asana allows the user to select both:

  • The Asana project.
  • The destination section within that project.

A preferred project and section can also be saved as defaults. That makes the common route fast without eliminating the ability to choose a different destination for an unusual email.

A task often needs more than a name and due date

A useful Asana task may also require:

  • An assignee.
  • A due date and due time.
  • Tags.
  • Newly created tags.
  • Collaborators or followers.
  • Completion status.
  • A clean and useful description.

Send to Asana exposes these details from Outlook before the task is created or updated.

It can also automatically assign newly created tasks and subtasks to the current user. This removes one repetitive step for people who regularly turn their own inbox into an action list.

The objective is not to expose fields merely because they exist. It is to prevent the user from creating an incomplete task in Outlook and then immediately opening Asana to finish it.

Long email threads usually make poor task descriptions

Copying a full email conversation into Asana can produce a description containing:

  • Repeated replies.
  • Signatures.
  • Legal disclaimers.
  • Quoted history.
  • Formatting debris.
  • Several screens of context before the actual request becomes clear.

Sometimes the complete thread is necessary. Often it is not.

Send to Asana allows the user to choose among several approaches:

  • Use a cleaned version of the email.
  • Include only the most recent response.
  • Use the complete original message body.
  • Edit the description manually.
  • Generate an AI summary of the message.

The task can therefore contain a concise, actionable description while the original email remains attached separately for complete reference.

Later replies should return to the same task

A common failure in email-to-task workflows occurs after the first message.

The initial email becomes an Asana task. Two days later, someone replies with a decision, a corrected document or additional requirements. The user must then remember which Asana task was created, search for it, and manually add the new information.

The alternative is accidentally creating another task for the same conversation.

Send to Asana can associate an Outlook conversation with its Asana task. When a later message in the same conversation is opened, the add-in can recognize the relationship and append the new content to the existing task.

This helps preserve one task for one continuing piece of work.

Task names should communicate more than the raw subject line

Email subjects are often poor task names:

  • “RE: RE: Question”
  • “Following up”
  • “Document”
  • “Urgent”
  • “Please review”
  • “FWD: Customer issue”

Send to Asana can construct a task name using email properties such as the sender, subject and date. It also supports configurable naming patterns.

The original subject remains available, but the Asana task can be named according to the organization’s workflow rather than accepting whatever subject happened to arrive in Outlook.

More capability should not mean more work every time

The purpose of Send to Asana is not to force every user through every option.

Defaults and remembered settings reduce repetitive decisions. Depending on the workflow, users can configure options such as:

  • Default project.
  • Default section.
  • Always assign new tasks to themselves.
  • Send email content to the description or comments.
  • Preserve the original email as .eml or PDF.
  • Include only the latest response.
  • Automatically recognize linked conversations.
  • Reuse preferred task-name patterns.

A simple task can still be created quickly. The additional controls are available when the email requires them.

Which Outlook-to-Asana workflow should you use?

Use the standard Asana for Outlook add-in when:

  • You need a straightforward task.
  • The email body is sufficient context.
  • You do not need the original email preserved as a file.
  • You do not need a subtask.
  • Basic assignment, project and due-date options are enough.
  • You are comfortable finishing any additional task configuration in Asana.

Use Send to Asana when:

  • You need to attach the original email as .eml or PDF.
  • You need to select individual email attachments.
  • You need to create or update a subtask.
  • You need to select a specific project section.
  • You need tags, collaborators, due time or completion controls.
  • You want to clean or summarize a long conversation.
  • You want later replies appended to the same task.
  • You want project, section, assignment or naming defaults.
  • You want to complete the task configuration without leaving Outlook.

Neither approach is universally correct. The appropriate choice depends on whether the email is merely the source of a task or remains an important part of the task itself.

Why I built Send to Asana

I did not create Send to Asana because Asana lacked an Outlook integration.

I created it because many real workflows require more than the initial act of creating a task.

Users were trying to preserve original emails, avoid manually downloading attachments, create subtasks, route work into sections, maintain long conversations and configure complete tasks without repeatedly moving between Outlook and Asana.

Those were not abstract feature ideas. They were recurring workflow problems.

Send to Asana was built to give users more control over what the email becomes:

  • More than copied text.
  • More than a basic task.
  • More than an all-or-nothing attachment transfer.
  • More than a disconnected series of messages.
  • More than a task that must still be completed somewhere else.

The goal is straightforward:

Turn the selected Outlook email into the correct Asana item, with the context, files, structure and task details needed to continue the work.

[Learn more about Send to Asana for Outlook]

Getting Outlook Emails into Microsoft Planner: Native Options, Power Automate, and Send to Planner

Stressed woman at desk with two computer monitors showing spreadsheets and emails, three coworkers laughing behind her in open office

A common Microsoft 365 workflow starts with a simple question:

How do I get an Outlook email into Microsoft Planner?

There are several possible answers, depending on what “into Planner” means.

You may only need a personal reminder. You may want an automated process that handles every matching email the same way. Or you may need to review each message and decide where the resulting Planner task belongs.

The main options are:

  1. Flag the email.
  2. Manually create a Planner task.
  3. Build a Power Automate flow.
  4. Use an Outlook add-in such as Send to Planner.

Flagging the Outlook Email

The easiest native option is to flag the message in Outlook.

Flagged emails can appear in Microsoft To Do and within the task views available through the newer Microsoft Planner experience. This works well when the goal is simply to remind yourself to return to a message.

However, flagging does not create a normal task in a selected Planner plan.

You cannot use the flag itself to choose:

  • A shared Planner plan
  • A bucket
  • An assignee
  • Start and due dates
  • Selected portions of the email
  • Specific attachments

Flagging is therefore best suited to personal follow-up rather than team task management.

Manually Creating the Planner Task

The next option is to open Planner and create the task manually.

This gives you full control, but it also means moving between Outlook and Planner and copying the relevant information yourself.

Depending on the email, that may include:

  • Rewriting the subject as a task title
  • Copying part of the message body
  • Saving and uploading attachments
  • Assigning the task
  • Selecting a bucket
  • Adding dates
  • Preserving a reference to the original email

Manual entry is reasonable when this only happens occasionally. It becomes repetitive when email is a regular source of work.

Using Power Automate

Power Automate is often the first recommendation for connecting Outlook and Planner.

A flow can create a Planner task when an email:

  • Arrives from a particular sender
  • Contains certain text
  • Is moved into a folder
  • Is assigned a category
  • Meets other predefined conditions

This is a good solution when the workflow is consistent.

For example, if every message sent to a particular mailbox should create a task in the same plan and bucket, Power Automate may be the correct tool.

The challenge is that many email-to-task decisions are not consistent.

One email may need to go to an operations plan. The next may belong to a customer project. Another may only require one paragraph from a long thread. Some attachments may be useful while others are signatures, logos, or unrelated files.

The user may need to decide, for each message:

  • Which plan to use
  • Which bucket to use
  • Who should be assigned
  • What the task title should be
  • Which part of the message to include
  • Which attachments to include
  • Whether a start or due date is needed
  • Whether the message came from a personal or shared mailbox

Power Automate can support sophisticated workflows, but an interactive process with many optional decisions can require a substantial amount of configuration.

At that point, the flow is no longer simply “when an email arrives, create a task.”

It becomes a small application.

Why I Built Send to Planner

I originally built Send to Planner because I regularly encountered emails that needed to become Planner tasks, but they did not all follow the same rule.

The problem was not merely creating the task. The problem was deciding what the task should contain and where it should go.

Send to Planner is an Outlook add-in that lets the user make those decisions while viewing the email.

The user can select options such as:

  • Planner plan
  • Bucket
  • Task title
  • Assignee
  • Start date
  • Due date
  • Email body content
  • Attachments
  • A reference to the original message

This makes it possible to create a complete Planner task without moving back and forth between Outlook and Planner.

The sent email inside Microsoft Planner
Email message fidelityAll attachments and email as PDF

It also avoids forcing every email through the same predefined automation.

Choosing the Right Approach

Each method has a valid use case.

MethodBest suited for
FlaggingPersonal reminders and follow-up
Manual entryOccasional task creation
Power AutomateRepetitive workflows with consistent rules
Send to PlannerInteractive task creation where each email may be different

The question is not whether Power Automate or an Outlook add-in is universally better.

The better question is:

Does the same rule apply to every email?

When the answer is yes, Power Automate is often a strong solution.

When the answer is no, an interactive Outlook add-in may be more practical.

Security and Microsoft 365 Administration

Third-party Outlook add-ins may require approval from a Microsoft 365 administrator, especially in managed organizational environments.

That is a reasonable concern.

The Send to Planner product page includes information covering:

  • Requested Microsoft permissions
  • Data access
  • Data flow
  • Privacy
  • Security
  • Administrative deployment

Send to Planner is also going through the Microsoft 365 App Certification process.

Certification is not a substitute for an organization’s own security review, but it provides an additional level of independent validation. I am also willing to work directly with Microsoft 365 administrators or security teams that need more information before approving the add-in.

Learn More

For a detailed comparison of the available methods, including flagged email, manual task creation, Power Automate, and Send to Planner, see:

How to Get an Outlook Email into Microsoft Planner

For product details, features, security information, and installation options, see:

Send to Planner for Microsoft Outlook

The complete user guide is also available here:

Send to Planner User Guide

How Content Security Policy Affects Office Add-ins

I now have several add-ins in AppSource and all doing well. But one in particular is getting a LOT more attention than others: “Send to Planner.” While popular with the general public, IT admins are not because it needs so many permissions. I wrote a fairly complex explanation to why it needs to many permissions: https://kryl.com/?page=kb&id=31. Ok, so some say – fine, I trust that, but others want more, a lot more, like my latest Penetration Testing Results. They also ask for more than attestation and wonder why I am not on the Office 365 certified list… me too, it turns out…

Sidebar first… This is leading somewhere, I promise… So, Office 365 Certification… I jump through God knows how many hoops to try to get my Office 365 certification rather than just a generic Publisher Attestation. I have to provide a TON of documentation and one of the artifacts is a good penetration test which are actually a LOT of work. Anyway, after a few weeks of gathering information, study on how to do this, that or the other thing, a ton of back-and-forth in email… I was told…

“Well, so, yeah… Your company is… yeah… just not big enough for us to consider you.”

So, when I submitted the VERY FIRST FORM with employee count you still let me proceed! I waste weeks, collecting and finagling and answering to artifacts and this… Ugh! Anyway, it was an educational experience and from that, I learned how to create a good Pen Test document.

…Back to the main attraction. Turns out to make administrators HAPPY, you need to have a really good Pen Test and one of the picker areas they remark upon is your sites Content Security Policy. I use an NGINX server in Azure. It took a LOT of finagling to get it restrictive enough for me to score an A+ on https://securityheaders.com:

script-src 'self' https://p.trellocdn.com https://alcdn.msauth.net https://cdn.msftauth.net https://login.microsoftonline.com https://login.live.com https://*.trello.com https://*.asana.com https://appsforoffice.microsoft.com;

In my QA testing, everything seems to be humming along with my A+ except that I started noticing my add-in failing to load sometimes. Pop open the F12 developer tools and viola, a MicrosoftAjax.js error that is failed to load because of my CSP. So, I added it:

script-src 'self' https://p.trellocdn.com https://alcdn.msauth.net https://cdn.msftauth.net https://login.microsoftonline.com https://login.live.com https://*.trello.com https://*.asana.com https://appsforoffice.microsoft.com https://ajax.aspnetcdn.com;

That seemed to make it happy, and my QA succeed so I published. I had figured it must be something in my code, but I did not find Ajax in any of my dependencies or my code base, so I gathered it was from office-js (rightly so), but no big deal, right. I did an NPM UPDATE and grabbed another coffee.

But then users started to contact me that they were unable to use the add-in. Why? Well, turns out in certain conditions my code did something that would fail. And after a lot of troubleshooting, I start to see this error around areas where I am getting mailbox session data:

Cannot read properties of undefined (reading ‘cannotDeserializeInvalidJson’)
at Sys.Serialization.JavaScriptSerializer.deserialize

So, oh boy… 2015 wet sock moment… the Microsoft Office JS library apparently injects the MicrosoftAjax.js library right into your taskpane page and uses it for JSON.parse(). What?

Send to Planner (and my other add-ins) were all showing this. And I had NEVER seen this Ajax error before — so it was new. I scoured the web, asked my new buddy Chat GPT and… long story short, because this was something new… What did I do… Pen Testing… Yes, and what did I recently change… Oh, yeah, my CSP. Yes… more digging, trial and error:

script-src 'self' 'unsafe-eval' 'unsafe-inline' https://p.trellocdn.com https://alcdn.msauth.net https://cdn.msftauth.net https://login.microsoftonline.com https://login.live.com https://*.trello.com https://*.asana.com https://appsforoffice.microsoft.com https://ajax.aspnetcdn.com;

Well, now I only have an A on security headers, and I get a nice little blurb about:

This policy contains ‘unsafe-inline’ which is dangerous in the script-src directive. This policy contains ‘unsafe-eval’ which is dangerous in the script-src directive.

Inline is one thing and good use of input sanitization with DomPurify (thanks MichaelZ), corner cases that. But unsafe-eval? I confirmed – on/off/on/off – yep… it needs to be there.

Anyway, it was a long journey – many hours – and I am wiser for it. I know this is probably because OfficeJS still supports versions back to Office 2013 and Edge before it went the path of the Chromium, but I hope maybe it can move away from needing eval() code and the MicrosoftAjax.js library in the near future and I can add a (+) back to my security posture.

Hopefully, this post will help others from tripping up on this as they lock things down.

Solving Outlook JS Email Reply Parsing with ES6 Class | Example Included

In working with Send to Trello, Send to Planner and Send to Asana, I found one of the most complicated tasks in Outlook JS is trying to determine where an email reply ends, and the original message begins in order to get the latest response in a Message.Read scenario.

Seems simple enough that you look for the break between the messages, our eyes pick that up fairly easily. I have not tried AI yet, but that is a next step for sure.

However, wanted to share what I have found works in most cases. I created an ES6 class OutlookEmailBodyParser. And you use it like this:

const emailBody = new Promise((resolve, reject) => {
try {
Office.context.mailbox.item.body.getAsync(type, (result) => {
if (result.status === Office.AsyncResultStatus.Succeeded) {
resolve(result.value);
} else {
reject(result.error);
}
});
} catch {
reject("Unable to get email body text.");
}
});
const parser = new OutlookEmailBodyParser(emailBody);
return parser.getLatestResponse();

And here is the class that does all the work:

export default class OutlookEmailBodyParser {
/** @type {String} */
#body = null;
/**
* Creates an instance of the Outlook Email Body Parser
* Next you call:
* – getLatestResponse() to get the most recent message
* @param {String} body
*/
constructor(body) {
this.#body = body;
}
/**
* Returns the latest response
*/
getLatestResponse = () => {
const lines = this.#body.replace("/\r/g", "\n").split("\n");
// any line that starts with a word, a color and a space, like From: , to: , Cc:, Date:
const prologLine = /(^[A-Z]{2,8}:\s)/i;
// any line that ends with a colon
const lineEndsWithColon = /^.+(:)$/;
// covers general patterns of first.last@email.domain
const emailRegex = /[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z]{2,6}/;
// covers ——-, _______, —–original message—-, _______PREV______
const breakRegex = /^([-_]+(\w{0,15}(\s|\s{0})){0,3}[-_]+)$/;
// looks for a 4 digit number on the line, we grab it and see if it looks reasonable
// meaning in compare is the 4 digit number starting with 19 or 20.
const containsYear = /([/\s][0-9]{4})/;
// looks for a time in formats 4:44, 16:44, 4:44 AM, 4:44 PM
// we then look at capture groups to verify in range
const containsTime = /\s([0-9]{1,2}):([0-9]{2})(\w{2}|\s\w{2}|:[0-9]{2}|.{0})/;
// — START —
var breakOnLine = "";
var fFoundLineBreak = false;
var candidateLines = 0;
var prevLine = "";
for (const line of lines) {
var gmailFoundCount = 0;
var outlookFoundCount = 0;
if (breakRegex.test(line)) {
fFoundLineBreak = true;
candidateLines++;
prevLine = line;
continue;
}
if (emailRegex.test(line)) {
gmailFoundCount++;
outlookFoundCount++;
}
if (prologLine.test(line)) outlookFoundCount++;
if (lineEndsWithColon.test(line)) gmailFoundCount++;
if (containsYear.test(line)) {
const year = containsYear.exec(line);
if (year.length === 2) {
const num = Number.parseInt(year[0].trim());
if (!Number.isNaN(num) && num > 1900 && num < 2100) {
gmailFoundCount++;
outlookFoundCount++;);
}
}
}
if (containsTime.test(line)) {
const time = containsTime.exec(line);
if (time.length >= 3) {
const hour = Number.parseInt(time[1].trim());
const min = Number.parseInt(time[2].trim());
if (!Number.isNaN(hour) && !Number.isNaN(min) && hour >= 0 && hour <= 23 && min >= 0 && min <= 59) {
gmailFoundCount++;
outlookFoundCount++;
}
}
}
if (fFoundLineBreak) outlookFoundCount++;
////////////////////////////////////
// VALIDATE OUTLOOK
////////////////////////////////////
if (candidateLines >= 1 && outlookFoundCount > 2) {
breakOnLine = prevLine;
break;
}
////////////////////////////////////
// VALIDATE GMAIL
////////////////////////////////////
if (gmailFoundCount >= 4) {
breakOnLine = line;
break;
}
if (candidateLines === 1 && gmailFoundCount === 1) {
breakOnLine = prevLine;
break;
}
////////////////////////////////////
// reset
////////////////////////////////////
if (candidateLines === 3) candidateLines = 0;
if (outlookFoundCount >= 2) candidateLines++;
if (gmailFoundCount === 3) candidateLines++;
if (candidateLines === 1) prevLine = line;
fFoundLineBreak = false; // must set here
}
var latestResponse = this.#body;
if (breakOnLine) {
const pos = this.#body.indexOf(breakOnLine);
latestResponse = this.#body.substring(0, pos);
}
// return
return latestResponse;
};
}

Send to Planner v1.04 is Released

I have been absent from my blog for a while as I have been busy working on Kryl Solutions add-ins and Power-Ups. It has been an enjoyable experience to really delve into the world of JavaScript (ES6) and get creative building things.

One of my favorite projects has been Send to Planner. I just released version 1.04 and after 6 months of being in the marketplace, the reception and stats for this add-in are amazing. It has quickly become my fastest growing integration.

With v1.04, I have added checklists. Now, you can do nearly everything with task from Send to Planner: create new tasks in any plan and bucket, add to existing tasks as comments, add start and due dates, update priority, update selected categories, update the task progress, add/remove user assignments, and now, add, remove or update checklist items.

If you use Microsoft Planner for managing your projects, and you deal a lot with incoming email driving or updating your task workflow, you really should check Send to Planner out and let me know what you think.

Send to Planner Add-in Published

Right before the holidays I got my latest solution published to AppSource: “Send to Planner.”

This add-in is based on the “Send to Trello” Add-in and has a very similar look and feel. It was an unexpected side bar in my solutions development. A Send to Trello user contacted me because they also used Planner and were unable to find an effective solution that just did the basic “send an email to Planner” for free. While this has premium features to do much more, like keeping responses to the same email with the original task, the basic functionality will likely meet most casual use.

This was fun to create but also vexing at the same time. I am not sure where I got the idea, that there was an ability to get a front-end access token of the user running the Office add-in (getAccessToken). But turns out this is called an “on behalf of” flow that requires a complex manifest setup and you must send the customer email information to your backend web service to make the call “on behalf of” the user to Graph API. There are several options, but I had to go with the OAUTH flow using displayDialogAsync(). The AppSource (GDRP/Privacy) requirements for a backend data flow was more work and upkeep than I care for (cost and time wise). It is a headache I did not want.

So, I used the MSAL flow to pop an authentication dialog and then call the Graph API from the front-end to write to Planner. I already have users complaining that “it pops up the authentication dialog too much.” This is even though it does not require the entire authentication flow, it just pops up and then goes away.

I try the ssoSilent from the task-pane side and when/if that fails, I pop the dialog and do it there. The issue is because I do not own the frame of the Office task pane my origination domain is not correct. MSAL rejects the Silent SSO attempt. Ergo, it must pop open the dialog every time to get ssoSilent and refresh the token that way. A tad annoying.

I am not sure if I am missing something, but it would be nice to be able to request a front-end token with the proper scopes to do this, or a way to call ssoSilent from a task pane. But for now – this is what it is. Another annoying fact is that the token I get from MSAL, although it is refreshable (with ssoSilent), it lasts only 1 hour before it must be refreshed. So, 99% of the time a user clicks “Send to Planner” they see the dialog flash.

Either way, the add-in is out there and consumable. Please check it out!

Autolaunch and Outlook on Windows

I have been updating my 5entences add-in install for use in the AppSource/App Center for Office, plus adding an auto-summarization capability via OpenAI. 😉 COMING SOON!!!!

Originally, this add-in was using the Dialog API inside the “original” OnSend event. This was a bit nifty as it presented the user with a blocking popup that would allow them to manage everything in one place. It told them, they had more than 5 sentences, and would suggest they go back and fix it, or go ahead and send it. But that type of event is NOT supported in the App Store.

Enter Smart Events, and with it specifically the OnMessageSend event. The adventure began…

I have an Office 365 account and installed Office 365 from my portal.office.com page, made sure I was updated, and everything was looking good, except that:

  • When I have my personal Outlook.com email address attached to Outlook, I cannot debug add-ins in Outlook full client on Windows.
  • Even when I did remove my Outlook.com email address, my events were still not firing.
  • Everything worked great in Office on the Web.

So, I proceeded with updating the code using Office on the web to debug, giving up on Outlook full client in the interim. Once I got everything working well in Outlook on the Web, I went back to Outlook on Windows and began to lose my hair.

I quickly discovered that my ES6 code in the command.js, were not working. As you dig into the documentation you find that the WebViewURL and the override for JSRuntime, sharing the same file become an issue. It turns out that even with the WebView2 control installed on my box, and even though I have the latest version of Office 365 full client installed, my JSRuntime code reverts to Trident+ (IE11). I refactored my code to:

  • stop using const, instead var everything.
  • stop using => arrow operators, reverting to full function()
  • stop using async/await, and built pyramids of doom
  • stopped using Promises() even

The reason I reverted, is because I pulled out all transpiling and polyfills because they SLOW down my add-in code, make it too large and it impacts my already overwhelmed server. I also like to remain as pure JavaScript ES6 as I can. I am a bit puritanical, I guess. 😆

But even with all that it did not work. So, line by line I went and found the first problem:

/**
* Ensures the Office.js library is loaded.
*/
Office.onReady((info) => {
/**
* Maps the event handler name specified in the manifest's LaunchEvent element to its JavaScript counterpart.
* This ensures support in Outlook on Windows.
*/
if (Office.context.platform === Office.PlatformType.PC || Office.context.platform == null) {
Office.actions.associate("onMessageSendHandler", onMessageSendHandler);
}
});
view raw onready.js hosted with ❤ by GitHub

That code seemed to work, but the add-in would just hang telling me “…it is taking too long… Try Again.” I resolved it by doing this:

/**
* Checks to see if we are running in Windows Outlook
* @returns {Boolean}
*/
function isPC() {
try {
if (Office.context.platform === Office.PlatformType.PC || Office.context.platform === null) {
return true;
} else {
return false;
}
} catch {
return false;
}
}
if (isPC() === true) {
Office.actions.associate("onMessageSendHandler", onMessageSendHandler);
} else {
Office.onReady(function () {});
// Everything below is for OTHER (non-PC) clients per older constructs. Not certain
// if any of this is needed except for COMMANDS (rather than EVENTS), so eventually
// if commands are added, we have this in place…
var g = getGlobal();
// The add-in command functions need to be available in global scope
g.onMessageSendHandler = onMessageSendHandler; // on send event
}
/**
* OnSend event triggered
* @param {Office.AddinCommands.Event} event
*/
function onMessageSendHandler(event) {
Office.onReady(function () {});
Office.context.mailbox.item.body.getAsync(Office.CoercionType.Text, { asyncContext: event }, function (asyncResult) {
var body = asyncResult.value;
var event = asyncResult.asyncContext;
// … more code here …
});
}
view raw commands.js hosted with ❤ by GitHub

Essentially, I had to put the associate at the root of the file. Without the PC check, this would bomb on Office online and the Mac, so I gated that with the function you see: IsPC(). And Office online needs the Office.onReady() in the root to work effectively, so you see that there. But putting Office.ready() in the root broken Outlook on Windows, but also ignoring it/not using it, gave me the same problem. I discovered that if I put it in the event activation itself, as you see, I was finally able to get into my event handler and execute and Office.context (line of code). However, deeper in my code, it was STILL failing.

Debugging my code further, I had a LOT of Regex to determine what was going on in the body of the email. Introduce Trident+ and IE11 (es5), and you realize that “look heads” and a lot of really cool stuff I have grown accustomed to do not work. So, I struggled and struggled, until I just sent to my friend ChatGPT and asked it to produce me IE11 compatible Regex for each of my Regex statements. And then viola, my add-in was fully functional on Windows and Office online.

I am still a hacker by nature – what works, works. And I have converted from Office Add-ins written in C# with Visual Studio Tools to Office to this OfficeJS paradigm. I spend a lot of time reading the documentation and I SWEAR it tells me that with my version of Office 365 and having the WebView2 control installed, I should not be reverting to IE11 (Trident+) for Smart Events:

Microsoft® Outlook® for Microsoft 365 MSO (Version 2308 Build 16.0.16731.20052) 64-bit

But maybe it is buried in there somewhere that on Windows/PC, it always uses IE11 for Smart Events. Either way, to make sure you support 99% of the market out there, I guess you need to write you code like this or use polyfills and transpile. Bottom line is I got it to work. If anyone else is having similar issues, hopefully this helps. If anyone has an alternative or can point to something I am doing wrong (other than using polyfills and transpile my code), I am open to suggestions.

Outlook Signature Add-in

I recently got a question about this add-in created as a sample by the Microsoft Office Developer Team. It is provided as a sample and is a challenging bit of code to follow. It all started because I was trying to provide some advice to someone who is new to the OfficeJS world (but not Office development in general). They wanted to build a cross-platform add-in for a cause. After tinkering with it for a few hours, I managed to get it to work. But then I looked it over and it was quite a bit of tinkering on my part.

In most cases I create Add-ins based on React, but because I have done a lot of Trello development of late, I have gotten into more of a pure ES6 vibe. The code provided in the add-in as I stated was hard to follow because I think I am losing my jQuery and ES5 JavaScript skills.

Anyway, as I said, I spent a few hours today and worked on getting it into ES6 format by moving most of the code into classes, removing redundant code, removing redundant HTML pages, consolidating CSS and adding a lot of additional JSDoc comments throughout the code.

Hopefully, this version is a bit easier to follow for those that develop in a more modern ES6 style.

NOTE: This looks and behaves exactly the same, but I have not thoroughly tested it. So, it might be a bit rough here and there. If you encounter issues please let me know. 😁

Outlook Calendar for Trello is Released

I have really enjoyed writing this bit of code because it stretched from Trello API to Office 365 API, two of my favorite programming interfaces. This Power-Up is similar to the default Trello Calendar Power-up, the key difference being is that it connects to your Outlook Calendar. So, you can see all your Trello Tasks and your Outlook appointments/meetings, side by side in one place, you can link your appointments to Trello cards and vice-versa. With a month view and a weekly view, you can manage your calendar easily by dragging and dropping your Trello Cards on the calendar to create linked appointments for specific tasks all in one place.

Check it out here:

https://trello.com/power-ups/637307154b117e05a423c8a1

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.