Feedback on Self-Hosting and Using n8n

Feedback on Self-Hosting and Using n8n

Today, I self-hosted n8n to explore its capabilities. The self-hosting process was straightforward, and I was looking at this tool for various automation use cases within our organization.

To test its functionality, I set up a simple workflow where n8n would collect issue details and create a Jira ticket. This use case is highly relevant to our organization, as manually setting it up via our admin portal and Jira API integration would have taken approximately 4-5 hours. Configuring credentials for both Jira and AWS was seamless.

However, challenges arose when I attempted to upload a file to AWS S3. It took me nearly six hours to figure out the correct approach for handling binary file uploads, a task that would have been much faster had I implemented it directly in the backend.

Areas for Improvement

  1. Limited Documentation Beyond Installation – While setting up the tool was well-documented, deeper workflow concepts and advanced configurations lacked sufficient guidance.
  2. Unclear Data Flow – Despite successfully completing the workflow, I still find the data flow within n8n difficult to comprehend fully.

Challenges Encountered

  • Uploading binary data to AWS S3 – The process was not intuitive and required extensive troubleshooting.
  • Aggregating multiple URLs into a single string – I struggled to collect and format multiple image URLs effectively.
  • Unexpected Ticket Creation Behavior – When uploading six images, n8n created six separate Jira tickets instead of associating all images with a single ticket. This was unexpected and required additional workarounds.

Final Thoughts

While n8n is a promising automation tool, my expectation was that a non-technical team member, such as a PM, could handle some of the automation tasks to reduce the load on the tech team. However, I ended up writing a significant amount of code, which somewhat defeated the purpose of using a no-code/low-code platform.

I am attaching my workflow diagram and would appreciate any insights on whether I have unnecessarily overcomplicated the setup.

code block 1

// Extract all binary fields dynamically
const items = $input.all();
let newItems = [];

for (const item of items) {
    if (item.binary) {
      
        for (const key in item.binary) {
          
           let fileName = `${key}.${item.binary[key]["fileExtension"]}`;         
          console.log("fileName",fileName)
            newItems.push({
             
                json: {
                   fileName:fileName,
                  ...item.json,
                    url:`https://example.com/jira-tickets/${fileName}`,
                },
              
                binary: {
                    data: item.binary[key]
                }
            });
        }
    }
}

return newItems;

Code Block 2

const items = $input.all();
let mergedItem = {
    json: {
        email:"",
    issueTitle:"",
    issueDescription:"",
    project:"",
    reportedBy:"",
    partnerId:"",
        fileNames: [],
        urls: [],
    },
    binary: {}
};

for (const item of items) {
    for (const key in item.binary) {
        let fileName = `${key}.${item.binary[key]["fileExtension"]}`;
        mergedItem.json.email = item.json.Email;
        mergedItem.json.issueTitle = item.json['Issue Title'];
        mergedItem.json.issueDescription = item.json['Issue Description'];
        mergedItem.json.project = item.json["Project"];
        mergedItem.json.reportedBy = item.json[
          "Reported By"
        ]
      mergedItem.json.partnerId = item.json[
        "Partner Id"
      ]
        mergedItem.json.fileNames.push(fileName);
        mergedItem.json.urls.push(`https://dlxpk8rzj7ccz.cloudfront.net/jira-tickets/${fileName}`);

        mergedItem.binary[key] = item.binary[key]; // Preserve binary data
    }
}

// Return a single item that contains all files
return [mergedItem];