N8N is amazing! Thank you!

Hi n8n Team, thank you for this amazing product, it’s the sh** (with a very long I for viewers of “The Wire”)
Even for people doing a lot of dev work and capable of coding and integrating API, n8n is a game changer.
You can play around with ideas very quickly and once everything seems to work your way you can still decide to turn it into code but also just leave it as it is and enjoy the flexibility of n8n.
But the start wasn’t easy, first mit ruby thinking probably got in the way and I didn’t understand how to manipulate some of the data to get it how n8n expects it. Probably reading more before playing with n8n would have helped but then also where do you start reading?
Here are a few things I have built and where I had issues

Here is what this does, it fetches via HTTP Request alle Tickets that have been tagged in our Ticketing system (zammad), I then check if these tickets have attached files and if these files match what I am looking for, if not, a comment is added in the ticketing system and the ticket is assigned to first level support to clarify.
If attachment is there, the file is downloaded, written to a file and sent to two different system via HTTP POST request.
If the Upload was ok, the result from the upload is added to the ticket and the ticket is closed, if not the error is added to the ticket and ticket assigned to first level.

Here is what I have struggled with, the ticketing system returns everything in an array, so for n8n it looked like it was just one item and I was not able to access all entries from the array.
But reading a few posts here I got the “Map Ticket” function working

{
  "nodes": [
    {
      "parameters": {
        "functionCode": "return items[0].json.map(item => {\n  return {\n    json: item\n  }\n});\n"
      },
      "name": "Map Tickets",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        450,
        680
      ]
    }
  ],
  "connections": {}
}

this finally made my nodes go through every ticket and not just one item.
The filtering also was a bit of trial and error but in the end I came up with some regex

{
  "nodes": [
    {
      "parameters": {
        "functionCode": "const data = {}\n//data.json = {}\n\nconst regex = /info_(foo|bar)_(\\d{2})_KW(\\d{1,2})_(\\d{2})/i;\nitem[0].attachments.forEach(function(attachment) {\n  data.ticket_id = item[0].ticket_id;\n  data.article_id = item[0].id;\n  data.filename = attachment.filename;\n  data.valid = false;\n  var found = attachment.filename.match(regex);\n  if (found) {\n    data.attachment_id = attachment.id;\n    data.filename = attachment.filename;\n    data.mime_type = attachment[\"preferences\"][\"Mime-Type\"];\n    data.valid = true;\n  }\n});\nreturn data;\n\n"
      },
      "name": "Filter Attachments",
      "type": "n8n-nodes-base.functionItem",
      "typeVersion": 1,
      "position": [
        800,
        680
      ]
    }
  ],
  "connections": {}
}

this adds a valid = true value if the file name matches what I need and I can use this later on in the IF to decide what to do later.
Another thing I struggled with was uploading a file via HTTP Post, a file I have initially downloaded and written to disk with the write binary file.
I ended up using the command node + curl to do the upload

curl -s -X "POST" ... -F "attachment=@\"{{$node["Write Attachment"].json["fileName"]}}\";type={{$node["Write Attachment"].json["mime_type"]}}" \

for this to work in the docker environment I had to install curl, which wasn’t that hard.
created a new Dockerfile

FROM n8nio/n8n

RUN apk --update add curl

changed my docker-compose to use my new n8n+curl

  n8n:
    image: n8n-curl

pull & build

docker pull n8nio/n8n
docker build -t n8n-curl .

One thing I could not figure out how to do is just log in once to the systems where the file is uploaded. I use the set node to define the URL + token and then do a http request with data from this set node.
If I would put the set node right at the start where it ran only once, any access to the data from set would not work anymore if I had multiple runs of the HTTP Request for the login, even if I select that it should run only once.

But since these n8n workflows are kind of addictive, why not do the informational logging via n8n?

The external systems where the files are uploaded, already work with rabbitMQ, so I created a few new queues where n8n listens, if something comes into that queue it either generates a support ticket or creates a slack message and if everything was ok, it uses the ticket id from the first workflow to find the initial ticket and document the process and any errors that occurred during the processing of the files.
I know I could have went with just one queue + switch, it actually is what I did in the beginning, but there as an issue with rabbitMQ overwriting messages which was fixed a few days ago so I now stuck with this setup.

So once again, thank you n8n team! This is really awesome.

8 Likes

Thanks a lot for this great write up! Glad to hear you’re also enjoying n8n :slight_smile:

Your points above are clear and can happily say most of these are something that we’ve got on our backlog to improve (like data transform nodes).

I want to make sure I completely understand each of your points though. For the set node issue, are you saying you can’t set it at the beginning of the flow because of the IF nodes? If that is the case, my strategy is to append relevant data to each item so that they’re “along for the ride” no matter which conditional route the data item takes (you can technically reference data from before a If node, but then have an index offset issue). Is that the scenario you experienced? If not, would be awesome if you could give a bit more detail on that one.

Lastly, seeing awesome workflows like your above usecase is very insightful AND motivational - so thanks for sharing!

1 Like

@crislyour post is amazing. It’s hard to exaggerate how helpful it is to see what you’ve managed to build with n8n, and especially where things were perhaps a little harder than they should have been. As Max said, this is perfect timing because we’re currently thinking about how data transformations should work.

We’d love to learn a little more about your experience with n8n — I’m sure you have some more insights that would help us improve the product! Will DM you :slight_smile:

2 Likes

I tried to write down some things I’ve stumbled over, but not sure in which of the gazzilion note taking Apps I wrote it or if I just planned to write it :)) only found the s3 issues I had (used it in a different workflow).

@maxT no, my problem with the “set” node is following:

I set the URL + Token in the SET node, this happens once, after that I used to have the login via http request which returns a token (this is not visible in the current screenshot)

Then I get the tickets, let’s say I get a list of 5 Tickets. The nodes for uploading the file is then called 5 times because there are 5 tickets which is great. But the Problem ist that the first run of the http request for the upload (which uses the token from the http login) works, but the second to fifth ones would fail because it’s trying to get the second to fifth (I assume it does that) token of the login node which is empty because the http login runs only once.

But thinking of it now as I am writing this … I assume I should just use a second set node to set the token and access that token from the set node in the file upload. :thinking:

First thanks a lot for sharing this @crisl and great to hear that you enjoy n8n!

To your problem. It is identical to the question I did just answer here.

2 Likes