Task Attachments

A task attachment is a representation for a file that is added (“attached”) to a task. Omni Automation in OmniFocus provides the ability to add, retrieve, and remove attachments to/from tasks.

Task Attachment Properties

There is one property regarding file attachments for the Task class:

Task Attachment Functions

The functions of the Task class dealing with the management of attachments.

Adding Attachments

Task attachments are instances of the FileWrapper class with each instance representing a file. FileWrappers can be generated from data of various FileTypes, such as images, and text, property list, and document files.

The following example plug-in demonstrates how create FileWrapper instances from chosen files and “attach” them to a selected task.

Add Chosen Files to Task as Attachments

/*{ "type": "action", "targets": ["omnifocus"], "author": "Otto Automaator", "identifier": "com.omni-automation.of.add-attachments-to-task", "version": "1.2", "description": "This action will add chosen files as attachments to the selected task.", "label": "Add Attachments to Task", "shortLabel": "Add Attachments" }*/ (() => { var action = new PlugIn.Action(function(selection, sender){ // action code // selection options: tasks, projects, folders, tags var task = selection.tasks[0] var picker = new FilePicker() picker.folders = false picker.multiple = true // Generic types: FileType.image, FileType.pdf, FileType.plainText, etc. // https://omni-automation.com/shared/filetypes.html picker.types = null // any file type picker.show().then(function(urlsArray){ urlsArray.forEach(url =>{ var urlStr = url.string var fileName = urlStr.substring(urlStr.lastIndexOf('/') + 1) url.fetch(function(data){ var wrapper = FileWrapper.withContents(decodeURIComponent(fileName), data) task.addAttachment(wrapper) }) }) }) }); action.validate = function(selection, sender){ // validation code // selection options: tasks, projects, folders, tags return (selection.tasks.length === 1) }; return action; })();

Deleting Attachments

Should you wish to remove attachments from their assigned task, Omni Automation provides two mechanisms for deleting existing task attachments:

Deleting All Attachments of Selected Tasks

var tasks = document.windows[0].selection.tasks tasks.forEach(task =>{ task.attachments = [] })

To delete specific attachments, use the removeAttachmentAtIndex(…) function combined with comparisons of the values of FileWrapper properties of each attachment.

For example, here's a script that will remove just the image attachments from the selected task:

Remove Image Attachments

var tasks = document.windows[0].selection.tasks if (tasks.length === 0){throw "no tasks selected"} var task = tasks[0] var wrappers = task.attachments for (var i = wrappers.length - 1; i >= 0; i--){ var wrapper = wrappers[i] if ( wrapper.type === FileWrapper.Type.File && wrapper.filename.toUpperCase().endsWith(".JPG") || wrapper.filename.toUpperCase().endsWith(".PNG") ) { task.removeAttachmentAtIndex(i) } }

NOTE: the previous example uses a JavaScript for loop to iterate the list of attachments in reverse order, removing only those file attachments whose file name ends with specified file extensions.

Export All Attachments

The following plug-in will export all of the attachments of the selected tasks into a new folder placed within a chosen directory.

Export All Attachments of Selected Tasks

/*{ "type": "action", "targets": ["omnifocus"], "author": "Otto Automator", "identifier": "com.omni-automation.of.export-attachments-of-selected-tasks", "version": "1.0", "description": "This action will export all of the attachments of the selected tasks into a new folder placed in a user-chosen directory.", "label": "Export Attachments of Selected Tasks", "shortLabel": "Export Attachments" }*/ (() => { var action = new PlugIn.Action(function(selection, sender){ // action code var tasks = selection.tasks var fileWrappers = new Array() tasks.forEach(task =>{ if(task.attachments.length > 0){ fileWrappers = fileWrappers.concat(task.attachments) } }) if (fileWrappers.length === 0){ throw new Error("No attachments") } var filesaver = new FileSaver() var folderType = new FileType("public.folder") filesaver.types = [folderType] var fldrwrapper = FileWrapper.withChildren("Export Folder", fileWrappers) var fileSaverPromise = filesaver.show(fldrwrapper) fileSaverPromise.then(urlObj => { console.log(urlObj.string) urlObj.open() }) fileSaverPromise.catch(err => { console.log(err.message) }) }); action.validate = function(selection, sender){ // validation code return (selection.tasks.length > 0) }; return action; })();