Turns each planned project in Notion into an Asana task with a subtask for every step, and never sends the same project twice.

UsesAsanaNotion

Break planned projects into Asana tasks and subtasks

Every two hours, your Notion planning database is read and each project not yet sent across becomes one Asana task with a subtask for every step of the work, so it arrives already broken down rather than as one line nobody can start on.

Each task takes the row's title as its name, the row's due date if it has one, and a description linking back to Notion; the steps you listed become subtasks in the order you wrote them. The new task's id is written back to the row and only rows without one are picked up, so the same project is never sent twice. A row with no steps yet is left alone and reported rather than sent. The row is marked only once the task and every subtask exist: if a subtask cannot be created the run stops and names the project and the step, so the project is rebuilt in full next time.

Before the first run your database needs a text property named 'Steps', an empty text property named 'Asana task' and, optionally, a date property named 'Due date'.

ScheduleRun every 2 hours.Run every 2 hours.
ValuesSet notionDatabaseId to blank.Set notionDatabaseId to blank.
ValuesSet asanaProjectIds to blank.Set asanaProjectIds to blank.
ValuesSet plannedProjects to an empty list.Set plannedProjects to an empty list.
Decisions & LoopsIf a step below fails, save the error as notionErrorIf a step below fails, save the error as notionError
Try
NotionNotionFind pages in notionDatabaseId. Save it as plannedWork.Find pages in notionDatabaseId. Save it as plannedWork.
ValuesChange plannedProjects to plannedWork.results.Change plannedProjects to plannedWork.results.
On error
ValuesSet notionFailure to Could not read that Notion database: notionError.message.Set notionFailure to Could not read that Notion database: notionError.message.
ValuesSet notionAdvice to Check the id in the 'notionDatabaseId' step, that the database is shared with your Notion connection, and that it has a text property named exactly 'Asana task'..Set notionAdvice to Check the id in the 'notionDatabaseId' step, that the database is shared with your Notion connection, and that it has a text property named exactly 'Asana task'..
Decisions & LoopsStop and report a problem: notionFailure plus notionAdvice.Stop and report a problem: notionFailure plus notionAdvice.
ValuesSet createdCount to 0.Set createdCount to 0.
Decisions & LoopsFor each projectRow in plannedProjects:For each projectRow in plannedProjects:
ValuesSet projectName to blank.Set projectName to blank.
Decisions & LoopsIf a step below fails, save the error as titleErrorIf a step below fails, save the error as titleError
Try
TextTrim projectRow.title and save it as projectName.Trim projectRow.title and save it as projectName.
On error
ValuesChange projectName to blank.Change projectName to blank.
Decisions & LoopsIf projectName is emptyIf projectName is empty
Yes
ValuesShow in the output: Skipped a row in the Notion database because it has no title, so there is nothing to call the Asana task..Show in the output: Skipped a row in the Notion database because it has no title, so there is nothing to call the Asana task..
No
ValuesSet stepsText to blank.Set stepsText to blank.
Decisions & LoopsIf a step below fails, save the error as stepsErrorIf a step below fails, save the error as stepsError
Try
TextTrim projectRow.properties.Steps and save it as stepsText.Trim projectRow.properties.Steps and save it as stepsText.
On error
ValuesChange stepsText to blank.Change stepsText to blank.
TextSplit stepsText with ; replaced by "Split stepsText with ; replaced by by a new line and save it as stepLines.
ValuesSet steps to an empty list.Set steps to an empty list.
ValuesSet stepsListed to 0.Set stepsListed to 0.
Decisions & LoopsFor each stepLine in stepLines:For each stepLine in stepLines:
Text Trim stepLine and save it as stepName. Trim stepLine and save it as stepName.
Decisions & Loops If stepName isn't empty If stepName isn't empty
Yes
ValuesAdd 1 to stepsListed.Add 1 to stepsListed.
Decisions & LoopsIf the length of steps is less than 15If the length of steps is less than 15
Yes
ListsAdd stepName to the end of steps and save it as steps.Add stepName to the end of steps and save it as steps.
No
No steps
No
No steps
Decisions & LoopsIf steps is emptyIf steps is empty
Yes
ValuesShow in the output: Left the Notion row '@projectName' for a later run: its 'Steps' property is empty, so there are no steps to break it into yet.Show in the output: Left the Notion row '@projectName' for a later run: its 'Steps' property is empty, so there are no steps to break it into yet.
No
Decisions & LoopsIf stepsListed is greater than 15If stepsListed is greater than 15
Yes
ValuesShow in the output: The Notion row '@projectName' lists stepsListed steps; only the first 15 became subtasks. Add the rest in Asana by hand.Show in the output: The Notion row '@projectName' lists stepsListed steps; only the first 15 became subtasks. Add the rest in Asana by hand.
No
No steps
ValuesSet dueDate to blank.Set dueDate to blank.
Decisions & LoopsIf a step below fails, save the error as dueDateErrorIf a step below fails, save the error as dueDateError
Try
TextTrim projectRow.properties["Due date"] and save it as dueValue.Trim projectRow.properties["Due date"] and save it as dueValue.
ListsGet the first item of the first item of dueValue split by a space split by T and save it as dueDay.Get the first item of the first item of dueValue split by a space split by T and save it as dueDay.
Decisions & LoopsIf the length of dueDay is 10 and dueDay contains -If the length of dueDay is 10 and dueDay contains -
Yes
ValuesChange dueDate to dueDay.Change dueDate to dueDay.
No
No steps
On error
ValuesChange dueDate to blank.Change dueDate to blank.
ValuesSet projectLink to blank.Set projectLink to blank.
Decisions & LoopsIf a step below fails, save the error as linkErrorIf a step below fails, save the error as linkError
Try
TextTrim projectRow.url and save it as projectLink.Trim projectRow.url and save it as projectLink.
On error
ValuesChange projectLink to blank.Change projectLink to blank.
ValuesSet taskNotes to Broken out of your Notion planning database..Set taskNotes to Broken out of your Notion planning database..
Decisions & LoopsIf projectLink isn't emptyIf projectLink isn't empty
Yes
ValuesChange taskNotes to Broken out of your Notion planning database: projectLink.Change taskNotes to Broken out of your Notion planning database: projectLink.
No
No steps
ValuesSet parentTaskId to blank.Set parentTaskId to blank.
Decisions & LoopsIf a step below fails, save the error as createErrorIf a step below fails, save the error as createError
Try
AsanaAsanaCreate task projectName. Save it as createdTask.Create task projectName. Save it as createdTask. Due date: dueDatetaskNotes
TextTrim createdTask.gid and save it as parentTaskId.Trim createdTask.gid and save it as parentTaskId.
On error
ValuesShow in the output: Could not create the Asana task for the Notion row '@projectName': createError.message The row was left unmarked, so it is picked up again on the next run.Show in the output: Could not create the Asana task for the Notion row '@projectName': createError.message The row was left unmarked, so it is picked up again on the next run.
Decisions & LoopsIf parentTaskId isn't emptyIf parentTaskId isn't empty
Yes
Decisions & LoopsFor each step in steps:For each step in steps:
Decisions & Loops If a step below fails, save the error as subtaskError If a step below fails, save the error as subtaskError
Try
AsanaAsanaCreate subtask step under task parentTaskId.Create subtask step under task parentTaskId.
On error
ValuesSet subtaskFailure to Created the Asana task for '@projectName' but could not add the subtask '@step': subtaskError.message.Set subtaskFailure to Created the Asana task for '@projectName' but could not add the subtask '@step': subtaskError.message.
ValuesSet subtaskAdvice to The run stopped there and the Notion row was left unmarked, so this project is built again from scratch on the next run - delete the half-built task in Asana first..Set subtaskAdvice to The run stopped there and the Notion row was left unmarked, so this project is built again from scratch on the next run - delete the half-built task in Asana first..
Decisions & LoopsStop and report a problem: subtaskFailure plus subtaskAdvice.Stop and report a problem: subtaskFailure plus subtaskAdvice.
Decisions & LoopsIf a step below fails, save the error as writeBackErrorIf a step below fails, save the error as writeBackError
Try
NotionNotionUpdate projectRow.Update projectRow.
ValuesAdd 1 to createdCount.Add 1 to createdCount.
On error
ValuesSet writeBackFailure to Broke the Notion row '@projectName' out into Asana but could not record the task id on that row: writeBackError.message.Set writeBackFailure to Broke the Notion row '@projectName' out into Asana but could not record the task id on that row: writeBackError.message.
ValuesSet writeBackAdvice to The run stopped there rather than send the rest of the database across twice. Check that the database has a text property named exactly 'Asana task' that Lodol is allowed to edit..Set writeBackAdvice to The run stopped there rather than send the rest of the database across twice. Check that the database has a text property named exactly 'Asana task' that Lodol is allowed to edit..
Decisions & LoopsStop and report a problem: writeBackFailure plus writeBackAdvice.Stop and report a problem: writeBackFailure plus writeBackAdvice.
No
No steps
ValuesShow in the output: Broke createdCount planned project(s) out of Notion into Asana tasks with subtasks.Show in the output: Broke createdCount planned project(s) out of Notion into Asana tasks with subtasks.