Send Multiple Tasks to OmniFocus at Once with Drafts and Pythonista

Tags: , , , , , ,

Bottom Line: I often come up with several tasks I need to jot down at once, and this script helps me get them all into OmniFocus in one shot.

Updated Jan 14, 2014: MultiLineOmniFocus V2 Available here. Still recommended to read this post for background.

NB: The script in this post is set up to use Drafts, Pythonista, OmniFocus, access to the OmniGroup’s Mail Drop Beta, and a Gmail email address. It may be possible to use the basic principles with a different setup (esp. re: Gmail, shouldn’t be hard to configure a different SMTP server), but you may need to get your hands dirty.

I do my best to keep the load of tasks “on my mind” to a minimum by getting them into OmniFocus on the fly. However, sometimes my thoughts race a bit, and I realize I’m juggling maybe 4 or 5 ideas that I really ought to get filed away before I forget them. On my Mac, it’s a simple matter to invoke the OmniFocus Quick Entry box, type a task, and hold Shift + Enter to go directly to a second task, making it seamless to input as many as I need at once. Protip: If you have your Quick Entry box set up to allow you to set Projects and Contexts, you can use ⌘ + d to duplicate a task, including title and context.

However, as the general rule goes, things on iOS are not quite this smooth. While OmniFocus does provide an in-app quick entry button, for entering a handful of tasks, the process is something like:

  1. Launch OmniFocus.
  2. Wait for for the sync to finish (usually pretty quick).
  3. Click the quick task button.
  4. Type task.
  5. Click save.
  6. Repeat 3-5 for each task.

Now this really isn’t that bad — OmniGroup has done a great job making this process pretty darn low-friction. However, I have only recently started playing around with Drafts, and I really like how quick and responsive it is. It includes a built-in action to send a task to OmniFocus, which works great. Others have recommended using the OmniFocus Mail Drop Beta, an email-to-task feature the OmniGroup has been working on, as one of Drafts’ “email actions,” for an even smoother workflow, since the email is sent in the background without any app switching. This works great as well.

I’ve also recently started playing with Pythonista, and I came across a Python script written by the dev himself that creates a little SMTP server and sends email directly from Pythonista. Between the two, I found it pretty easy — even for a beginner like me — to put together a combined Drafts / Pythonista workflow that makes for a superior way to import a bunch of tasks to OmniFocus at once (aka “brain dump”).

They way it works

  • Open a new draft in Drafts.
  • Type in your tasks, one task per line, as fast as your thumbs can peck.
  • Hit the MultiLineOmniFocus action.
  • Pythonista will launch, you’ll see some info about the SMTP server starting and each task getting sent.
  • It will return to Drafts when it’s done.

Here’s a quick video example of how it works. Apologies for the shoddy editing.

Setup

  1. If you haven’t already, get set up with the OmniFocus Mail Drop Beta, which provides an email address that will turn subject lines into tasks. Request access in your OmniSync management page.
  2. Install the URL action into Drafts.

    pythonista://MultiLineOmniFocus?action=run&argv=[[draft]]

  3. Import the script below into Pythonista (here are a few ways to import scripts).
  4. Input your information in the ### CHANGE THESE VALUES: section.

I’m also trying to figure out what in the world GitHub is all about, so I put this (and a bunch of my other scripts) into a repo. Here is the link for this one: https://github.com/n8henrie/fromPastebin/blob/master/MultiLineOmniFocus.py. Maybe you can branch it and tweak it or whatever people do with GitHub stuff.

I’m not convinced that this method actually saves time compared to just inputting the actions directly into OmniFocus. Even if it did, the time saved would be minimal, because there are already fairly quick methods for doing this. For me, the benefit is that it minimizes the disruption between dumping tasks — that I can put down everything in one go without having to pause in between each task to hit “save” and “new task.” If you’re trying to get 5 ideas out of your head and into OmniFocus, saving 10 clicks is saving 10 clicks. Especially if those clicks are before you’ve gotten the ideas written down.

Pending issues

Currently, I have Drafts set up to delete the contents of the draft when the action is called so I don’t have to do it manually later. However, this could present a problem if, for example, I didn’t have internet access at the time. In this case, I’m guessing Drafts would delete all the tasks I’d just typed out, and the Pythonista script would fail, and I’d have to start over. One idea that I haven’t yet tried but would probably take minimal effort would be to have Drafts not delete the contents at the time the action is called, but to change the final Pythonista webbrowser.open(‘drafts://’) to call the Drafts “delete” action. That way, hopefully the contents would only be deleted if the action succeeded. If Pythonista eventually implements x-callback-url, this might be even easier (just have an x-success argument call the delete action).

I’d love to hear your feedback or suggestions for improvement in the comments section. I’ve only discovered Python in the last couple of weeks, so I’m definitely going for “functional” and not necessarily “elegant” here, but I’d love to hear how it could be done better.

Update Apr 11, 2013: A reader and fellow Pythonista in training, Jon Kameya, sent in this modification that uses | to separate email subject and body, which translates into task title and note in OmniFocus, as well as a check for blank lines. Thanks!

  • Toni

    Hello Nathan! This is awesome, but I was copying the code into pythonista and at the line ‘tasks = sys.argv[1].splitlines()’ I got the message ‘Expected an indented block’. Since I don’t want to fool around int he code, do you probably have an idea what I do wrong? I am maybe very stupid :). Cheers!

    • http://www.n8henrie.com/ Nathan Henrie

      Hi Toni, thanks for the comment. I have had mixed luck with copying and pasting Python scripts, mostly because the indentation level is so important. I recommend you check out my post here for a few other ways to import the scripts: http://n8henrie.com/2013/02/quickly-import-pythonista-scripts-via-textexpander-or-bookmarklet/

      Based on that error, it sounds like copying and pasting may have lost some of the (~8?) spaces in front of that line — compare with the code I have above in the Pastebin iframe. One other thing you might try is the “Download Raw” link at the top of the code, provided by Pastebin, which should offer a plaintext version of the code that might be better preserved with copying and pasting. Alternatively, the GitHub “Raw” view (from https://github.com/n8henrie/fromPastebin/blob/master/MultiLineOmniFocus.py) should give you the same plaintext formatting, although I seem to remember having similar issues with this previously, which is why I wrote the import scripts in the post I’ve linked to at the top of this comment.

      Let me know if you get it working! Also, don’t be afraid to get your hands dirty and tweak the code a bit. I knew nothing about Python 2 weeks ago, but it’s actually pretty friendly for beginners. Worst case scenario, you can always come back to this post / Pastebin / GitHub and re-copy the original :)

      • Toni

        It worked!! Awesome! Thanks for the light speed answer and very clear answer. I’ll take a look at some other stuff you did :). Thank man!

        • http://www.n8henrie.com/ Nathan Henrie

          Glad to have helped.

  • http://twitter.com/Samwich007 Sam Matthews

    This code absolutely works a treat. I can now go into a meeting, make tasks for myself, via drafts and send them to omnifocus via pythonista.

    The code works really well. The only trouble I had was the editor within Pythonista didn’t seem to work very well for me. Deleting characters for my email address etc, I found the entire line deleted and I had indentation errors.

    To resolve this I pasted the code into drafts, made the changes, then directly pasted into pythonista. No changes required.

    This is a nice addition to my omnifocus productivity workflow on iOS.

    Thanks Nate.

    • http://www.n8henrie.com/ Nathan Henrie

      Thanks a ton for the detailed comments, Sam. Glad this ended up working for you!

  • Pingback: More Ways to Send Tasks to OmniFocus with Launch Center Pro and Drafts

  • Pingback: Using Drafts Line Tags with URL Schemes and Actions | IOS Workflow Automation

  • James

    What is the benefit of this approach over using the send list to reminders action in Drafts and having Omnifocus pull the reminders list into its inbox, this will also work in event of not having an internet connection. Or am I missing something?

    • http://n8henrie.com/ Nathan Henrie

      Good point. The only thing you’re missing is the date the post was published (2013-03-10) as compared to the date Agile Tortoise incorporated Reminders integration (with multiline support) in Drafts 3.0, announced 2013-04-24, here.

  • Des Dougan

    Nate,

    Many thanks for the script. I’ve installed and tested and it works almost exactly as I’d like. You mentioned in the posting that Drafts doesn’t delete the text after it’s been sent, and that it might be possible to add that feature. Have you been able to do that?

    • http://n8henrie.com Nathan Henrie

      Hi Des,

      I think you may have misunderstood. I wrote above that Drafts does delete the text, which may be a problem (e.g. if there was an error in the Pythonista part, that text would have already been deleted). As a solution to this, in recent versions of Drafts, I have it set to “archive” instead of delete. Settings -> Manage Actions -> MultiLineOmniFocus -> After Sucess -> Archive

      • Des Dougan

        Duh! I never thought of checking the Drafts options.

        That’s perfect – many thanks!

        Des

        • http://n8henrie.com Nathan Henrie

          Happy to help!