I use OmniFocus for personal task-tracking and Zapier to automate work when possible. I also coordinate open source work on GitHub. Recently I was wondering if there was a way to make OmniFocus automatically import any GitHub issue assigned to me. It turns out there is!
What you need:
- Zapier account
- OmniFocus Pro (desktop)
- OmniSync with Mail Drop configured
- GitHub account
- ParseInbox applescript (mine, original)
Optional tools include Hazel or Lingon to automate the running of the ParseInbox applescript.
Before I continue, thank you to Joe Buhling for sharing his collection of OmniFocus scripts!
Part One: Create zap on Zapier
If you haven’t already, enable OmniSync and create a Mail Drop email address. You’ll also need a GitHub account and there should be a newly created issue assigned to you.
To get started, while logged into Zapier, click MAKE A ZAP! button.
Step 1: GitHub app, new issue trigger
Select GitHub as the trigger app:
Next, select New Issue as the GitHub trigger:
Next, set up the GitHub new issue trigger according to your preferences:
In my Zap, I’ve selected Only issues assigned to you and for the time being, I’ve limited it to a single GitHub organization. What you select is up to you.
Next, test this step to ensure it is retrieving the data from GitHub that you expect it to. Before you run the test, Zapier will remind you to have a recently created issue that matches your trigger options:
Once everything looks good, save the step.
Next, you’ll create a formatter step to format any dates attached to GitHub issues via their assigned milestones.
Step 2: Formatter app, date/time action
The app you’ll select for this 2nd step is Formatter by Zapier:
The action you’ll use for Formatter is Date / Time:
Next, set up the Date / Time action. You’ll want to set the following fields accordingly:
- Transform: Format
- Input: Step 1 Milestone Due On
- To Format: MM/DD/YY
Now test the action to ensure the result is as you expect. You’ll see something like:
Once everything looks good, save the step.
Step 3: Code by Zapier app, run Python action
In this step, I’m using Python code to map GitHub repository names to OmniFocus folders and GitHub milestones to OmniFocus projects within those folders. If you have a different organizational scheme, you’ll want to modify the code in this step accordingly.
First, select the Code by Zapier app:
Next, select Run Python as the Code by Zapier action:
(You could also select Run Javascript and re-write the Python code below in Javascript.)
Next, configure the Input Data for use with our custom python code. You’ll want to set the following:
- repo: Step 1: Repository Name
- milestone: Step 1: Milestone Title
The names of the fields on the left doesn’t really matter, but it must match the key names we’ll use in our Python code.
Next, you’ll enter the following Python code into the Code field:
# want to set the project as # repo milestone # or just repo if no milestone output = {'project' : input_data.get('repo').replace("-", " ")} if input_data.get('milestone'): repo = input_data.get('repo') milestone = input_data.get('milestone') project = repo.replace("-", " ") + ' ' + milestone.replace("-", " ") output = {'project' : project}
If the issue being processed by Zapier has a milestone, this code sets project to Repository name milestone name
, replacing any hyphens with spaces. Otherwise, it sets project to simply Repository name
, also replacing any hyphens with spaces.
This works for me because I organize NumFOCUS projects in GitHub like this:
- [repository] my-project
- [milestone] milestone 1
- [milestone] milestone 2
And in OmniFocus, I organize projects like this:
- [folder] My Project
- [project] Milestone 1
- [project] Milestone 2
If you structure your projects differently, you’ll need to update the Python code above accordingly.
When you’re ready, test the Python code and check to see that it creates the expected output:
When everything looks good, save this step and continue on to creating the 4th and final step.
Step 4: OmniFocus app, create task action
In this last step you’ll configure the OmniFocus app to create an OmniFocus task with information from the retrieved GitHub issue.
First, select the OmniFocus app:
Now select the Create Task action for the OmniFocus app:
Next you’ll need to connect your OmniFocus account if you haven’t already and select which connection you’d like to use.
Next, set up the create task action. You’ll configure only the Title field as such:
--Step 1 Title @GitHub ::Step 3 Project #Step 2 Output //Step 1 Html Url
Let’s break this down:
- The
--
sets the name of the task. - The
@
sets the context. - The
::
sets the the name of the project. - The
#
sets the due date. - The
//
sets the text of the note.
Two notes:
- The name of the project is fuzzy matched against flatted name of folders and projects, so you don’t need to use a colon between folder and project name.
- With the applescript I’m using to parse OmniFocus’ Inbox, I had trouble with dates including time, so this is why I simplify the due date format in Step 2 of the Zap.
- If you wanted to dynamically set the name of the context based on some attribute of the GitHub issue (e.g. label), you could do that by modifying the Run Python action in Step 3.
For details on the syntax used for parsing the inbox, see this post.
Here’s what the the task looks like in Zapier:
As always, test the action before proceeding to make sure everything looks right:
If this looks good, click Create & Continue to create the task. Once you do this, flip over to OmniFocus and wait for the task to appear in your Inbox. It’ll look something like this:
Now you’re ready to setup the script to parse that monster-looking task out of your OmniFocus Inbox and into the right spot!
Part 2: Parsing tasks in OmniFocus’ Inbox
Step 1: Manually run the ParseInbox script
For this part, if you haven’t already, you’ll want to grab a copy of the AutoParser scripts from either the original author or myself.
The repositories linked to above contain a collection of applescripts for use with OmniFocus. (Thank you Joe Buhling for putting these together!)
There are two main options for running the script manually.
Option 1: You can run any of the scripts from the command line with the osascript
command:
/usr/bin/osascript "/Users/christie/Bin/OFScripts/Auto-Parser/ParseInbox.applescript"
Option 2: If you don’t want to use the command line to run scripts, you can copy the ParseInbox.applescript into OmniFocus’ scripts folder. To find out where this is, go to Help > Open Scripts Folder in OmniFocus and it will open a new finder window at that location. Once you do this, you’ll see Script: ParseInbox as an option in the View > Customize Toolbar… window. Drag this icon to your toolbar for ease of use.
When you run the ParseInbox script, it will transform the Inbox task Zapier created that looks like this:
--install certbot @GitHub ::sustainbility index project kick off #06/08/17 //https://github.com/numfocus/collab-infrastructure/issues/30
Into the task install certbot, belonging to the project Project Kick Off in the folder Sustainability Index. The task will now have a due date of 6/8/2017, and note text that includes a link back to the original GitHub issue:
If at this point you realize that your Zap isn’t quite configured correctly or exactly how you want it, you can go back and adjust it. And, if you get tired of waiting for OmniFocus to sync with the server to retrieve the new task, just remember you can copy and paste the test output from Step 4 of your Zap.
Step 2 (optional): Automatically running ParseInbox
This step is totally optional and you can skip it if you’re happy manually running the script when you want to parse Inbox items.
However, if you don’t want to have to remember to do this, or if you want OmniFocus to be able to process Inbox items while you’re out and about, then you’ll want to automate it.
There are a few options for doing this. They all require your computer be on, but OmniFocus doesn’t have to be open (the script will open it if closed).
Option 1 is to use Hazel to run the script when your OmniFocus has been updated. Joe explains how to configure this option on his blog here. I had mixed results with this method. The script seemed to run sometime and not others. YMMV.
Option 2 is to schedule the script using launchd (macOS’s version of cron). This involves editing plist files, which I hate doing, so I bought Lingon X to make this easy.
Here’s what my settings for Lingon look like:
And the plist generated by Lingon looks like this:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>EnvironmentVariables</key> <dict> <key>PATH</key> <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/MacGPG2/bin:/usr/local/sbin</string> </dict> <key>Label</key> <string>of.autoparser</string> <key>ProgramArguments</key> <array> <string>/usr/bin/osascript</string> <string>/Users/christie/Bin/OFScripts/Auto-Parser/ParseInbox.applescript</string> </array> <key>StartInterval</key> <integer>300</integer> </dict> </plist>