Vikunja to n8n to NTFY

:information_source: I use this setup to get notified about a task when they are due, You can tinker with it to make NTFY trigger multiple ways, please message me if you need help with this.

Setting up n8n

I cribbed off the compose with Postgres from n8n for my instance, feel free to reach out to me if you need help.

  • After getting your account setup, head over to the side bar >Settings >Community Nodes > Install
    • add the following community nodes
    • @jyln/n8n-nodes-ntfy
    • n8n-nodes-vikunja

Get your Vikunja API Key

Bearer token into n8n

Head back over to n8n Credentials page and add your NTFY Bearer token just like you did for Vikunja.

Setting up the workflow

Getting the workflow to trigger was easy, just add your Vikunja Trigger, I use On Task Created and link it to my NTFY:

I use the Project ID instead of the name because I couldn’t search by name, sure this is something to do with my setup.

Next, I want to get notified when the task is due, which means doing a bit of date math:

Time relative notifications

currently, the way I have my workflow set, NTFY reminds me as the task is due, I am working on getting a notification 15 minutes before, but have been hitting some logic blocks. UPDATE: I solved this

Setting a reminder 15m before

Just add an * Edit Fields* in your switch that is using a delay, and drag in timeDifference.seconds and edit your formula to reflect the following:

  • {{( $json.timeDifference.seconds - 900)}}

This sets the delay to 15 minutes before the time set.

Sending and Action Buttons

Finally, we send the notification to NTFY for our tasks. But wait! why don’t we add a button to automatically complete the task?!

Just click the Add Option button and select Click Action

this is just doing a HTTP Request to complete your tasks, docs on it here

Action

  • The action should be set to HTTP to send requests

URL

  • The URL should be https://tasks.tld/tasks/{{ $('Vikunja Trigger').item.json.data.task.id }} or similar when dragging choices in.

Label

Use what you want here, I like to keep it simple with Complete Task

Clear

when set to true this will clear the notification from your topic when the action button is selected

I leave this option unchecked, as I had issues with iOS when having it set

Headers

I had trouble getting this setup, but after inspecting the network when doing test notifications from multiple services, I came up with the following needed in my Headers:

{
"accept": "*/*",
    "accept-language": "en-US,en;q=0.9",
    "authorization": "Bearer API_KEY_FROM_VIKUNJA",
    "content-type": "application/json",
    "priority": "u=1, i"
}

Body

In order to complete the task, you need to add the folowing to your body as well

{"done" : true}

The View Button

Maybe I just want to look at the task in Vikunja directly from NTFY, easy, just add a view button, just add another option and use the following:

Action

  • View

Label

  • View Task

URL

  • https://tasks.tld/projects/{{ $('Vikunja Trigger').item.json.data.task.project_id }}/{{ $('Vikunja Trigger').item.json.data.task.id }}

The final product

In the end, I create a task, and

Boom

1 Like

Wow, looks awesome! Could you share the json of n8n workflow?

I will export and scrub my json for sharing tonight! :call_me_hand::call_me_hand:

I’m having some trouble getting the Vikunja integration in n8n working. I put in the url and then when listening for an event it just never finishes. Any assistance on the matter would be greatly appreciated!

If it’s based off get new task or similar you may have to create/update the task to start the flow when testing, I believe this is how I have mine working when testing

1 Like

@Onufry Here you are!

Json for n8n
{
  "name": "Vikunja NTFY copy",
  "nodes": [
    {
      "parameters": {
        "project": 4,
        "events": [
          "task.created"
        ]
      },
      "id": "71f7c994-fa52-4845-9f04-ecbcf424c554",
      "name": "Vikunja Trigger",
      "type": "n8n-nodes-vikunja.vikunjaTrigger",
      "typeVersion": 1,
      "position": [
        440,
        640
      ],
      "webhookId": "13b8021e-9174-4125-879a-d6f21463550e",
      "credentials": {
        "vikunjaApi": {
          "id": "7bg2fUUIdtORa2Ac",
          "name": "Vikunja account"
        }
      }
    },
    {
      "parameters": {
        "useCustomServer": true,
        "serverUrl": "https://ntfy.tld",
        "topic": "test",
        "title": "={{ $('Vikunja Trigger').item.json.data.task.title }}",
        "message": "=",
        "additionalOptions": {
          "actions": {
            "actionButtons": [
              {
                "action": "http",
                "label": "Complete Task",
                "url": "=https://vikunja.tld/api/v1/tasks/{{ $('Vikunja Trigger').item.json.data.task.id }}",
                "sendHeaders": true,
                "headersJson": "{\"accept\": \"*/*\",\n    \"accept-language\": \"en-US,en;q=0.9\",\n    \"authorization\": \"Bearer tk_ apiTkHere\",\n    \"content-type\": \"application/json\",\n    \"priority\": \"u=1, i”}",
                "sendBody": true,
                "bodyJson": "{\"done\" : true}"
              },
              {
                "label": "view tasks",
                "url": "=https://vikunja.tld/projects/ {{ $('Vikunja Trigger').item.json.data.task.project_id }}/{{ $('Vikunja Trigger').item.json.data.task.id }}"
              }
            ]
          },
          "delay": "={{ $json.timeDifference.seconds }}s"
        }
      },
      "id": "1ee44262-3255-446e-9b2f-4055fd948395",
      "name": "NTFY",
      "type": "@jyln/n8n-nodes-ntfy.ntfy",
      "typeVersion": 1,
      "position": [
        1340,
        460
      ],
      "credentials": {
        "ntfyApi": {
          "id": "RHQC718v8b2JAxNM",
          "name": "NTFY account"
        }
      }
    },
    {
      "parameters": {
        "height": 370.36494824925626,
        "width": 576.4489346748361,
        "color": 6
      },
      "id": "3f0afe18-7441-4123-a6b5-6fe010ef73d0",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1080,
        320
      ]
    },
    {
      "parameters": {
        "useCustomServer": true,
        "serverUrl": "https://ntfy.tld",
        "topic": "test",
        "title": "={{ $('Vikunja Trigger').item.json.data.task.title }}",
        "message": "={{ $('Vikunja Trigger').item.json.data.task.description }}",
        "additionalOptions": {
          "actions": {
            "actionButtons": [
              {
                "action": "http",
                "label": "Complete Task",
                "url": "=https://vikunja.tld/api/v1/tasks/{{ $('Vikunja Trigger').item.json.data.task.id }}",
                "sendHeaders": true,
                "headersJson": "{\"accept\": \"*/*\",\n    \"accept-language\": \"en-US,en;q=0.9\",\n    \"authorization\": \"Bearer tk_apiTkHere”,\n    \"content-type\": \"application/json\",\n    \"priority\": \"u=1, i\"}",
                "sendBody": true,
                "bodyJson": "{\"done\" : true}"
              },
              {
                "label": "view task",
                "url": "=https://vikunja.tld/projects/ {{ $('Vikunja Trigger').item.json.data.task.project_id }}/{{ $('Vikunja Trigger').item.json.data.task.id }}"
              }
            ]
          }
        }
      },
      "id": "25f6d8f8-6420-409b-b1c0-9c32e9c7b159",
      "name": "NTFY1",
      "type": "@jyln/n8n-nodes-ntfy.ntfy",
      "typeVersion": 1,
      "position": [
        1180,
        760
      ],
      "credentials": {
        "ntfyApi": {
          "id": "RHQC718v8b2JAxNM",
          "name": "NTFY account"
        }
      }
    },
    {
      "parameters": {
        "options": {

        }
      },
      "id": "d85366eb-7839-46bb-a696-bf945ed39fab",
      "name": "current date",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 2,
      "position": [
        580,
        460
      ]
    },
    {
      "parameters": {
        "operation": "getTimeBetweenDates",
        "startDate": "={{ $json.time }}",
        "endDate": "={{ $json.data.task.due_date }}",
        "units": [
          "second"
        ],
        "options": {

        }
      },
      "id": "b3aa6ac3-8645-4cbd-a725-4c3114c35033",
      "name": "Now - due",
      "type": "n8n-nodes-base.dateTime",
      "typeVersion": 2,
      "position": [
        720,
        640
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "2a47237b-7183-4638-94be-707917696bd0",
              "name": "timeDifference.seconds",
              "value": "={{( $json.timeDifference.seconds - 900)}} ",
              "type": "number"
            }
          ]
        },
        "options": {
          "ignoreConversionErrors": false
        }
      },
      "id": "1a5d989c-0de0-4b11-8331-e25d3989db26",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1120,
        540
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.timeDifference.seconds}}",
                    "rightValue": 1200,
                    "operator": {
                      "type": "number",
                      "operation": "gt"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": "={{ false }}"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "f47699ec-abb2-4168-95ad-a07da3f9c304",
                    "leftValue": "={{ $json.timeDifference.seconds }}",
                    "rightValue": 1200,
                    "operator": {
                      "type": "number",
                      "operation": "lt"
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {

        }
      },
      "id": "08a433a9-de99-4322-b767-fef5d4e4c188",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        880,
        640
      ]
    }
  ],
  "pinData": {

  },
  "connections": {
    "Vikunja Trigger": {
      "main": [
        [
          {
            "node": "Now - due",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "current date": {
      "main": [
        [
          {
            "node": "Now - due",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Now - due": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "NTFY",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "NTFY1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "60c4fbfd-8ebe-495e-9c09-1e496299c51b",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "e234f4c89e392d674e3c354223ae632a20577144675556cd9aa0143889358002"
  },
  "id": "vDZKS1JHhkzkZZob",
  "tags": [

  ]
}
1 Like