JACOB SILVER

web developer | musician | venue booker

Creating a Daily Project Template in Omnifocus 3 with Varying Tasks Depending on the Day of the Week

As an avid user of Omnifocus for both Mac and iOS, I was super excited when the OmniGroup released version 3 of Omnifocus last week. Though it has many awesome changes and new features, all that release really did for me was re-inspire my automation brain, now equipped with more coding skills and experience than ever before. I decided to set out to create a script which I would run every morning that would create a new project for the day with all the tasks I planned on accomplishing that day.
The complicated part was that there is never one day where every task is the same. Let me explain…as a booker for two music venues in New York City, I have tons of emails to write and bands to book. But there’s more than that. I need to send out confirmation emails (I have a detailed confirmation email system involving sending emails out 3 weeks before show date, 2 weeks before show date, and 1 week before show date), do reporting for the night before, setup Evernote notes for the evening’s events for the staff to do reporting on, and much more. Some days I don’t need to send out confirmation emails. This is because at both venues, there is no music booked on certain nights, meaning I don’t need to send out confirmation emails on those dates.
So I set out to make the ultimate script which was able to make a new project every day with day-specific tasks. Here we go:

Set Date Variables

First of all, we’ll need to create the date variable for the title. It will need to be a string, not a date object.

set theDate to date string of (current date)

Next we’ll need to get the day of today (you know - Monday, Tuesday, etc…)

set theDay to weekday of (current date)

And lastly, we’ll need to get today’s date as a date object, and then change the time to 11pm, which will be the time all these tasks will be due.

set dueDate to (current date)
tell dueDate
    set {its hours, its minutes, its seconds} to {23, 0, 0}
end tell

This is some oddball syntax if you ask me. I guess “its” is something akin to Javascript’s “this” keyword, but I dunno, maybe not?

Create Task Variables

I’m sure there’s a cleaner way to do this, likely involving Applescript’s odd way of using subroutines (functions), but this works, and the nice thing about this is that if I need to change anything, I know exactly where to look. Though if this were a javascript app, I’d probably spread most of this code over the span of at least a few files and do imports/exports, React.js style. Anyways, I’m making 14 different arrays. Two arrays per day. Two music venues, so separate arrays per venue. Like this: set petesSun to {"Clear Inbox", "Send 2 week confirmation email", "Send 3 week media request email", "Send 1 week promo email", "Log last night's evernote notebook to BusyCal", "Enter last night's show data to the BusyCal Events", "Make daily Evernote Entry", "Email bands who did well last night"} set pineboxSun to {"Clear Inbox", "Send 2 week confirmation email", "Enter last night's show data to the BusyCal Events", "Make sure every band has submitted show info for tonight's show and email the bands who haven't"}

set petesMon to {"Clear Inbox", "Send 2 week confirmation email", "Send 3 week media request email", "Send 1 week promo email", "Log last night's evernote notebook to BusyCal", "Enter last night's show data to the BusyCal Events", "Make daily Evernote Entry", "Email bands who did well last night"}
set pineboxMon to {"Clear Inbox", "Send 2 week confirmation email", "Enter last night's show data to the BusyCal Events", "Make sure every band has submitted show info for tonight's show and email the bands who haven't"}

set petesTues to {"Clear Inbox", "Send 2 week confirmation email", "Send 3 week media request email", "Send 1 week promo email", "Log last night's evernote notebook to BusyCal", "Enter last night's show data to the BusyCal Events", "Make daily Evernote Entry", "Email bands who did well last night"}
set pineboxTues to {"Clear Inbox", "Enter last night's show data to the BusyCal Events"}

set petesWed to {"Clear Inbox", "Log last night's evernote notebook to BusyCal", "Enter last night's show data to the BusyCal Events", "Make daily Evernote Entry", "Email bands who did well last night"}
set pineboxWed to {"Clear Inbox", "Make Evernote tables for next Thursday-Monday", "Send an email to all bands who have not submitted tech info"}

set petesThurs to {"Clear Inbox", "Send 2 week confirmation email", "Send 3 week media request email", "Send 1 week promo email", "Log last night's evernote notebook to BusyCal", "Make daily Evernote Entry"}
set pineboxThurs to {"Clear Inbox", "Send 2 week confirmation email", "Make sure every band has submitted show info for tonight's show and email the bands who haven't"}

set petesFri to {"Clear Inbox", "Send 2 week confirmation email", "Send 3 week media request email", "Send 1 week promo email", "Log last night's evernote notebook to BusyCal", "Enter last night's show data to the BusyCal Events", "Make daily Evernote Entry", "Email bands who did well last night"}
set pineboxFri to {"Clear Inbox", "Send 2 week confirmation email", "Enter last night's show data to the BusyCal Events", "Make sure every band has submitted show info for tonight's show and email the bands who haven't"}

set petesSat to {"Clear Inbox", "Send 2 week confirmation email", "Send 3 week media request email", "Send 1 week promo email", "Log last night's evernote notebook to BusyCal", "Enter last night's show data to the BusyCal Events", "Make daily Evernote Entry", "Email bands who did well last night"}
set pineboxSat to {"Clear Inbox", "Send 2 week confirmation email", "Enter last night's show data to the BusyCal Events", "Make sure every band has submitted show info for tonight's show and email the bands who haven't"}

What’s also confusing is that the syntax uses curly braces for arrays. Very un-JS!

I’ll also make three more task arrays, one for coding, one for exercise, and one for music. Most of the time I won’t know exactly what I’ll be doing for those until the week-of, or even the day-of, so I’m content to get more specific with the tasks after the project is generated. set codingTasks to {"Work On Coding Project"} set exerciseTasks to {"Exercise at least 45 minutes"} set musicTasks to {"Practice at least 30 minutes"}

Create the New Project and Make Some Tags

Now we can finally do something with Omnifocus. Here we’ll create the new project, and also assign some tags (new with OF3) to some variables to set to the new tasks a little later in the script.
Keep in mind the tags must exist first in Omnifocus, or else AppleScript will throw an error saying it can’t find these tags!

tell application "OmniFocus"
    activate
    tell default document
        -- Set Tag Variables
        set petesTag to first flattened tag where its name is "Pete's Candy Store"
        set pineBoxTag to first flattened tag where its name is "Pine Box Rock Shop"
        set codingTag to first flattened tag where its name is "Coding"
        set musicTag to first flattened tag where its name is "Music"
        set exerciseTag to first flattened tag where its name is "Exercise"


        -- Make a new Omnifocus Document
        set theProject to make new project with properties {name:theDate, due date:dueDate}

Great! Now we have a new project whose name is the current date, and is due at 11pm today.

Make Parent Tasks

I like to have “parent” tasks. Meaning, for Pete’s Candy Store (one of the venues I book), there will be a task called “Pete’s Candy Store”, and beneath it will be all the tasks for Pete’s Candy Store. Same with the other venue, Pine Box Rock Shop, as well as Coding, Music and Exercise.

tell theProject

            -- Make Parent Tasks
            set petesParentTask to make new task with properties {name:"Pete's Candy Store", primary tag:petesTag}
            set pineboxParentTask to make new task with properties {name:"Pine Box Rock Shop", primary tag:pineBoxTag}
            set codingParentTask to make new task with properties {name:"Coding", primary tag:codingTag}
            set musicParentTask to make new task with properties {name:"Music", primary tag:musicTag}
            set exerciseParentTask to make new task with properties {name:"Exercise", primary tag:exerciseTag}

So now in our project we have 5 tasks, all with 11pm due dates and tagged accordingly. Nice!

Create Child Tasks

Now for all the fun stuff. This will create new tasks from the items in the arrays defined above, and will designate them as “children” to whatever parent task we set it to. Like so: -- Make Tasks Depending On Day Of Week if weekday of (current date) is Sunday then repeat with theItem in petesSun set petesTask to make new task with properties {name:theItem, primary tag:petesTag} move petesTask to end of tasks of petesParentTask end repeat repeat with theItem in pineboxSun set pineboxTask to make new task with properties {name:theItem, primary tag:pineBoxTag} move pineboxTask to end of tasks of pineboxParentTask end repeat

else if weekday of (current date) is Monday then
                repeat with theItem in petesMon
                    set petesTask to make new task with properties {name:theItem, primary tag:petesTag}
                    move petesTask to end of tasks of petesParentTask
                end repeat
                repeat with theItem in pineboxMon
                    set pineboxTask to make new task with properties {name:theItem, primary tag:pineBoxTag}
                    move pineboxTask to end of tasks of pineboxParentTask
                end repeat


            else if weekday of (current date) is Tuesday then
                repeat with theItem in petesTues
                    set petesTask to make new task with properties {name:theItem, primary tag:petesTag}
                    move petesTask to end of tasks of petesParentTask
                end repeat
                repeat with theItem in pineboxTues
                    set pineboxTask to make new task with properties {name:theItem, primary tag:pineBoxTag}
                    move pineboxTask to end of tasks of pineboxParentTask
                end repeat


            else if weekday of (current date) is Wednesday then
                repeat with theItem in petesWed
                    set petesTask to make new task with properties {name:theItem, primary tag:petesTag}
                    move petesTask to end of tasks of petesParentTask
                end repeat

                repeat with theItem in pineboxWed
                    set pineboxTask to make new task with properties {name:theItem, primary tag:pineBoxTag}
                    move pineboxTask to end of tasks of pineboxParentTask
                end repeat


            else if weekday of (current date) is Thursday then
                repeat with theItem in petesThurs
                    set petesTask to make new task with properties {name:theItem, primary tag:petesTag}
                    move petesTask to end of tasks of petesParentTask
                end repeat
                repeat with theItem in pineboxThurs
                    set pineboxTask to make new task with properties {name:theItem, primary tag:pineBoxTag}
                    move pineboxTask to end of tasks of pineboxParentTask
                end repeat


            else if weekday of (current date) is Friday then
                repeat with theItem in petesFri
                    set petesTask to make new task with properties {name:theItem, primary tag:petesTag}
                    move petesTask to end of tasks of petesParentTask
                end repeat
                repeat with theItem in pineboxFri
                    set pineboxTask to make new task with properties {name:theItem, primary tag:pineBoxTag}
                    move pineboxTask to end of tasks of pineboxParentTask
                end repeat


            else if weekday of (current date) is Saturday then
                repeat with theItem in petesSat
                    set petesTask to make new task with properties {name:theItem, primary tag:petesTag}
                    move petesTask to end of tasks of petesParentTask
                end repeat
                repeat with theItem in pineboxSat
                    set pineboxTask to make new task with properties {name:theItem, primary tag:pineBoxTag}
                    move pineboxTask to end of tasks of pineboxParentTask
                end repeat

            end if

And finally, we’ll do the same with Coding, Exercise and Music:

repeat with theItem in codingTasks
                set codingTask to make new task with properties {name:theItem, primary tag:codingTag}
                move codingTask to end of tasks of codingParentTask
            end repeat


            repeat with theItem in exerciseTasks
                set exerciseTask to make new task with properties {name:theItem, primary tag:exerciseTag}
                move exerciseTask to end of tasks of exerciseParentTask
            end repeat


            repeat with theItem in musicTasks
                set musicTask to make new task with properties {name:theItem, primary tag:musicTag}
                move musicTask to end of tasks of musicParentTask
            end repeat

…and then we’ll close off the tell blocks.

end tell
    end tell
end tell

And voila! We now have a killer everyday template to use and abuse. The full code can be downloaded on my GitHub page at: https://github.com/jacobsilver2/OmniFocusDailyProjectTemplate

Thanks! Jake