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.