×

App-to-App

One of the most powerful aspects of Omni Automation is its built-in support for executing scripting functions between the Omni applications. For example, an OmniPlan action can perform scripting functions in OmniFocus and return any resulting data back to the OmniPlan action, for use in the current project.

Copy OmniPlan Task to OmniFocus

The following example OmniPlan action will create a new task in OmniFocus, using the name, note, project title, and end date values of the selected OmniPlan task for the name, note, tag, and due date parameters of the created task.

Such “app-to-app” scripts use the tellFunction(…) and call(…) functions of the URL class to generate and execute the Omni Automation script links that perform script actions and transfer data between applications.

NOTE: a corresponding plug-in for copying OmniFocus tasks to OmniPlan is detailed on this page in the OmniFocus section of this site.

op-task-to-of-task

 1  The task selected in the OmniPlan project.

 2  The task created by the script within OmniFocus.

 3  The text of the selected task’s note is assigned to the created OmniFocus task.

 4  The name of the OmniPlan document is prepended to the note body of the created task, and is added as a tag to OmniFocus (if it doesn’t already exist).

 5  A link to the OmniFocus task is appended to the note of the selected OmniPlan task. Clicking or tapping this link will cause the created task to be displayed within OmniFocus.

 6  The end date of the the OmniPlan task is used as the due date for the created OmniFocus task.

Here is the OmniPlan action for creating a new tasks in OmniFocus using parameters of the OmniPlan selected tasks.

Copy Selected Tasks to OmniFocus
 

/*{ "type": "action", "targets": ["omniplan"], "author": "Otto Automator", "identifier": "com.omni-automation.op.copy-tasks-to-omnifocus", "version": "1.0", "description": "This action will create copies of the selected OmniPlan tasks in OmniFocus.", "label": "Copy Selected Tasks to OmniFocus", "shortLabel": "Copy to OmniFocus" }*/ (() => { var action = new PlugIn.Action(selection, sender) => { // action code // selection options: project, tasks, resources var now = new Date() var today = Calendar.current.startOfDay(now) var targetFunctionArgument = new Array() var OPprojectName = document.name selection.tasks.forEach(OPtask => { var OPtaskTitle = OPtask.title var OPtaskID = OPtask.uniqueID var OPtaskLink = "omniplan:///task/" + OPtaskID var OPtaskNote = OPtask.note if (OPtaskNote){ OPtaskNote = (OPtaskNote.length > 0) ? OPtaskNote + "\n" + OPtaskLink : OPtaskLink } else { OPtaskNote = OPtaskLink } var OPtaskDueDate = OPtask.endDate OPtaskDueDate = (OPtaskDueDate != null) ? OPtaskDueDate : today // CREATE TASK DATA OBJECT var taskDataObj = { "OPprojectName":OPprojectName, "OPtaskTitle":OPtaskTitle, "OPtaskNote":OPtaskNote, "OPtaskDueDate":OPtaskDueDate } targetFunctionArgument.push(taskDataObj) }) console.log(JSON.stringify(targetFunctionArgument)) function targetAppFunction(arg){ try { var OFTaskLinks = new Array() arg.forEach(taskDataObj => { OFtask = new Task(taskDataObj["OPtaskTitle"]) OFtaskLink = "omnifocus:///task/" + OFtask.id.primaryKey OFtask.note = taskDataObj["OPtaskNote"] OFtask.dueDate = new Date(taskDataObj["OPtaskDueDate"]) var tagName = taskDataObj["OPprojectName"] var tag = tagNamed(tagName) || new Tag(tagName) OFtask.addTag(tag) OFTaskLinks.push(OFtaskLink) }) return OFTaskLinks } catch(error){ console.log("An error occurred.") throw error } } var scriptURL = URL.tellFunction( "omnifocus", targetAppFunction, targetFunctionArgument ) scriptURL.call(resultObj => { // PROCESS RESULTS OF SCRIPT console.log("targetAppFunction result: ", resultObj) var selectedTasks = selection.tasks resultObj.forEach((OFTaskLink, index) => { var OPTask = selectedTasks[index] var OPTaskNote = OPTask.note if (OPTaskNote){ if(OPTaskNote.length > 0){ OPTask.note = OPTaskNote + "\n" + OFTaskLink } else { OPTask.note = OFTaskLink } } else { OPTask.note = OFTaskLink } }) }, function(err){ // PROCESS SCRIPT ERROR new Alert("SCRIPT ERROR", err.errorMessage).show() console.error(err.errorMessage) }) }); action.validate = (selection, sender) => { // validation code // selection options: project, tasks, resources return (selection.tasks.length > 0) }; return action; })();

 01-10  The metadata keys and values for the action plug-in file.

 11-104  The main function that contains all of the action components, including the validation  97-101  and processing functions:  12-95 

 12-95  The processing function of the action is passed the selection and sender objects. The selection object may contain references to the selected: projects, tasks, or resources.

 16-17  Create and store a reference to the current date to be used if no date is provided in OmniPlan.

 19-41  In order to re-create the selected OmniPlan tasks in OmniFocus, property values for each of the selected tasks are gathered and stored within standard JavaScript objects with key:value pairs, one for each task, that are grouped together as a collection in a JavaScript array. [{"OPprojectName":"Project Name", "OPtaskTitle":"Prepare Footings", "OPtaskNote":"Check dig depth",…},{"OPprojectName":"Project Name", "OPtaskTitle":"Add Rebar", "OPtaskNote":"Check wiring",…}…]. The generated array is stored in the variable targetFunctionArgument which will be used as input for the function that generates the tasks in OmniFocus.

 24  Note that a link to each OmniPlan task is created and stored. These links will ultimately be placed at the end of each of the individual OmniFocus notes to enable the user to TAP|CLICK to select the originating task in the OmniPlan project window.

 43  As an aide in customizing or troubleshooting the plug-in, the contents of the generated array of OmniPlan task data is logged to the console.

 45-64  The task-creation function that will be sent to OmniFocus to be executed (see detailed explanation elsewhere on this page). Note that the function incorporates a single input parameter (arg) which will contain the OmniPlan task data when it is sent to OmniFocus.

 66-70  The tellFunction(…) function of the URL class is used to convert the OmniFocus function and passed-in data into an encoded Omni Automation script URL. Note that the tellFunction(…) function takes three parameters: 1) the name of the targeted app that will execute the passed function; 2) the variable containing the function to be passed; 3) the data to be processed by the function when it executed by the targeted application.

 72-93  The call(…) function of the URL class is used to execute the script URL generated by the tellFunction(…) function. The result of the sent function will be passed into the callback function parameter of the call(…) function in the variable named resultObj. If the result of the sent function is a single item (such as a string or array), the value of the call-back function’s parameter variable will be that single object. But if the value returned contains multiple items, function’s parameter variable will be a JavaScript object containing key:value pairs of data. In this script, the result of the sent function is a simple array of strings.

 97-101  The validation function of the plug-in determines when the plug-in is enabled in the Automation menu. In this case, the plug-in can be used only when one or more OmniPlan tasks are selected.

The OmniFocus Task Creation Function

Here is the function used in the action above to create new tasks in OmniFocus using the metadata of the selected OmniPlan tasks. Documentation of the Omni Automation support in OmniFocus is available here.

The metadata of the selected OmniPlan tasks is passed into the function through the single input parameter (arg) which in this example is a JavaScript array of JavaScript objects.

The OmniFocus Task Creation Function


function targetAppFunction(arg){ try { var OFTaskLinks = new Array() arg.forEach(taskDataObj => { OFtask = new Task(taskDataObj["OPtaskTitle"]) OFtaskLink = "omnifocus:///task/" + OFtask.id.primaryKey OFtask.note = taskDataObj["OPtaskNote"] OFtask.dueDate = new Date(taskDataObj["OPtaskDueDate"]) var tagName = taskDataObj["OPprojectName"] var tag = tagNamed(tagName) || new Tag(tagName) OFtask.addTag(tag) OFTaskLinks.push(OFtaskLink) }) return OFTaskLinks } catch(error){ console.log("An error occurred.") throw error } }

 01-20  The function for creating new tasks in OmniFocus using the OmniPlan task data.

 02-19  The script is placed within JavaScript error handlers (try, catch, throw) so that any problems in the script execution are displayed to the user in OmniPlan.

 03  Create an empty array to contain links to the created OmniFocus tasks that will be returned to the calling function so that each link can be added to the notes field of its originating OmniPlan task.

 04-13  Use the forEach(…) JavaScript function to process each of the OmniPlan task data objects within the array of objects contained in the input parameter (arg). Each object will be represented by the variable taskDataObj as the array of objects is iterated.

 05  Create a new OmniFocus task using the title of the corresponding OmniPlan task extracted from the passed-in object using the key: "OPtaskTitle"

 06  Generate a link URL to the created task and store it in the variable: OFtaskLink

 07  Set the value fo the created task's note using the notes of the corresponding OmniPlan task extracted from the passed-in object using the key: "OPtaskNote"

 08  Create a date object using the date string representing the end date value of the OmniPlan task. Assign the due date of the created task to the reconstituted date object.

 09-11  If it doesn’t already exist, create a new tag using the name of the OmniPlan project. Use the addTag(…) function of the Task class to add the tag to the created task.

 12  Add the generated link to the created OmniFocus task to the array of task links.

 13  Return the array of links to the created OmniFocus tasks to the calling function so that they may be inserted into the notes of their corresponding OmniPlan tasks.