Describe the issue/error/question
I am trying to sync Gitlab issues with Todoist tasks.
- Create Gitlab issue → Todoist create task works.
- Close Gitlab issue → Close Todoist task also works
However since there is no update API for Todoist, once a Gitlab issue is created, I attach the Gitlab project ID to the Todoist task description. Then when a Gitlab issue gets updated, I retrieve all Todoist tasks, search their description for the relevant Gitlab ID, and once I get those I delete them (if for some reason/ problem there are multiple Todoist tasks created) and create a new one with the updated info.
My problem is that updating a Gitlab issue sometimes results in double Todoist task IDs and I would love some feedback from you to fix it and ideally refactor my workflow to make it more efficient.
The workflow I currently use
{
"nodes": [
{
"parameters": {},
"name": "Start",
"type": "n8n-nodes-base.start",
"typeVersion": 1,
"position": [
460,
-20
]
},
{
"parameters": {
"owner": "",
"repository": "",
"events": [
"issues"
]
},
"name": "Gitlab Trigger",
"type": "n8n-nodes-base.gitlabTrigger",
"position": [
60,
80
],
"webhookId": "459081ce-f254-44b2-925a-a078007f36c5",
"typeVersion": 1,
"credentials": {
"gitlabApi": {
"id": "3",
"name": "Gitlab account 2"
}
}
},
{
"parameters": {
"functionCode": "return item;"
},
"name": "the_gitlab_event",
"type": "n8n-nodes-base.functionItem",
"typeVersion": 1,
"position": [
360,
360
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$node[\"the_gitlab_event\"].json[\"body\"][\"object_attributes\"][\"action\"]}}",
"operation": "contains",
"value2": "open"
}
]
}
},
"name": "action_is_open_reopen",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
540,
700
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$node[\"the_gitlab_event\"].json[\"body\"][\"object_attributes\"][\"action\"]}}",
"value2": "close"
}
]
}
},
"name": "action_is_close",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
540,
180
]
},
{
"parameters": {
"authentication": "oAuth2",
"project": 2290715561,
"content": "=[{{$node[\"the_gitlab_event\"].json[\"body\"][\"object_attributes\"][\"title\"]}}]({{$node[\"the_gitlab_event\"].json[\"body\"][\"object_attributes\"][\"url\"]}})",
"options": {
"description": "=gitlab_issue_id: {{$node[\"the_gitlab_event\"].json[\"body\"][\"object_attributes\"][\"id\"]}}",
"dueDateTime": "={{$node[\"the_gitlab_event\"].json[\"body\"][\"object_attributes\"][\"due_date\"]}}"
}
},
"name": "create_task",
"type": "n8n-nodes-base.todoist",
"position": [
1700,
580
],
"typeVersion": 1,
"credentials": {
"todoistOAuth2Api": {
"id": "4",
"name": "Todoist account"
}
}
},
{
"parameters": {
"authentication": "oAuth2",
"operation": "delete",
"taskId": "={{$node[\"filter_todoist_tasks_by_gitlab_issue_id\"].json[\"id\"]}}"
},
"name": "delete_task",
"type": "n8n-nodes-base.todoist",
"position": [
1700,
380
],
"typeVersion": 1,
"credentials": {
"todoistOAuth2Api": {
"id": "4",
"name": "Todoist account"
}
}
},
{
"parameters": {
"authentication": "oAuth2",
"operation": "close",
"taskId": "={{$node[\"filter_todoist_tasks_by_gitlab_issue_id1\"].json[\"id\"]}}"
},
"name": "close_task",
"type": "n8n-nodes-base.todoist",
"position": [
1580,
-80
],
"typeVersion": 1,
"credentials": {
"todoistOAuth2Api": {
"id": "4",
"name": "Todoist account"
}
}
},
{
"parameters": {
"owner": "",
"repository": "",
"events": [
"issues"
]
},
"name": "Gitlab Trigger1",
"type": "n8n-nodes-base.gitlabTrigger",
"position": [
60,
360
],
"webhookId": "fe3eac42-fba2-43fe-b30b-2f37bcef3e38",
"typeVersion": 1,
"credentials": {
"gitlabApi": {
"id": "3",
"name": "Gitlab account 2"
}
}
},
{
"parameters": {
"owner": "",
"repository": "",
"events": [
"issues"
]
},
"name": "Gitlab Trigger2",
"type": "n8n-nodes-base.gitlabTrigger",
"position": [
60,
640
],
"webhookId": "319272f8-6260-4a95-a390-5ef55557d254",
"typeVersion": 1,
"credentials": {
"gitlabApi": {
"id": "3",
"name": "Gitlab account 2"
}
}
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$node[\"the_gitlab_event\"].json[\"body\"][\"object_attributes\"][\"action\"]}}",
"value2": "update"
}
]
}
},
"name": "action_is_update",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
540,
360
]
},
{
"parameters": {
"functionCode": "return [{json: {empty: items.length == 1 && Object.keys(items[0].json).length == 0}}];"
},
"name": "tasks_found",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
1140,
60
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json[\"empty\"]}}",
"operation": "notEqual",
"value2": true
}
],
"number": []
}
},
"name": "task_exists",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1320,
60
]
},
{
"parameters": {
"functionCode": "return [{json: {empty: items.length == 1 && Object.keys(items[0].json).length == 0}}];"
},
"name": "tasks_found1",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
1160,
260
]
},
{
"parameters": {
"authentication": "oAuth2",
"operation": "getAll",
"returnAll": true,
"filters": {
"projectId": 2290715561
}
},
"name": "get_all_open_tasks",
"type": "n8n-nodes-base.todoist",
"position": [
800,
340
],
"typeVersion": 1,
"alwaysOutputData": true,
"credentials": {
"todoistOAuth2Api": {
"id": "4",
"name": "Todoist account"
}
}
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json[\"empty\"]}}",
"operation": "notEqual",
"value2": true
}
],
"number": []
}
},
"name": "task_exists1",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1380,
260
]
},
{
"parameters": {
"functionCode": "const filtered_tasks = [];\nfor (item of items) {\n if (item.json.description.includes(\"gitlab_issue_id: \" + $node[\"the_gitlab_event\"].json.body.object_attributes.id)) {\n filtered_tasks.push(item);\n }\n}\nreturn filtered_tasks;"
},
"name": "filter_todoist_tasks_by_gitlab_issue_id",
"type": "n8n-nodes-base.function",
"position": [
980,
260
],
"typeVersion": 1,
"alwaysOutputData": true
},
{
"parameters": {
"authentication": "oAuth2",
"operation": "getAll",
"returnAll": true,
"filters": {
"projectId": 2290715561
}
},
"name": "get_all_open_tasks1",
"type": "n8n-nodes-base.todoist",
"position": [
800,
120
],
"typeVersion": 1,
"alwaysOutputData": true,
"credentials": {
"todoistOAuth2Api": {
"id": "4",
"name": "Todoist account"
}
}
},
{
"parameters": {
"functionCode": "const filtered_tasks = [];\nfor (item of items) {\n if (item.json.description.includes(\"gitlab_issue_id: \" + $node[\"the_gitlab_event\"].json.body.object_attributes.id)) {\n filtered_tasks.push(item);\n }\n}\nreturn filtered_tasks;"
},
"name": "filter_todoist_tasks_by_gitlab_issue_id1",
"type": "n8n-nodes-base.function",
"position": [
980,
80
],
"typeVersion": 1,
"alwaysOutputData": true
},
{
"parameters": {
"authentication": "oAuth2",
"operation": "getAll",
"returnAll": true,
"filters": {
"projectId": 2290715561
}
},
"name": "get_all_open_tasks2",
"type": "n8n-nodes-base.todoist",
"position": [
800,
720
],
"typeVersion": 1,
"alwaysOutputData": true,
"credentials": {
"todoistOAuth2Api": {
"id": "4",
"name": "Todoist account"
}
}
},
{
"parameters": {
"functionCode": "const filtered_tasks = [];\nfor (item of items) {\n if (item.json.description.includes(\"gitlab_issue_id: \" + $node[\"the_gitlab_event\"].json.body.object_attributes.id)) {\n filtered_tasks.push(item);\n }\n}\nreturn filtered_tasks;"
},
"name": "filter_todoist_tasks_by_gitlab_issue_id2",
"type": "n8n-nodes-base.function",
"position": [
980,
720
],
"typeVersion": 1,
"alwaysOutputData": true
},
{
"parameters": {
"functionCode": "return [{json: {empty: items.length == 1 && Object.keys(items[0].json).length == 0}}];"
},
"name": "tasks_found2",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
1160,
720
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json[\"empty\"]}}",
"operation": "notEqual",
"value2": true
}
],
"number": []
}
},
"name": "task_exists2",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1340,
720
]
}
],
"connections": {
"Gitlab Trigger": {
"main": [
[
{
"node": "the_gitlab_event",
"type": "main",
"index": 0
}
]
]
},
"the_gitlab_event": {
"main": [
[
{
"node": "action_is_update",
"type": "main",
"index": 0
},
{
"node": "action_is_close",
"type": "main",
"index": 0
},
{
"node": "action_is_open_reopen",
"type": "main",
"index": 0
}
]
]
},
"action_is_open_reopen": {
"main": [
[
{
"node": "get_all_open_tasks2",
"type": "main",
"index": 0
}
]
]
},
"action_is_close": {
"main": [
[
{
"node": "get_all_open_tasks1",
"type": "main",
"index": 0
}
]
]
},
"delete_task": {
"main": [
[
{
"node": "get_all_open_tasks",
"type": "main",
"index": 0
}
]
]
},
"Gitlab Trigger1": {
"main": [
[
{
"node": "the_gitlab_event",
"type": "main",
"index": 0
}
]
]
},
"Gitlab Trigger2": {
"main": [
[
{
"node": "the_gitlab_event",
"type": "main",
"index": 0
}
]
]
},
"action_is_update": {
"main": [
[
{
"node": "get_all_open_tasks",
"type": "main",
"index": 0
}
]
]
},
"tasks_found": {
"main": [
[
{
"node": "task_exists",
"type": "main",
"index": 0
}
]
]
},
"task_exists": {
"main": [
[
{
"node": "close_task",
"type": "main",
"index": 0
}
]
]
},
"tasks_found1": {
"main": [
[
{
"node": "task_exists1",
"type": "main",
"index": 0
}
]
]
},
"get_all_open_tasks": {
"main": [
[
{
"node": "filter_todoist_tasks_by_gitlab_issue_id",
"type": "main",
"index": 0
}
]
]
},
"task_exists1": {
"main": [
[
{
"node": "delete_task",
"type": "main",
"index": 0
}
],
[
{
"node": "create_task",
"type": "main",
"index": 0
}
]
]
},
"filter_todoist_tasks_by_gitlab_issue_id": {
"main": [
[
{
"node": "tasks_found1",
"type": "main",
"index": 0
}
]
]
},
"get_all_open_tasks1": {
"main": [
[
{
"node": "filter_todoist_tasks_by_gitlab_issue_id1",
"type": "main",
"index": 0
}
]
]
},
"filter_todoist_tasks_by_gitlab_issue_id1": {
"main": [
[
{
"node": "tasks_found",
"type": "main",
"index": 0
}
]
]
},
"get_all_open_tasks2": {
"main": [
[
{
"node": "filter_todoist_tasks_by_gitlab_issue_id2",
"type": "main",
"index": 0
}
]
]
},
"filter_todoist_tasks_by_gitlab_issue_id2": {
"main": [
[
{
"node": "tasks_found2",
"type": "main",
"index": 0
}
]
]
},
"tasks_found2": {
"main": [
[
{
"node": "task_exists2",
"type": "main",
"index": 0
}
]
]
},
"task_exists2": {
"main": [
null,
[
{
"node": "create_task",
"type": "main",
"index": 0
}
]
]
}
}
}
```