I love Trello.

And I love OmniFocus.

I use Trello to manage tasks and projets with my students. As soon as there are more than one person working on a project, I have a Trello board for it.

But I also have very big lists of tasks that are only mine, and for managing these lists, there is nothing like OmniFocus.

The problem is that both programs are not obvious to keep in sync, and I still want to have one place to manage my day, and this place is OmniFocus.

So I adapted a very nice applescript from Matthew Conto (thanks a lot, Matthew – https://github.com/nsh87/trello-geektool) to fetch all the Trello cards, on all my Trello boards, that are assigned to me and that are not labelled ‘Done’ or ‘Terminé’ (In French). These cards are then created as tasks in OmniFocus in a dedicated “Trello” project. The nice part of it is that if a Trello card becomes completed or is not assigned to me anymore, then it becomes completed in OmniFocus. And if it becomes not-completed or becomes again assigned to me in Trello, then is also becomes not-completed in OmniFocus. Due dates are also synced.

Okay, you need to be a little bit tech savvy to use this script, but I think it’s pretty well commented, so if you want to try it out by yourself, here it is.

You have to install “JSON Helper” before using this script : https://apps.apple.com/us/app/json-helper-for-applescript/id453114608

Good luck !

-- This script fetches for all my tasks on every board and adds them or update them in OmniFocus, in a project named Trello.
 -- For every Trello tasks that is assigned to me, an OmniFocus task is created or its status (completed/not completed) is updated. This is an unidirectional sync. Every modification must be done in Trello and  then synced to OmniFocus. Defer dates and new tags can however be assigned to the tasks in OmniFocus.
 -- Application "JSON Helper" must be installed for this script to work.
 -- https://apps.apple.com/us/app/json-helper-for-applescript/id453114608
 

 

 on ConvertURLtoTrelloApp(inURL)
 -- Convert a https://trello.com/xxxxxx url to a trello://trello.com/xxxxxx one.
 set nChars to count of inURL
 set outURL to "trello://" & characters 9 through nChars of inURL
 return outURL
 end ConvertURLtoTrelloApp
 

 

 on run
 
 -- Based on the GetTrelloCards applescript by Matthew Conto
 -- https://github.com/nsh87/trello-geektool
 
 set tagName to "Trello"
 set trelloCompletedString to {"Terminé", "Done"}
 set linkToTrelloApp to false -- Set to true to link to Trello App instead of Trello website
 
 set trelloAppKey to "PUT_YOUR_OWN_APP_KEY_HERE" -- get your key at https://trello.com/1/appKey/generate
 set trelloUserToken to "PUT_YOUR_OWN_TOKEN_HERE" -- then get your token at https://trello.com/1/authorize?key=**YOURKEY**&name=**YOURAPP**&expiration=never&response_type=token&scope=read
 
 -- NEVER POST OR COMMIT YOUR APP KEYS OR USER TOKENS ONLINE.
 -- Bad things happen to good people.
 
 set nCompletedTasks to 0
 set nOpenTasks to 0
 set nNewTasks to 0
 set newTaskNames to ""
 
 tell front document of application "OmniFocus"
 
 set allProjects to flattened projects whose name is "Trello"
 if length of allProjects is 0 then
 --Create the project
 set omnifocusToplevelProject to make new project with properties {name:"Trello"}
 else
 set omnifocusToplevelProject to first item of allProjects
 end if
 
 -- Mark all task in Trello project complete. We will update it after using information from Trello.
 tell tasks of omnifocusToplevelProject to mark complete
 set omnifocusTasks to tasks of omnifocusToplevelProject
 set nCompletedTasks to length of omnifocusTasks
 
 end tell
 
 
 
 
 tell application "JSON Helper"
 set jsonString to fetch JSON from "https://trello.com/1/members/my/cards?fields=idList,name,url,desc,labels,due,idBoard&key=" & trelloAppKey & "&token=" & trelloUserToken
 
 set nCards to count of jsonString
 repeat with iCard from 1 to nCards
 
 -- Get the ID, URL and title
 set taskID to |id| of item iCard of jsonString as string
 set taskURL to |url| of item iCard of jsonString as string
 if linkToTrelloApp is true then
 set taskURL to my ConvertURLtoTrelloApp(taskURL)
 end if
 set taskName to |name| of item iCard of jsonString as string
 set taskNote to desc of item iCard of jsonString as string
 set boardID to idBoard of item iCard of jsonString as string
 set listID to idList of item iCard of jsonString as string
 set boardURL to "https://trello.com/b/" & boardID
 set taskDue to due of item iCard of jsonString as string
 if taskDue is not "missing value" then
 -- Reformat due date
 set taskDueYear to characters 1 thru 4 of taskDue as string
 set taskDueMonth to characters 6 thru 7 of taskDue as string
 set taskDueDate to characters 9 thru 10 of taskDue as string
 set taskDue to the current date
 set the year of taskDue to taskDueYear
 set the day of taskDue to taskDueDate
 set the month of taskDue to taskDueMonth
 set the time of taskDue to 0
 else
 set taskDue to missing value
 end if
 
 -- Get board name and append it to the task name
 set jsonBoardString to fetch JSON from "https://trello.com/1/boards/" & boardID & "?fields=name,url&key=" & trelloAppKey & "&token=" & trelloUserToken
 set boardName to |name| of jsonBoardString as string
 set boardURL to |url| of jsonBoardString as string
 if linkToTrelloApp is true then
 set boardURL to my ConvertURLtoTrelloApp(boardURL)
 end if
 set taskName to "Trello - " & boardName & " - " & taskName
 
 -- Get list name and append it to the task name
 set jsonListString to fetch JSON from "https://trello.com/1/cards/" & taskID & "/list?fields=name&key=" & trelloAppKey & "&token=" & trelloUserToken
 set listName to |name| of jsonListString as string
 
 -- Check in the labels if the task is complete
 set taskComplete to false
 set nLabels to count of labels of item iCard of jsonString
 if nLabels > 0 then
 repeat with iLabel from 1 to nLabels
 set taskLabel to |name| of item iLabel of labels of item iCard of jsonString
 if trelloCompletedString contains taskLabel then
 set taskComplete to true
 end if
 end repeat
 end if
 
 -- Check the list name if the task is complete
 if trelloCompletedString contains listName then
 set taskComplete to true
 end if
 
 
 -- Search for this task in OmniFocus and update it. If it doesn't exist, create it.
 tell front document of application "OmniFocus"
 set omnifocusTasks to (tasks of omnifocusToplevelProject whose note begins with "Trello Card #" & taskID)
 if length of omnifocusTasks > 0 then
 -- The task exists
 set omnifocusTask to first item of omnifocusTasks
 set name of omnifocusTask to taskName
 else
 -- The task must be created
 tell omnifocusToplevelProject
 set omnifocusTask to make new task with properties {name:taskName, note:taskNote}
 end tell
 set nNewTasks to nNewTasks + 1
 set nCompletedTasks to nCompletedTasks + 1
 set newTaskNames to newTaskNames & "- " & taskName & "
 "
 end if
 
 -- Update the card
 set name of omnifocusTask to taskName
 set note of omnifocusTask to "Trello Card #" & taskID & "
 

 This task must be edited in Trello and not directly in OmniFocus. See below for more information.
 

 Go to the Trello board:
 " & boardURL & "
 

 Edit this task in Trello:
 " & taskURL & "
 

 " & taskNote & "
 

 -----------------------------
 

 This is an unidirectional sync. Every update must be done in Trello.
 Defer dates and tags can however be assigned to the task in OmniFocus.
 

 After editing the task in Trello, run the sync script again to reflect the changes in OmniFocus."
 
 if taskComplete is true then
 tell omnifocusTask to mark complete
 else
 set nOpenTasks to nOpenTasks + 1
 set nCompletedTasks to nCompletedTasks - 1
 tell omnifocusTask to mark incomplete
 end if
 
 set due date of omnifocusTask to taskDue
 
 end tell
 
 
 end repeat
 
 
 end tell
 
 tell application "JSON Helper" to quit
 
 display dialog "Sync complete: 
 " & nNewTasks & " new tasks
 " & newTaskNames & " 
 " & nOpenTasks & " open tasks
 " & nCompletedTasks & " completed tasks." with title "Trello importer" buttons "OK"
 
 end run