Skip to content

Instantly share code, notes, and snippets.

@tgray
Last active May 5, 2021 12:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tgray/3e81bad89479b3e8a4d582d197f63bdf to your computer and use it in GitHub Desktop.
Save tgray/3e81bad89479b3e8a4d582d197f63bdf to your computer and use it in GitHub Desktop.
Omni automation scripts for OmniFocus

OmniFocus automation scripts

Automation scripts for OmniFocus (OF). Barely tested, but they seem to work for me.

Follow Up

Tags selected tasks with the tag "Follow up". Change this if you'd like to use a different tag. Also shifts the due and defer date of the tasks 7 days into the future, if they tasks have them. Lastly, adds a line in the Note for each task saying "Followd up on yyyy-mm-dd", with the date that the script was run.

Example

My use case is as follows. It's Monday, and I need Steve to do something for me. I ask him and he replies that he will work on it, but it might take time for reasons. I want to follow up in a week to check on the status, so I make a task in OF ("Follow up with Steve about Item"), with a defer date of next Monday (so I don't bug him too early) and a due date of Wednesday (because I need to report out on the status on Thursday). I may drop the defer and/or due date depending on the nature of the task.

When I follow up with Steve next week, if the task is done, I just check it off and go about my business. If it is not done and needs further follow up, I run this script. It records in the Note of the task that I did take action and follow up, and it also pushes any dates out by a week to remind me in the future, if I needed reminders. It also tags the task with "Follow up" so I can easily find any tasks that need to be checked on in the future. This is particularly useful for tasks without due dates. I have a custom perspective for these tasks that I check on as part of my weekly review.

Shift Dates

Sometimes dates need to be changed for tasks. It is easy enough to change dates on a single tasks using the Inspector. However, it is more annoying if multiple tasks need to be shifted by the same amount.

This script will shift due and/or defer dates if a task has them. The script opens a date dialog. The amount to shift is based on the difference between the date selected and today, the date the script is run. It is easier to think about if one just types in the number of days or weeks one would like to shift that tasks, e.g. "3d" to shift the tasks 3 days into the future. It is also possible to move dates earlier by entering negative values ("-2w" would be two weeks earlier). This script does not adjust the time; it only works in increments of days.

Accepts tasks for now. I'd like to be able shift project dates as well, but currently it does not appear that projects have accessible dueDate or deferDate properties yet.

Date math note

Typing in a relative date like "3d" works because the script calculates the difference in days between the entered date ("3d" calculates as 3 days from today) and today. In this example, one ends up with "today" - "today + 3 days" -> 3 days difference.

/*{
"type": "action",
"targets": ["omnifocus"],
"author": "Tim Gray",
"identifier": "com.125px.FollowUp",
"version": "1.0",
"description": "This action will tag the selected task with 'Follow Up' and move the defer and due dates by one week.",
"label": "Follow Up",
"shortLabel": "Follow Up"
}*/
(() => {
var action = new PlugIn.Action(function(selection, sender){
// action code
// selection options: tasks, projects, folders, tags
function addDays(date, days) {
var result = new Date(date)
result.setDate(result.getDate() + days)
return result
}
var now = new Date()
now.getDate()
datestr = now.toISOString().substring(0, 10)
selection.tasks.forEach(function(task){
// <# PUT YOUR PROCESSING CODE HERE #>
console.log("Follow up on task '" + task.name + "'");
// Find the right tag, or make it
targetTagName = "Follow up"
var targetTag = null
tags.apply(function(tag){
if(tag.name == targetTagName){
targetTag = tag
return ApplyResult.Stop
}
})
tag = targetTag || new Tag(targetTagName)
task.addTag(tag)
if ( task.dueDate != null){
task.dueDate = addDays(task.dueDate, 7)
}
if ( task.deferDate != null){
task.deferDate = addDays(task.deferDate, 7)
}
if ( task.note == ""){
task.note = "Followed up on " + datestr + "."
} else {
task.note += "\nFollowed up on " + datestr + "."
}
})
});
action.validate = function(selection, sender){
// validation code
// selection options: tasks, projects, folders, tags
return (selection.tasks.length > 0)
};
return action;
})();
// vim: set et ft=javascript sts=4 sw=4 ts=4 :
// COPY & PASTE into editor app. EDIT & SAVE with “.omnijs” file extension.
/*{
"type": "action",
"targets": ["omnifocus"],
"author": "Tim Gray",
"identifier": "com.125px.shiftdates",
"version": "1.0",
"description": "Shift both defer and due dates by the specified amount.",
"label": "Shift Dates",
"shortLabel": "Shift Dates"
}*/
(() => {
var action = new PlugIn.Action(function(selection, sender){
// action code
// selection options: tasks, projects, folders, tags
function addDays(date, days) {
var result = new Date(date)
result.setDate(result.getDate() + days)
// console.log(result, days)
return result
}
var now = new Date()
now.getDate()
now.setHours(0,0,0,0)
datestr = now.toISOString().substring(0, 10)
// CONSTRUCT THE FORM
var inputForm = new Form()
// CREATE FORM ELEMENTS: TEXT INPUT
shiftField = new Form.Field.Date("shiftDate", "Shift Dates", null)
// dueField = new Form.Field.Date("newDue", "Due Date", null)
// deferField = new Form.Field.Date("newDefer", "Defer Date", null)
// CREATE FORM ELEMENT: OPTION MENU
// popupMenu = new Form.Field.Option(
// "dateType",
// "Date Type",
// [0, 1, 2],
// ["Due and Defer","Due", "Defer"],
// 0
// )
// ADD THE ELEMENTS TO THE FORM
inputForm.addField(shiftField)
// inputForm.addField(popupMenu)
// DIALOG PROMPT AND OK BUTTON TITLE
let formPrompt = "Enter the amount to shift dates:"
let buttonTitle = "Continue"
// DISPLAY THE FORM DIALOG
formPromise = inputForm.show(formPrompt, buttonTitle)
// VALIDATE FORM CONTENT
// inputForm.validate = function(formObject){
// // EXTRACT VALUES FROM THE FORM’S VALUES OBJECT
// textValue = formObject.values['newDue']
// return ((textValue) ? true:false)
// }
// PERFORM PROCESSES USING FORM DATA
formPromise.then(function(formObject){
shiftVal = formObject.values['shiftDate']
// dateTypes = formObject.values['dateType']
dateDelta = (shiftVal - now) / (1000 * 60 * 60 * 24)
// console.log(dateDelta)
// item loops
selection.folders.forEach(function(folder){
console.log(folder.name);
// folder processing statements
})
selection.projects.forEach(function(project){
console.log(project.name);
// project processing statements
})
selection.tasks.forEach(function(task){
console.log("Shifting task '" + task.name + "' by " + dateDelta + " days");
// task processing statements
// if ( task.dueDate != null && [0,1].includes(dateTypes) ){
if ( task.dueDate != null ){
task.dueDate = addDays(task.dueDate, dateDelta)
}
// if ( task.deferDate != null && [0,2].includes(dateTypes) ){
if ( task.deferDate != null ){
task.deferDate = addDays(task.deferDate, dateDelta)
}
})
selection.tags.forEach(function(tag){
console.log(tag.name);
// tag processing statements
})
})
// PROCESS FORM CANCELLATION
formPromise.catch(function(err){
console.log("form cancelled", err.message)
})
});
action.validate = function(selection, sender){
// validation code
// selection options: tasks, projects, folders, tags
var conditionsArray = [
eval(selection.tasks.length > 0),
// eval(selection.projects.length > 0),
// eval(selection.folders.length > 0),
// eval(selection.tags.length > 0)
]
return conditionsArray.includes(true)
};
return action;
})();
// vim: set et ft=javascript sts=4 sw=4 ts=4 :
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment