Links to Outlook e-mails: how I integrate Todoist and Outlook

Todoist is a great multi-platform task manager, and it provides facilities to integrate with many other tools including e-mail apps. Email integration is typically via forwarding your e-email to a todoist inbox email. This, however, sends the actual content of the email to Todoist, which might not be desirable all the time. In this post, we integrate Outlook with Todoist (or any other tool, actually) by creating links back to Outlook e-mails.

I use Outlook for my work email, and Todoist for managing my tasks. However, every time an email results in creating a task in Todoist, I struggle finding a way to refer back to the original email. I want to do this for many reasons. Sometimes the details of the task is defined in the email, sometimes I have reference documents attached to the email, or I just need to reply back to the email when I am done with the task. Sending emails directly to Todoist is not an option for me, as my workplace policies doesn’t allow that. So, what do I do now?

After some googling around, I noticed that it is possible to interact with Outlook using Mac Automation Scripting. What I want to have is some capability to copy link to an outlook message and use it in Todoist. So, I decided to give it a go…

Before we dive into the scripting details, let’s clarify what I am trying to achieve here. I would like to be able to copy links to selected Outlook emails to clipboard, and then paste them to Todoist or any other app. The links will be something in the form of outlook://<message id>. And I want to be able to click on the links and jump back to the Outlook message.

Let’s move to the scripting details…

Mac Automation Scripting

First, we need to gather some basic understanding of how this scripting mechanism works. Mac Automation Scripting allows interacting with applications to automate tasks. AppleScript is the language that Apple provides for this purpose, but it is also possible to use JavaScript for automation as well. The built-in Script Editor application provides a very basic IDE for editing scripts. There is built-in documentation on the available libraries via File > Open Dictionay... menu on Script Editor application.

First script: Getting selected Outlook messages

Now that we have some understanding of how Automation scripting works, it is time to get our hands dirty. Let’s first try to get some information on a selected message in Outlook.

tell application "Microsoft Outlook"
	set selectedMessages to selected objects
	set messageSubject to subject of item 1 of selectedMessages
	display notification messageSubject
end tell

The above script shows the subject of the selected message as a notification. You can copy and try this script in Script Editor. You can also try this with ob-applescript.el if you live in Org Mode.

As I said before, you can actually use JavaScript instead of AppleScript if you don’t feel like learning the quite uncommon syntax of AppleScript. So, here is the same functionality as above in JavaScript for comparison.

var outlook = Application("Microsoft Outlook");

var selectedMessageSubject = outlook.selectedObjects()[0].subject();


var app = Application.currentApplication();
app.includeStandardAdditions = true;

app.displayNotification(selectedMessageSubject);

JavaScript version is more verbose, especially because it needs two additional lines to access the Standard Additions library, which provides various functions including one for displaying a notification. I would probably still use JavaScript instead of AppleScript for anything somewhat complicated, since I feel better with the more familiar syntax.

Now that we know how to get selected messages, we need to create a link to that message.


tell application "Microsoft Outlook"
	set selectedMessages to selected objects
  if selectedMessages is {} then
    display notification "Please select a message in Outlook before running the script!"
  else
  	set messageId to id of item 1 of selectedMessages
	  set uri to "outlook://" & messageId
  	set the clipboard to uri
  	display notification "URI " & uri & " copied to clipboard"
  end if
end tell

As you can see above, in addition to just creating a URI for the selected message, we now have some error handling and user interaction built into the script to make it more user-friendly.

To try the script, just run in it Script Editor as usual. When you select a message in Outlook and then run the script, it will copy the URI to the system clipboard ready to paste into Todoist (or wherever else you might want to).

Now that we are able to copy links to outlook messages, we need a way to handle those links to go back to the Outlook message. The way to do this, is to develop a custom protocol handler. This way our newly introduced outlook://<message id> urls will be recognized by macOS.

In order to implement a custom protocol handler with AppleScript, we simply implement an open location handler as follows.

on open location this_URL
	set the messageId to text 11 thru -1 of this_URL
	tell application "Microsoft Outlook"
		activate
		open message id messageId
	end tell
end open location

Then we need to turn this into an app package and edit its Info.plist to define our new URL scheme. Basically we need to go through the following steps:

  1. Save the script as an app package in Script Editor. (Save... > Format: Application)

  2. Open Finder and locate the saved file. Right click and select Show Package Contents.

  3. Under the Contents folder, open Info.plist with your favorite text editor, and add the following content before the last two lines.

          <key>CFBundleIdentifier</key>
          <string>org.personal.outlook</string>
          <key>CFBundleURLTypes</key>
          <array>
              <dict>
                  <key>CFBundleURLName</key>
                  <string>Pass To OutlookUriHandler</string>
                  <key>CFBundleURLSchemes</key>
                  <array>
                      <string>outlook</string>
                  </array>
              </dict>
          </array>
    
  4. Save the file. Go back to your app and double click to execute it.

Now we are basically done. If you want to see it working, copy an Outlook message link and paste it to Todoist. Then, you should be able to just click on the link and get back to your e-mail in Outlook. You can use this link in many other places, including the command line (just run open <your outlook link>).

Putting it all together

At this point, we have script that can copy links to Outlook to clipboard, so that we can paste the link to another application. And we can also click on that link (in most apps, including Todoist) to get back to Outlook. We are almost done, but not quite yet. Copying the links is very tedious…

We need to go to Outlook to select a message, and then open our script in Script Editor and run it to copy links to clipboard. This process is not efficient at all. Let’s see what we can do to make this more streamlined.

We have a few options here. One option is to use Automator app to define a service with our script, and then add a keyboard shortcut to our new service. For me this didn’t work reliably unfortunately.

Another option is enabling system-wide script menu. Just go to Script Editor app, and select Script Editor > Preferences menu, and enable Show Script menu in menu bar. This gives you a way to run your scripts by just clicking on the menubar icon for scripts and select your script. In order to make this work, though, we need to save our script to \~/Library/Script folder. After doing this, you can see your script in the menu.

If you are like me, and still think that a keyboard shortcut would do better. You can use a more powerful script launcher like Fast Scripts.

Now we have a neat and basic way to integrate Outlook with Todoist, or actually we have a way to link to Outlook messages, and this can be used to integrate Outlook with other applications.

I uploaded the script and ready to use macOS application to github. If you don’t want to replicate the process you can get the app and script from this link.