Tasks in the Inbox

var projectName = "Inbox-Backup" var projectTitles = projects.map(project => {return project.name}) if (projectTitles.includes(projectName)){ var project = projectNamed(projectName) document.windows[0].perspective = Perspective.BuiltIn.Projects document.windows[0].selectObjects([project]) var alertTitle = "Project Exists" var alertMessage = "A project named “" + projectName + "” already exists. Please retore, rename, or remove the existing project before running the Inbox Backup script." new Alert(alertTitle,alertMessage).show() } else if (inbox.length === 0){ var alertTitle = "Empty Inbox" var alertMessage = "The Inbox contains no tasks to backup." new Alert(alertTitle,alertMessage).show() } else { try { var alertTitle = "Confirm Backup" var alertMessage = "This script will move the contents of the Inbox into a new project named: “" + projectName + "”\n\nPlease confirm this action." var alert = new Alert(alertTitle,alertMessage) alert.addOption("Proceed") alert.addOption("Stop") alert.show(function(result){ if (result == 0){ // create the backup project var project = new Project(projectName) project.containsSingletonActions = true var projectID = project.id.primaryKey // move contents of inbox moveTasks(inbox, project) // show the new project URL.fromString("omnifocus:///task/" + projectID).open() } }) } catch(err){console.error(err.message)} }
omnifocus://localhost/omnijs-run?script=var%20projectName%20%3D%20%22Inbox%2DBackup%22%0Avar%20projectTitles%20%3D%20projects%2Emap%28project%20%3D%3E%20%7Breturn%20project%2Ename%7D%29%0Aif%20%28projectTitles%2Eincludes%28projectName%29%29%7B%0A%09var%20project%20%3D%20projectNamed%28projectName%29%0A%09document%2Ewindows%5B0%5D%2Eperspective%20%3D%20Perspective%2EBuiltIn%2EProjects%0A%09document%2Ewindows%5B0%5D%2EselectObjects%28%5Bproject%5D%29%0A%09var%20alertTitle%20%3D%20%22Project%20Exists%22%0A%09var%20alertMessage%20%3D%20%22A%20project%20named%20%E2%80%9C%22%20%2B%20projectName%20%2B%20%22%E2%80%9D%20already%20exists%2E%20Please%20retore%2C%20rename%2C%20or%20remove%20the%20existing%20project%20before%20running%20the%20Inbox%20Backup%20script%2E%22%0A%09new%20Alert%28alertTitle%2CalertMessage%29%2Eshow%28%29%0A%7D%20else%20if%20%28inbox%2Elength%20%3D%3D%3D%200%29%7B%0A%09var%20alertTitle%20%3D%20%22Empty%20Inbox%22%0A%09var%20alertMessage%20%3D%20%22The%20Inbox%20contains%20no%20tasks%20to%20backup%2E%22%0A%09new%20Alert%28alertTitle%2CalertMessage%29%2Eshow%28%29%0A%7D%20else%20%7B%0A%09try%20%7B%0A%09%09var%20alertTitle%20%3D%20%22Confirm%20Backup%22%0A%09%09var%20alertMessage%20%3D%20%22This%20script%20will%20move%20the%20contents%20of%20the%20Inbox%20into%20a%20new%20project%20named%3A%20%E2%80%9C%22%20%2B%20projectName%20%2B%20%22%E2%80%9D%5Cn%5CnPlease%20confirm%20this%20action%2E%22%0A%09%09var%20alert%20%3D%20new%20Alert%28alertTitle%2CalertMessage%29%0A%09%09alert%2EaddOption%28%22Proceed%22%29%0A%09%09alert%2EaddOption%28%22Stop%22%29%0A%09%09alert%2Eshow%28function%28result%29%7B%0A%09%09%09if%20%28result%20%3D%3D%200%29%7B%0A%09%09%09%09%2F%2F%20create%20the%20backup%20project%0A%09%09%09%09var%20project%20%3D%20new%20Project%28projectName%29%0A%09%09%09%09project%2EcontainsSingletonActions%20%3D%20true%0A%09%09%09%09var%20projectID%20%3D%20project%2Eid%2EprimaryKey%0A%09%09%09%09%2F%2F%20move%20contents%20of%20inbox%0A%09%09%09%09moveTasks%28inbox%2C%20project%29%0A%09%09%09%09%2F%2F%20show%20the%20new%20project%0A%09%09%09%09URL%2EfromString%28%22omnifocus%3A%2F%2F%2Ftask%2F%22%20%2B%20projectID%29%2Eopen%28%29%0A%09%09%09%7D%0A%09%09%7D%29%0A%09%7D%0A%09catch%28err%29%7Bconsole%2Eerror%28err%2Emessage%29%7D%0A%7D
var projectName = "Inbox-Backup" var project = projectNamed(projectName) if (project === null){ document.windows[0].perspective = Perspective.BuiltIn.Projects var alertTitle = "Missing Project" var alertMessage = "A project named “" + projectName + "” does not exist in Projects." new Alert(alertTitle,alertMessage).show() } else if (project.tasks.length === 0){ document.windows[0].perspective = Perspective.BuiltIn.Projects document.windows[0].selectObjects([project]) var alertTitle = "Empty Project" var alertMessage = "The project “" + projectName + "” contains no tasks to restore to the Inbox." new Alert(alertTitle,alertMessage).show() } else { try { var alertTitle = "Confirm Restore" var alertMessage = "This script will move the contents of project “" + projectName + "” into the Inbox.\n\nPlease confirm this action." var alert = new Alert(alertTitle,alertMessage) alert.addOption("Proceed") alert.addOption("Stop") alert.show(function(result){ if (result == 0){ moveTasks(project.tasks,inbox.ending) if(project.children.length === 0){deleteObject(project)} URL.fromString("omnifocus:///inbox").open() } }) } catch(err){console.error(err.message)} }
omnifocus://localhost/omnijs-run?script=var%20projectName%20%3D%20%22Inbox%2DBackup%22%0Avar%20project%20%3D%20projectNamed%28projectName%29%0Aif%20%28project%20%3D%3D%3D%20null%29%7B%0A%09document%2Ewindows%5B0%5D%2Eperspective%20%3D%20Perspective%2EBuiltIn%2EProjects%0A%09var%20alertTitle%20%3D%20%22Missing%20Project%22%0A%09var%20alertMessage%20%3D%20%22A%20project%20named%20%E2%80%9C%22%20%2B%20projectName%20%2B%20%22%E2%80%9D%20does%20not%20exist%20in%20Projects%2E%22%0A%09new%20Alert%28alertTitle%2CalertMessage%29%2Eshow%28%29%0A%7D%20else%20if%20%28project%2Etasks%2Elength%20%3D%3D%3D%200%29%7B%0A%09document%2Ewindows%5B0%5D%2Eperspective%20%3D%20Perspective%2EBuiltIn%2EProjects%0A%09document%2Ewindows%5B0%5D%2EselectObjects%28%5Bproject%5D%29%0A%09var%20alertTitle%20%3D%20%22Empty%20Project%22%0A%09var%20alertMessage%20%3D%20%22The%20project%20%E2%80%9C%22%20%2B%20projectName%20%2B%20%22%E2%80%9D%20contains%20no%20tasks%20to%20restore%20to%20the%20Inbox%2E%22%0A%09new%20Alert%28alertTitle%2CalertMessage%29%2Eshow%28%29%0A%7D%20else%20%7B%0A%09try%20%7B%0A%09%09var%20alertTitle%20%3D%20%22Confirm%20Restore%22%0A%09%09var%20alertMessage%20%3D%20%22This%20script%20will%20move%20the%20contents%20of%20project%20%E2%80%9C%22%20%2B%20projectName%20%2B%20%22%E2%80%9D%20into%20the%20Inbox%2E%5Cn%5CnPlease%20confirm%20this%20action%2E%22%0A%09%09var%20alert%20%3D%20new%20Alert%28alertTitle%2CalertMessage%29%0A%09%09alert%2EaddOption%28%22Proceed%22%29%0A%09%09alert%2EaddOption%28%22Stop%22%29%0A%09%09alert%2Eshow%28function%28result%29%7B%0A%09%09%09if%20%28result%20%3D%3D%200%29%7B%0A%09%09%09%09moveTasks%28project%2Etasks%2Cinbox%2Eending%29%0A%09%09%09%09if%28project%2Echildren%2Elength%20%3D%3D%3D%200%29%7BdeleteObject%28project%29%7D%0A%09%09%09%09URL%2EfromString%28%22omnifocus%3A%2F%2F%2Finbox%22%29%2Eopen%28%29%0A%09%09%09%7D%0A%09%09%7D%29%0A%09%7D%0A%09catch%28err%29%7Bconsole%2Eerror%28err%2Emessage%29%7D%0A%7D

The topic of this section is about creating and manipulating tasks in the OmniFocus Inbox.

In preparation, select the Inbox perspective and clear it of any tasks with a TAP|CLICK on the Inbox Backup button below. The corresponding Omni Automation script will be executed and will move the contents of the Inbox into a new project titled “Inbox-Backup.”

To return the archived tasks to the Inbox, TAP|CLICK the Inbox Restore button, whose script will move the contents of the “Inbox-Backup” project back into the Inbox and then delete the empty backup project.

 • 


The inbox property of the top-level Database class represents the same list of tasks that are displayed in the Inbox view in the OmniFocus interface.

In JavaScript, normally the properties of classes are invoked by placing the property name after the class name delineated with a period (.), like this:

Class.property

In Omni Automation, since the Database class is the top-level scripting element in OmniFocus, it is implied, and its properties and functions do not need to be preceded with a class reference in your script statements.

For example, the inbox property of the Database class is invoked in scripts like this:

inbox

instead of:

Database.inbox

This behavior pertains only to the properties and functions of the top-level Database class.

DO THIS ►

In the OmniFocus console window, enter the term: inbox and TAP|CLICK the Return key to execute the script:

The result of the property statement is an array of references to all of the tasks in the inbox, which in this example is none, and is shown as an empty array: [ ]

DO THIS ►

To confirm the results of the previous script, enter and run the following statement that checks the “length” or number of items in the result array:

The resulting zero digit confirms that indeed there are no items in the inbox. So, let’s change that by creating a new task!

DO THIS ►

New Tasks are created using the new item constructor. Enter and execute the following statement for creating a new instance of the Task class titled “Task Two” by placing the new constructor term prior to the class name Task and include the name for the new task as a text string placed within the opening and closing constructor parenthesis:

A new task is created in the inbox, and an object reference and properties record for the created task are returned in the console window.

Object References and Properties Records

An [object reference] is a representative for a scripting object and may be stored in a variable for use later in a script in order to address the previously created/referenced item.

A resulting console {properties record} is a JavaScript object containing a comma-delimited list of each of the source object’s property names and their corresponding values:

{property:value, property:value, property:value, etc.}

A property is a quality, feature, or element of the object (in this example, the object is a Task). Properties have values that may be expressed in the form of text strings (such as the name property), an array of object references (like the attachments property), booleans (true/false) (such as the flagged property), or even dates (such as the dueDate and deferDate properties)

Here is a property record for a newly created task:

Task Object Reference and Properties Record


[object Task: Task Two] {active: true, added: null, after: [object Task.ChildInsertionLocation], assignedContainer: null, attachments: [], before: [object Task.ChildInsertionLocation], beginning: [object Task.ChildInsertionLocation], children: [], completed: false, completedByChildren: false, completionDate: null, containingProject: null, deferDate: null, dropDate: null, dueDate: null, effectiveActive: true, effectiveCompletedDate: null, effectiveDeferDate: null, effectiveDropDate: null, effectiveDueDate: null, effectiveFlagged: false, ending: [object Task.ChildInsertionLocation], estimatedMinutes: null, flagged: false, flattenedChildren: [], flattenedTasks: [], hasChildren: false, id: [object ObjectIdentifier: Task ay_6C0aFLsr], inInbox: true, linkedFileURLs: [], modified: null, name: "Task Two", note: "", notifications: [], project: null, repetitionRule: null, sequential: false, shouldUseFloatingTimeZone: true, tags: [], taskStatus: [object Task.Status: Available], tasks: []}

Since the created task is new and not yet altered, its properties record contains many empty arrays [ ], null values, and negative boolean (false) values. As we will see later, scripts can change the values of many of a task’s properties.

The corresponding properties record for an object can be viewed in the console window at any time by entering the object reference or history variable for the created item.

FYI: The properties record for a created item is automatically displayed in the console as a convenience to enable you to quickly see the current state of an object. To generate the properties record for an object for use in your scripts, pass an object reference to the object into JavaScript’s built-in Object.getOwnPropertyDescriptors(objRef) function.

Now back to our task! In the application interface, the newly created task is displayed in the Inbox:

first-task

With our first task created, let’s return to our first script statement and run it again.

DO THIS ►

Enter and run the following script statement:

As with the first script, the result is an array of object reference to the tasks in the inbox. Currently there is only one task in the inbox so the resulting array contains a single object reference to the task we just created.

Let’s confirm those results by getting the number of items in the inbox.

DO THIS ►

Enter and execute the same script statement as we did previously:

The script result is an integer representing the number of items in the inbox, in this example: 1

Scripts often reference specific tasks in the inbox by identifying them by their position in the array of inbox tasks, or by their name (title).

We use these same techniques often in “real life.” For example, imagine you are standing in front of a line of people. You could identify a specific person in the line by their position in the line by saying “Will the third person in line please step forward.” Or you could identify a specific person in line by using their name: “Will Roberta Carlise please step forward.”

Using an item’s positional index, you can reference an existing inbox task. However, it is important to note that indexes representing items in JavaScript array, begin with 0 not 1. The first item in a JavaScript array is item[0] not item[1]. So to generate an object reference to the previously created task, we would request the first item in inbox by including a positional indicator of 0. To make the script a bit more interesting, we will also append the name property to the statement in order to retrieve the title of the identified task.

DO THIS ►

Enter and run the following script statement in the colsole:

The result of the script statement will be the text string that is the title of our created task: "Task Two"

Aside from using a positional index to identify a task by its position in the inbox, you may reference the task by its name (title) using the taskNamed(…) function of the Database class.

DO THIS ►

Enter and run the following script statement:

The result of the script statement is an object reference to the task in the inbox named: "Task Two"

We can use the object reference generated by the statement to change the value a property of the specified task.

DO THIS ►

Enter and run the following script statement that will cause the task to become flagged:

The result of the statement will be the boolean value true and the task will now appear flagged in the OmniFocus interface.

flagged-task

As stated previously, object references can be stored in JavaScript variables for use elsewhere in a script. Let’s store the object reference generated by the taskNamed(…) function in a variable, and then use the variable in another script statement that changes the value of one of the referenced task’s properties.

DO THIS ►

Enter and run the following script statement that will instantiate the variable “task” with an object reference to the targeted task:

In our example, an object reference to the target task has been generated by the taskNamed(…) function and stored in the variable: task

Now let’s use the variable in a script statement that will change the value of the referenced task’s note property.

DO THIS ►

Enter and run the following script statement that will set the value of the referenced task’s note property:

Note that you may use an opening/closing pair of either single ( ' ) or double ( " ) quotes when encasing text strings.

In OmniFocus, the text of the task’s note will now be the indicated text:

task-note

Task Insertion Locations

The instance of the Inbox class returned as the value the inbox property of the Database class has two properties that can be used when adding, duplicating, or moving tasks: beginning and ending

Use of these properties will enable scripts to add tasks at either the beginning or the end of the list of tasks currently in the inbox.

In a previous script statement we used the new class constructor to create a new task:

new Task("Task Two")

Here's the definition for the Task constructor from the OmniFocus API documentation:

As this API entry states, when creating a new instance of the Task class, you must supply a text string as the value for the first parameter of the function, which is the “name” parameter.

The Task constructor function has a second optional parameter “position” which is used to indicate where you want to insert the newly created task: in a specific project; in another task; or in a specified task insertion location.

We’ll use the beginning and ending properties of the Inbox class to create task insertion locations used to add two new tasks to the inbox:

DO THIS ►

Enter and run the following script statements:

There will now be three tasks in the Inbox:

three-tasks-inbox

Next, let’s iterate the tasks in the Inbox (process them in order and one-at-a-time) to set some of their properties to be similar. To accomplish this process we’ll use the built-in JavaScript function forEach(…) (w3cschools.com) that is designed for processing arrays of items.

DO THIS ►

Enter and run the following multiple-line script. TAP|CLICK the “Copy Script” button and then paste the copied script into OmniFocus console and press the “Return” or “Go” key.

IMPORTANT: The ability to copy the multiple-line script to the clipboard is provided as a convenience for you — but it can be entered by hand if you wish. In OmniFocus on iPadOS, you can press Option-Return to insert a new line without attempting to evaluate the current input.

Iterate Inbox


inbox.forEach(task => { task.note = "This is the note for task: " + task.name task.flagged = false })

 1-4  The forEach() method calls the provided function once for each element in an array, in order. In this example, the function is stated as an “arrow function” with a single argument that represents each one of the array items as the array is iterated. Since the forEach(…) method is called on the inbox property of the Database class, the resulting array will be an array of the tasks in the inbox. Accordingly, the argument variable is named “task” as it represents each one of the array’s tasks as they are processed in order.

 2  The value of the note property of the iterated task is set the be the provided string appended with the name of the iterated task.

 3  The value of the flagged property of the iterated task is set to false, meaning that the task will appear as un-flagged.

After running the script, the three tasks will have been edited:

processed-inbox

Summary

In this section you learned:

In the next section, we’ll create and modify repeating and due tasks in the OmniFocus Inbox.