Collection from Trello, Upwave, Asana, Avaza & ProofHub

Just wanted to share some initial feedback now that omni automation supports headers for authentication to cloud based productivity services.

Under GTD, I used to use AppleScript to automate collection from lots of client’s project management systems along with emails, calendars and other various places. Porting this all over to “native” omnijs has been fun and executes much quicker - too quick in some cases! And its really handy to be able to trigger most of the automated collection without being tied to the laptop/desktop.

Authentication on Trello:
URL.FetchRequest.fromString(this.base_url + path + this.auth_token).fetch();

Authentication on Upwave, Asana and Avaza:
var ufr = URL.FetchRequest.fromString(this.base_url + path)
ufr.headers = {“Authorization”: this.auth_token}

Authentication on Proofhub:
var ufr = URL.FetchRequest.fromString(this.base_url + path)
ufr.headers = {“X-API-KEY”: this.auth_token}

Once the authentication string was sorted, the mapping from each systems data model to OF was a bit fiddly (not because of OF). I generally used:
System -> Folder
Board -> Project
Card -> Task
Task -> Subtask

Some systems needed a different mapping because of the way clients used each system and structured their data. Tags came in handy for all the additional organisation elements such as: Colours, Columns, Labels, Lists etc.

There is some rate limiting which kicks in, especially on Trello, and rather than mess with async and await, the built in Timer functionality worked out - seems like OmniGroup have thought of everything.

On Upwave, for example, a basic timer was sufficient:
var delay = 0.5;
let upwave = new Upwave();
upwave.getUFR(“boards/”).then(function(boardsObject) {
boards_resp = JSON.parse(boardsObject.bodyString);
boards_resp.results.forEach((boards_item, i) => {
Timer.once(delay, function(timer) {
upwave.getUFR(“boards/” + + “/”).then(function(boardObject) {
Timer.once(delay, function(timer) {
upwave.getUFR(“cards/?board=” + {
cards_resp = JSON.parse(cardsObject.bodyString);
cards_resp.results.forEach((cards_item, i) => {
Timer.once(delay, function(timer) {
upwave.getUFR(“cards/” + + “/”).then(function(cardObject) {
Timer.once(delay, function(timer) {
upwave.getUFR(“tasklistitems/?card=” + {

On Trello, an increment with each call was necessary to spread out the requests:
var delay = 0;
var inc = 0.1;
let trello = new Trello();
trello.getUFR(“members/me/boards”).then(function(boardsObject) {
boards_resp = JSON.parse(boardsObject.bodyString);
boards_resp.forEach((boards_item, i) => {
delay = delay + inc
Timer.once(delay, function(timer) {
trello.getUFR(“boards/” + + “/”).then(function(boardObject) {
Timer.once(delay, function(timer) {
trello.getUFR(“boards/” + + “/cards”).then(function(cardsObject) {
cards_resp = JSON.parse(cardsObject.bodyString);
cards_resp.forEach((cards_item, i) => {
delay = delay + inc
Timer.once(delay, function(timer) {
trello.getUFR(“cards/” + + “/”).then(function(cardObject) {
var card_resp = JSON.parse(cardObject.bodyString)
delay = delay + inc
Timer.once(delay, function(timer) {
trello.getUFR(“cards/” + + “/checklists”).then(function(tasksObject) {

If anyone has any ideas for how to generalise the collection from these systems into OF using a data structure for each system then I am all ears. It seems like it might be possible to specify a mapping for each system that can then be used for the collection process.


1 Like

Not too much to add here for the moment. Had some (nerve wrecking) fun with async and promises myself when collecting overdue tasks from I could post the function I use to scrape their paged API if that is of any help.