{"workflow":{"id":14338,"name":"Review GitLab merge requests with parallel Azure OpenAI reviewers","views":0,"recentViews":0,"totalViews":0,"createdAt":"2026-03-26T02:27:20.445Z","description":"## Who this template is for\n\nThis template is for teams that use GitLab merge requests and want a practical AI-assisted review workflow in n8n. It is useful for engineering teams that want faster first-pass reviews, consistent review comments, and a simple way to separate likely bugs, security risks, and maintainability issues before a human reviewer takes over.\n\n## How it works\n\nThis workflow starts when a user posts a trigger comment in a GitLab merge request discussion. It loads the merge request changes, splits the diff into one item per changed file, and skips files that are not suitable for inline review.\n\nEach file is then reviewed in parallel by three AI reviewers focused on bugs, security, and maintainability. Their findings are merged and sent to a verifier step, which removes weak or duplicate findings and normalizes severity and confidence.\n\nOnly findings that pass the configured confidence threshold are posted. If a valid GitLab diff position can be resolved, the workflow creates an inline review comment. Otherwise, it falls back to a reply comment in the trigger discussion. A summary reply is also posted to mark the review as completed.\n\n## Set up\n\nSetup usually takes around 10 to 20 minutes.\n\nYou will need:\n- a GitLab access token with permission to read merge requests and post discussions\n- one or more AI model credentials for the reviewer and verifier steps\n- your GitLab base URL and preferred trigger comment\n- a minimum confidence threshold for posting findings\n\nMost detailed setup guidance is included directly in the sticky notes inside the workflow.\n\n## Requirements\n\n- GitLab project with merge request discussions enabled\n- n8n credentials for GitLab API access\n- AI chat model credentials for the reviewer and verifier nodes\n\n## How to customize the workflow\n\nYou can change the trigger comment, GitLab base URL, and minimum confidence threshold in the configuration section.\n\nYou can also customize:\n- which findings are posted by adjusting the confidence threshold\n- reviewer prompts for bug, security, and maintainability analysis\n- the final verifier behavior for severity, confidence, and duplicate handling\n- the fallback behavior for findings that cannot be mapped to a valid inline diff position","workflow":{"id":"3y8HmuJr5BXYuHGo","meta":{"instanceId":"8dd3ba08d4bb15bbfd736f08ff517e812636be912add57cd0b192b9f99a9142f","templateCredsSetupCompleted":true},"name":"Review GitLab merge requests with parallel AI reviewers","tags":[],"nodes":[{"id":"7b4c951f-df41-479b-894b-a2807530a58f","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[-3120,-384],"parameters":{"width":768,"height":848,"content":"## How it works\n\nThis workflow runs an AI-assisted review for GitLab merge requests.\n\nWhen a reviewer posts the trigger comment in a merge request discussion, the workflow fetches the changed files, filters unsupported diffs, and prepares review context for each file.\n\nEach changed file is analyzed in parallel by three reviewers:\n- Bug reviewer\n- Security reviewer\n- Maintainability reviewer\n\nTheir findings are merged and then checked by a verifier, which removes weak, duplicate, or pre-existing issues.\n\nVerified findings that pass the posting checks can be posted as inline GitLab comments.\nA separate summary reply is posted back to the original trigger discussion.\n\n## Setup\n\nBefore using this template:\n\n- Connect your GitLab credential\n- Connect your LLM credential\n- Update the values in **Workflow Configuration** for your environment:\n  - GitLab base URL\n  - Review trigger phrase\n  - Start / summary / no-issues messages\n  - Minimum confidence required for posting. \n- Review the prompts and model settings used by each reviewer and the verifier\n- Test the workflow on a sample merge request discussion before enabling it\n\nThe verifier assigns a confidence score to each finding.\nOnly findings with status=keep and final_confidence at or above this threshold are posted. \nFindings with a resolved inline position are posted as inline comments; otherwise they are posted as reply comments.\n\nLower threshold values increase recall but may allow more false positives.\nHigher threshold values are stricter and may suppress borderline findings."},"typeVersion":1},{"id":"e8c95236-4071-43ce-926f-4fa1a7c50dd1","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[-2256,0],"parameters":{"color":7,"width":880,"height":448,"content":"## Trigger the review\n\nPost the configured trigger comment in a GitLab merge request discussion to start the workflow.\n\nDefault trigger: `+0`\nChange it in **Workflow Configuration**."},"typeVersion":1},{"id":"3529266d-af18-4585-989b-01af994b9c18","name":"Sticky Note4","type":"n8n-nodes-base.stickyNote","position":[-1312,-112],"parameters":{"color":7,"width":800,"height":560,"content":"## Fetch and filter changed files\n\nLoad the merge request changes, split them into one file per item, and skip unsupported diffs such as renamed, deleted, or non-commentable files."},"typeVersion":1},{"id":"a3ada654-1ded-4275-8d84-ed3b6e5b3f61","name":"GitLab Discussion Webhook","type":"n8n-nodes-base.webhook","position":[-2160,240],"webhookId":"8a1a0ef5-a1ab-49e0-9cd5-321d0c4bc080","parameters":{"path":"8a1a0ef5-a1ab-49e0-9cd5-321d0c4bc080","options":{},"httpMethod":"POST"},"typeVersion":2},{"id":"8dbf3590-f83f-437e-bcca-88846af6ff2c","name":"Check Review Trigger Comment","type":"n8n-nodes-base.if","position":[-1648,240],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"617eb2c5-dd4b-4e28-b533-0c32ea6ca961","operator":{"name":"filter.operator.equals","type":"string","operation":"equals"},"leftValue":"={{ $json.body.object_attributes.note }}","rightValue":"={{ $('Workflow Configuration').first().json.reviewTriggerPhrase }}"}]}},"typeVersion":2.2},{"id":"4a7768fd-9c71-4e5c-ae77-06395b94d044","name":"Post Review Started Reply","type":"n8n-nodes-base.httpRequest","position":[-1232,48],"parameters":{"url":"={{ $('Workflow Configuration').first().json.gitlabBaseUrl }}/projects/{{ $('GitLab Discussion Webhook').item.json.body.project.id }}/merge_requests/{{ $('GitLab Discussion Webhook').item.json.body.merge_request.iid }}/discussions/{{ $('GitLab Discussion Webhook').item.json.body.object_attributes.discussion_id }}/notes","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"body","value":"={{ $('Workflow Configuration').first().json.reviewStartedMessage }}"}]},"nodeCredentialType":"gitlabApi"},"credentials":{"gitlabApi":{"id":"jNWhLjAYuN421t1v","name":"GitLab account"}},"typeVersion":4.2},{"id":"ced91e4b-aea1-48d5-baca-11e61cf53e11","name":"Fetch Merge Request Changes","type":"n8n-nodes-base.httpRequest","position":[-1232,224],"parameters":{"url":"={{ $('Workflow Configuration').first().json.gitlabBaseUrl }}/projects/{{ $json[\"body\"][\"project_id\"] }}/merge_requests/{{ $json[\"body\"][\"merge_request\"][\"iid\"] }}/changes","options":{},"authentication":"predefinedCredentialType","nodeCredentialType":"gitlabApi"},"credentials":{"gitlabApi":{"id":"jNWhLjAYuN421t1v","name":"GitLab account"}},"typeVersion":4.2},{"id":"bb0320ac-0086-484f-aba4-812dd83ada77","name":"Split Changed Files","type":"n8n-nodes-base.splitOut","position":[-960,224],"parameters":{"options":{},"fieldToSplitOut":"changes"},"typeVersion":1},{"id":"eb1c3141-4dbc-44e5-b232-2b96c6aca112","name":"Filter Supported Diffs","type":"n8n-nodes-base.if","position":[-720,224],"parameters":{"options":{},"conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"c6e1430b-84a7-47ce-8fe9-7b94da0f2d31","operator":{"type":"boolean","operation":"false","singleValue":true},"leftValue":"={{ $json.renamed_file }}","rightValue":""},{"id":"bf6e9eb9-d72d-459c-a722-9614bab8842c","operator":{"type":"boolean","operation":"false","singleValue":true},"leftValue":"={{ $json.deleted_file }}","rightValue":""},{"id":"501623a9-9515-4034-bb13-a5a6a4f924eb","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ /(^|\\n)@@ -\\d+(?:,\\d+)? \\+\\d+(?:,\\d+)? @@/m.test($json.diff ?? '') }}","rightValue":"@@"}]}},"typeVersion":2.2},{"id":"3e8222aa-d68a-4366-9167-f039831d8ed5","name":"Prepare Review Context","type":"n8n-nodes-base.code","position":[-288,208],"parameters":{"mode":"runOnceForEachItem","jsCode":"const diff = $input.item.json.diff ?? '';\n\nconst lines = diff\n  .replace(/\\n\\\\ No newline at end of file/g, '')\n  .split('\\n');\n\nlet originalCode = '';\nlet newCode = '';\nlet newCodeLogicalLine = 0;\nconst newCodeLineMap = {};\n\nlet oldLine = 0;\nlet newLine = 0;\n\nlet reviewableNewCode = '';\n\nfor (const line of lines) {\n  const hunk = line.match(/^@@ -(\\d+)(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@/);\n  if (hunk) {\n    oldLine = Number(hunk[1]);\n    newLine = Number(hunk[2]);\n    continue;\n  }\n\n  if (line.startsWith('+++') || line.startsWith('---')) {\n    continue;\n  }\n\n  if (line.startsWith('-')) {\n    originalCode += line + '\\n';\n    oldLine += 1;\n    continue;\n  }\n\n  if (line.startsWith('+')) {\n    newCode += line + '\\n';\n    newCodeLogicalLine += 1;\n    newCodeLineMap[newCodeLogicalLine] = newLine;\n    reviewableNewCode += `[L${newLine}] ${line}\\n`;\n    newLine += 1;\n    continue;\n  }\n\n  // context line\n  newCode += line + '\\n';\n  newCodeLogicalLine += 1;\n  newCodeLineMap[newCodeLogicalLine] = newLine;\n  reviewableNewCode += `[L${newLine}] ${line}\\n`;\n  oldLine += 1;\n  newLine += 1;\n}\n\nreturn {\n  path: $input.item.json.new_path || $input.item.json.old_path || '',\n  oldPath: $input.item.json.old_path || '',\n  newPath: $input.item.json.new_path || '',\n  gitDiff: diff,\n  originalCode,\n  newCode,\n  newCodeLineMap,\n  reviewableNewCode,\n  mrTitle: $('GitLab Discussion Webhook').item.json.body.merge_request.title || '',\n  mrDescription: $('GitLab Discussion Webhook').item.json.body.merge_request.description || '',\n  projectId: $('GitLab Discussion Webhook').item.json.body.project.id,\n  mrIid: $('GitLab Discussion Webhook').item.json.body.merge_request.iid,\n  discussionId: $('GitLab Discussion Webhook').item.json.body.object_attributes.discussion_id,\n  startSha: $('Fetch Merge Request Changes').item.json.diff_refs.start_sha || '',\n  headSha: $('Fetch Merge Request Changes').item.json.diff_refs.head_sha || '',\n  baseSha: $('Fetch Merge Request Changes').item.json.diff_refs.base_sha || ''\n};"},"typeVersion":2},{"id":"f979e02c-9f39-41ac-80af-5b02b7735101","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[96,-288],"parameters":{"color":7,"width":608,"height":1184,"content":"## Run parallel AI reviewers\n\nAnalyze each changed file with bug, security, and maintainability reviewers.\nEach reviewer returns structured findings for final verification."},"typeVersion":1},{"id":"e2045ae9-9360-4b10-84ba-001dbfe67613","name":"Merge Reviewer Results","type":"n8n-nodes-base.merge","position":[928,192],"parameters":{"numberInputs":3},"typeVersion":3.2},{"id":"833740be-aae9-45e3-ba88-9d326cfb0cb9","name":"Combine Findings","type":"n8n-nodes-base.code","position":[1184,208],"parameters":{"jsCode":"const allItems = $input.all();\n\nlet merged = [];\n\n// Assuming that the reviewer’s output is stored in item.json.output\nfor (const item of allItems) {\n  const src = item.json.output ?? item.json;\n  const findings = src.findings || [];\n  merged = merged.concat(findings);\n}\n\nconst uniqueMap = new Map();\n\nfor (const f of merged) {\n  const key = `${f.title}_${f.path}_${f.line}`;\n  if (!uniqueMap.has(key)) {\n    uniqueMap.set(key, f);\n  }\n}\n\nreturn [\n  {\n    json: {\n      path: $('Prepare Review Context').first().json.path || '',\n      oldPath: $('Prepare Review Context').first().json.oldPath || '',\n      newPath: $('Prepare Review Context').first().json.newPath || '',\n      gitDiff: $('Prepare Review Context').first().json.gitDiff || '',\n      originalCode: $('Prepare Review Context').first().json.originalCode || '',\n      newCode: $('Prepare Review Context').first().json.newCode || '',\n      newCodeLineMap: $('Prepare Review Context').first().json.newCodeLineMap || {},\n      reviewableNewCode: $('Prepare Review Context').first().json.reviewableNewCode || '',\n      mrTitle: $('Prepare Review Context').first().json.mrTitle || '',\n      mrDescription: $('Prepare Review Context').first().json.mrDescription || '',\n      projectId: $('Prepare Review Context').first().json.projectId || '',\n      mrIid: $('Prepare Review Context').first().json.mrIid || '',\n      discussionId: $('Prepare Review Context').first().json.discussionId || '',\n      startSha: $('Prepare Review Context').first().json.startSha || '',\n      headSha: $('Prepare Review Context').first().json.headSha || '',\n      baseSha: $('Prepare Review Context').first().json.baseSha || '',\n      findings: Array.from(uniqueMap.values())\n    }\n  }\n];"},"typeVersion":2},{"id":"90de14bc-3f94-44bd-95c3-9ffbf2840ee4","name":"Analyze Bugs","type":"@n8n/n8n-nodes-langchain.agent","onError":"continueRegularOutput","maxTries":2,"position":[288,-128],"parameters":{"text":"={{ JSON.stringify($json, null, 2) }}","options":{"systemMessage":"You are the Bug Reviewer for a pull request.\n\nGoal:\nDetect only newly introduced functional or logical bugs caused by this change.\n\nFocus areas:\n- Incorrect logic\n- Wrong conditions or boundary checks\n- Incorrect calculations (length, offsets, indices)\n- Off-by-one errors\n- Wrong assumptions about input values\n\nDo NOT report:\n- Style issues\n- Pure maintainability concerns\n- Security concerns unless they are primarily functional bugs in this change\n\nInput:\n- path: {{ $json.path }}\n- gitDiff: {{ $json.gitDiff }}\n- originalCode: {{ $json.originalCode }}\n- reviewableNewCode: {{ $json.reviewableNewCode }}\n- mr: {{ $json.mrTitle }}, {{ $json.mrDescription }}\n\nRules:\n- Report only issues introduced by this change\n- Do not speculate beyond the provided diff and code\n- If there is no real bug, return no findings\n- Use reviewableNewCode for line selection\n- line must be the L-number from reviewableNewCode\n- Prefer the exact changed statement over nearby context\n- reviewer must be \"bug\"\n- category must be \"bug\"\n- severity must be one of: high, medium, low\n- confidence must be an integer from 0 to 100\n- path must be the input path\n- Return a single JSON object matching the structured output schema exactly\n- Do not wrap the result in an \"output\" field\n- Return JSON only\n- Do not add explanations or markdown\n- If there is no real issue, return no findings.\n- Do not omit required fields when returning a finding."},"promptType":"define","hasOutputParser":true},"retryOnFail":true,"typeVersion":3.1,"alwaysOutputData":true},{"id":"d8a1225a-8bfc-4973-9374-7aed82883310","name":"Bug Reviewer Model","type":"@n8n/n8n-nodes-langchain.lmChatAzureOpenAi","position":[208,48],"parameters":{"model":"gpt-5.4-mini","options":{"topP":1}},"credentials":{"azureOpenAiApi":{"id":"mrpZgA0s7HoGAJIm","name":"Azure Open AI eagle"}},"typeVersion":1},{"id":"109ef89e-9a1b-44fd-a002-8e8bb6ae7c19","name":"Parse Bug Review Output","type":"@n8n/n8n-nodes-langchain.outputParserStructured","maxTries":2,"position":[528,48],"parameters":{"jsonSchemaExample":"{\n  \"reviewer\": \"bug\",\n  \"findings\": [\n    {\n      \"title\": \"CRC is computed over the wrong byte range\",\n      \"severity\": \"high\",\n      \"confidence\": 98,\n      \"path\": \"project/src/packet.c\",\n      \"line\": 42,\n      \"category\": \"bug\",\n      \"why\": \"The CRC input length was changed so one required byte is no longer included in the checksum.\",\n      \"suggestion\": \"Restore the original CRC input length so the decoder validates the intended packet range.\"\n    }\n  ]\n}"},"retryOnFail":true,"typeVersion":1.3,"alwaysOutputData":true},{"id":"222b4278-17ea-4390-aed2-48c8d72e4282","name":"Analyze Security Risks","type":"@n8n/n8n-nodes-langchain.agent","onError":"continueRegularOutput","maxTries":2,"position":[288,208],"parameters":{"text":"={{ JSON.stringify($json, null, 2) }}","options":{"systemMessage":"You are the Security Reviewer for a pull request.\n\nGoal:\nDetect only newly introduced security risks caused by this change.\n\nFocus areas:\n- Missing validation of external input\n- Buffer overflow or out-of-bounds access\n- Unsafe memory operations\n- Injection risks\n- Sensitive data exposure\n- Missing checks that allow malformed input to cause damage\n\nDo NOT report:\n- General bugs unless they are real security risks\n- Pure maintainability concerns\n- Style issues\n\nInput:\n- path: {{ $json.path }}\n- gitDiff: {{ $json.gitDiff }}\n- originalCode: {{ $json.originalCode }}\n- reviewableNewCode: {{ $json.reviewableNewCode }}\n- mr: {{ $json.mrTitle }}, {{ $json.mrDescription }}\n\nRules:\n- Report only real security risks introduced by this change\n- If the issue is only a bug and not a real security risk, do not report it\n- If there is no real security issue, return no findings\n- Use reviewableNewCode for line selection\n- line must be the L-number from reviewableNewCode\n- Prefer the exact changed statement over nearby context\n- reviewer must be \"security\"\n- category must be \"security\"\n- severity must be one of: high, medium, low\n- confidence must be an integer from 0 to 100\n- path must be the input path\n- Return a single JSON object matching the structured output schema exactly\n- Do not wrap the result in an \"output\" field\n- Return JSON only\n- Do not add explanations or markdown\n- If there is no real issue, return no findings.\n- Do not omit required fields when returning a finding."},"promptType":"define","hasOutputParser":true},"notesInFlow":false,"retryOnFail":true,"typeVersion":3.1,"alwaysOutputData":true},{"id":"2e4fe6a8-ed29-41f2-9987-73e9d45028eb","name":"Security Reviewer Model","type":"@n8n/n8n-nodes-langchain.lmChatAzureOpenAi","position":[208,384],"parameters":{"model":"gpt-5.4-mini","options":{"topP":1}},"credentials":{"azureOpenAiApi":{"id":"mrpZgA0s7HoGAJIm","name":"Azure Open AI eagle"}},"typeVersion":1},{"id":"7810d8b4-07d2-4eda-8e61-7a7d855e0645","name":"Parse Security Review Output","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[528,384],"parameters":{"jsonSchemaExample":"{\n  \"reviewer\": \"security\",\n  \"findings\": [\n    {\n      \"title\": \"Missing upper-bound validation before payload copy\",\n      \"severity\": \"high\",\n      \"confidence\": 95,\n      \"path\": \"project/src/packet.c\",\n      \"line\": 46,\n      \"category\": \"security\",\n      \"why\": \"The decoded length is copied into the payload buffer without checking that it fits the destination buffer.\",\n      \"suggestion\": \"Validate that len does not exceed the payload buffer size before calling memcpy.\"\n    }\n  ]\n}"},"typeVersion":1.3,"alwaysOutputData":true},{"id":"a91382fc-e303-4dff-91f8-1cd15d2de5c5","name":"Analyze Maintainability Risks","type":"@n8n/n8n-nodes-langchain.agent","onError":"continueRegularOutput","maxTries":2,"position":[288,560],"parameters":{"text":"={{ JSON.stringify($json, null, 2) }}","options":{"systemMessage":"You are the Maintainability Reviewer for a pull request.\n\nGoal:\nDetect only meaningful maintainability issues introduced by this change.\n\nFocus areas:\n- Missing defensive checks\n- Risky assumptions not validated\n- Changes that significantly reduce readability\n- Logic that becomes harder to test or reason about\n- Changes that increase future defect risk even if they are not immediate bugs\n\nDo NOT report:\n- Formatting issues\n- Naming preferences\n- Minor readability suggestions\n- General advice not tied to changed code\n- Pure bug or security issues unless the maintainability concern is clearly distinct\n\nInput:\n- path: {{ $json.path }}\n- gitDiff: {{ $json.gitDiff }}\n- originalCode: {{ $json.originalCode }}\n- reviewableNewCode: {{ $json.reviewableNewCode }}\n- mr: {{ $json.mrTitle }}, {{ $json.mrDescription }}\n\nRules:\n- Report only meaningful issues introduced by this change\n- If the issue is weak, subjective, or minor, do not report it\n- If there is no real maintainability issue, return no findings\n- Use reviewableNewCode for line selection\n- line must be the L-number from reviewableNewCode\n- Prefer the exact changed statement over nearby context\n- reviewer must be \"maintainability\"\n- category must be \"maintainability\"\n- severity must be one of: medium, low\n- confidence must be an integer from 0 to 100\n- path must be the input path\n- Return a single JSON object matching the structured output schema exactly\n- Do not wrap the result in an \"output\" field\n- Return JSON only\n- Do not add explanations\n- If there is no real issue, return no findings.\n- Do not omit required fields when returning a finding."},"promptType":"define","hasOutputParser":true},"notesInFlow":false,"retryOnFail":true,"typeVersion":3.1,"alwaysOutputData":true},{"id":"6ce560ca-d1b0-450d-ab26-f1aa13f5b7ba","name":"Maintainability Reviewer Model","type":"@n8n/n8n-nodes-langchain.lmChatAzureOpenAi","position":[208,736],"parameters":{"model":"gpt-5.4-mini","options":{"topP":1}},"credentials":{"azureOpenAiApi":{"id":"mrpZgA0s7HoGAJIm","name":"Azure Open AI eagle"}},"typeVersion":1},{"id":"bf350a82-ed47-425c-ab99-0da161717062","name":"Parse Maintainability Review Output","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[512,736],"parameters":{"jsonSchemaExample":"{\n  \"reviewer\": \"maintainability\",\n  \"findings\": [\n    {\n      \"title\": \"Length validation is missing in the decode path\",\n      \"severity\": \"medium\",\n      \"confidence\": 88,\n      \"path\": \"project/src/packet.c\",\n      \"line\": 46,\n      \"category\": \"maintainability\",\n      \"why\": \"The decode path relies on an unchecked length value before copying data into the payload buffer.\",\n      \"suggestion\": \"Add an explicit upper-bound check for len before copying the payload.\"\n    }\n  ]\n}"},"typeVersion":1.3,"alwaysOutputData":true},{"id":"3d6a3c26-9f14-4f61-bc1f-20d6f0186575","name":"Verify Findings","type":"@n8n/n8n-nodes-langchain.agent","onError":"continueRegularOutput","maxTries":2,"position":[1632,208],"parameters":{"text":"={{ JSON.stringify($json, null, 2) }}","options":{"systemMessage":"You are the verifier for pull request review findings.\n\nGoal:\nValidate and normalize findings from the reviewers.\n\nInput:\n- path: {{ $json.path }}\n- gitDiff: {{ $json.gitDiff }}\n- originalCode: {{ $json.originalCode }}\n- reviewableNewCode: {{ $json.reviewableNewCode }}\n- findings: {{ JSON.stringify($json.findings, null, 2) }}\n\nTasks:\n- Keep only findings grounded in the diff\n- Remove speculative or weak findings\n- Remove duplicates\n- Prefer the most useful classification when findings overlap\n- Normalize severity and confidence\n- Produce concise, GitLab-ready English comments\n\nRules:\n\n[General]\n- Reviewer output may be imperfect; always re-evaluate findings\n- Drop findings that are not clearly supported by the diff\n- Path must not be empty; if missing or unknown, use input path\n\n[Line selection]\n- Use reviewableNewCode for line selection\n- line must be the L-number from reviewableNewCode\n- Prefer the exact changed statement over nearby context\n- If unclear, select the closest relevant changed line only when the finding clearly applies\n- If no specific changed line can be identified, set line to null and post_inline to false\n\n[Status]\n- status must be one of: keep, drop, duplicate, pre_existing\n- Use \"keep\" only for findings worth posting after verification\n- Never use \"open\" or any other value\n\n[Severity normalization]\n- final_severity must be one of: high, medium, low\n- Always re-evaluate severity; do not trust reviewer severity\n\nUse the following strict criteria:\n\nhigh:\n- Causes incorrect behavior, broken functionality, or protocol mismatch\n- Can lead to crash, data corruption, or memory safety issues\n- Security vulnerabilities (e.g., OOB write, injection)\n\nmedium:\n- Potential bug, missing validation, or fragile logic\n- May become a bug under certain conditions\n- Maintainability issues that can realistically cause future defects\n\nlow:\n- Readability, naming, minor structure or style issues\n- No realistic impact on correctness\n\n- When multiple findings describe the same root problem:\n  - Keep the most critical one\n  - Downgrade or mark others as duplicate\n  - Avoid multiple high severity findings for the same root cause\n\n[Confidence normalization]\n- final_confidence must be one of: 0, 25, 50, 75, 100\n- Use 100 only when directly proven by the diff with almost no ambiguity\n- Use 75 when strongly supported and very likely correct\n- Use 50 when plausible but requires assumptions or missing context\n- Use 25 when weak signal; generally should be dropped unless still useful\n- Use 0 when unsupported or incorrect\n\n- Findings with final_confidence = 0 should normally have status = \"drop\"\n\n[Inline decision]\n- post_inline must be boolean\n- Set post_inline = true only when:\n  - status = \"keep\"\n  - AND a specific changed line is clearly identified\n- Otherwise set post_inline = false\n- Do NOT use severity or confidence to decide inline vs reply\n\n[Output quality]\n- title must be concise English\n- comment must be short, practical, and directly actionable\n- Avoid repeating the same issue in multiple findings\n\n[Output format]\n- Return a single JSON object matching the structured output schema exactly\n- Do not wrap the result in an \"output\" field\n- Return JSON only\n- Do not add explanations or markdown\n- Do not omit any required field in validated_findings\n- If no finding should remain, return an empty validated_findings array"},"promptType":"define","hasOutputParser":true},"retryOnFail":true,"typeVersion":3.1,"alwaysOutputData":true},{"id":"800ab383-e391-407a-85ec-8dc5b8361974","name":"Verifier Model","type":"@n8n/n8n-nodes-langchain.lmChatAzureOpenAi","position":[1552,416],"parameters":{"model":"gpt-5.4-mini","options":{"topP":1}},"credentials":{"azureOpenAiApi":{"id":"mrpZgA0s7HoGAJIm","name":"Azure Open AI eagle"}},"typeVersion":1},{"id":"c424f47a-cbe8-41bd-bcd5-83f7b1793fde","name":"Parse Verification Output","type":"@n8n/n8n-nodes-langchain.outputParserStructured","position":[1840,416],"parameters":{"jsonSchemaExample":"{\n  \"validated_findings\": [\n    {\n      \"title\": \"Restore CRC length and byte order\",\n      \"path\": \"project/src/packet.c\",\n      \"line\": 42,\n      \"final_severity\": \"high\",\n      \"final_confidence\": 100,\n      \"status\": \"keep\",\n      \"post_inline\": true,\n      \"comment\": \"The CRC validation now uses the wrong byte range and byte order, so valid packets can be rejected. Restore the original CRC length and trailer byte order.\"\n    },\n    {\n      \"title\": \"Clarify unchecked length assumption\",\n      \"path\": \"project/src/packet.c\",\n      \"line\": null,\n      \"final_severity\": \"low\",\n      \"final_confidence\": 50,\n      \"status\": \"keep\",\n      \"post_inline\": false,\n      \"comment\": \"The safety of this path depends on an external length guarantee. Consider documenting or enforcing that contract closer to the use site.\"\n    }\n  ]\n}"},"typeVersion":1.3,"alwaysOutputData":true},{"id":"3ee34738-ec78-48ff-b1f3-b257c2a0929a","name":"Sticky Note5","type":"n8n-nodes-base.stickyNote","position":[1488,-16],"parameters":{"color":7,"width":752,"height":592,"content":"## Verify and normalize findings\n\nRe-check each finding against the diff, remove weak or duplicate issues, and normalize the final severity and confidence."},"typeVersion":1},{"id":"24d31f5a-dbf6-448f-9141-d562b336813b","name":"Normalize Verified Findings","type":"n8n-nodes-base.code","position":[2000,208],"parameters":{"jsCode":"const out = $json.output ?? $json;\nconst meta = $('Combine Findings').first().json;\n\nconst validatedFindings = (out.validated_findings || []).map(f => {\n  const rawLine = f.line;\n  const line = Number(rawLine);\n  const lineMap = meta.newCodeLineMap || {};\n  const mappedLine = Number.isInteger(line) && line > 0\n    ? Number(lineMap[line] ?? line)\n    : null;\n\n  const normalizedLine =\n    Number.isInteger(mappedLine) && mappedLine > 0 ? mappedLine : null;\n\n  const normalizedStatus = f.status || 'drop';\n  const normalizedInline =\n    normalizedStatus === 'keep' &&\n    normalizedLine !== null &&\n    f.post_inline === true;\n\n  return {\n    ...f,\n    path: f.path && f.path !== 'unknown' ? f.path : (meta.path || ''),\n    oldPath: meta.oldPath || '',\n    newPath: meta.newPath || '',\n    projectId: meta.projectId || '',\n    mrIid: meta.mrIid || '',\n    discussionId: meta.discussionId || '',\n    startSha: meta.startSha || '',\n    headSha: meta.headSha || '',\n    baseSha: meta.baseSha || '',\n    line: normalizedLine,\n    post_inline: normalizedInline\n  };\n});\n\nconst keepCount = validatedFindings.filter(f => f.status === 'keep').length;\n\nreturn [\n  {\n    json: {\n      validated_findings: validatedFindings,\n      keep_count: keepCount\n    }\n  }\n];"},"typeVersion":2},{"id":"2d6de0fe-3507-470c-bd76-df6365079d53","name":"Check Findings Exist","type":"n8n-nodes-base.if","position":[2416,352],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"90a27f07-8e7f-4b1d-bbde-05e0f73846f9","operator":{"type":"number","operation":"gte"},"leftValue":"={{$json.keep_count}}","rightValue":1}]}},"typeVersion":2.3},{"id":"35f1a3ee-f0bf-42a6-a0a9-193a477708ef","name":"Build Summary Comment","type":"n8n-nodes-base.code","position":[3360,432],"parameters":{"jsCode":"return {\n  text: $('Workflow Configuration').first().json.summaryMessage\n    || '✅ Review finished. See inline comments for details.'\n};"},"typeVersion":2},{"id":"5ac8e5c4-d800-4f15-9ced-1bc334832716","name":"Build No-Issues Comment","type":"n8n-nodes-base.code","position":[3360,640],"parameters":{"jsCode":"return {\n  text: $('Workflow Configuration').first().json.noIssuesMessage\n};"},"typeVersion":2},{"id":"26500903-ef4a-42d8-bdb0-9b50504d1dd9","name":"Post Summary Reply","type":"n8n-nodes-base.httpRequest","position":[3664,544],"parameters":{"url":"={{ $('Workflow Configuration').first().json.gitlabBaseUrl }}/projects/{{ $('Combine Findings').item.json.projectId }}/merge_requests/{{ $('Combine Findings').item.json.mrIid }}/discussions/{{ $('Combine Findings').item.json.discussionId }}/notes","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"body","value":"={{ $json.text }}"}]},"nodeCredentialType":"gitlabApi"},"credentials":{"gitlabApi":{"id":"jNWhLjAYuN421t1v","name":"GitLab account"}},"typeVersion":4.2},{"id":"a6977948-6c59-4b2a-a609-61a2b18e9b91","name":"Split Verified Findings","type":"n8n-nodes-base.splitOut","position":[2704,208],"parameters":{"options":{},"fieldToSplitOut":"validated_findings"},"typeVersion":1},{"id":"d01239bd-af12-48f5-b5eb-d7ef74889886","name":"Filter Publishable Findings","type":"n8n-nodes-base.if","position":[2944,208],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"67f9d8b0-7268-4068-8572-873a8e4f8f43","operator":{"type":"string","operation":"equals"},"leftValue":"={{$json.status}}","rightValue":"keep"},{"id":"7d9ed55a-e8d5-491d-b7b0-9f26b466280c","operator":{"type":"number","operation":"gte"},"leftValue":"={{$json.final_confidence}}","rightValue":"={{ $('Workflow Configuration').first().json.minConfidenceToPost }}"}]}},"typeVersion":2.3},{"id":"1a91dabf-b880-4c18-b97c-bc6cb1ff764a","name":"Build Inline Comment","type":"n8n-nodes-base.code","position":[3616,-224],"parameters":{"mode":"runOnceForEachItem","jsCode":"const iconMap = {\n  high: \"🔴\",\n  medium: \"🟡\",\n  low: \"🔵\",\n};\n\nconst icon = iconMap[$json.final_severity] || \"🔵\";\n\nreturn {\n  ...$json,\n  text: `${icon} **${$json.title}**\\n\\n${$json.comment}`\n};"},"typeVersion":2},{"id":"0ed853a6-492a-4a20-aacf-d07c6c46e9a1","name":"Post Inline Review Comment","type":"n8n-nodes-base.httpRequest","position":[4192,-400],"parameters":{"url":"={{ $('Workflow Configuration').first().json.gitlabBaseUrl }}/projects/{{ $json.projectId }}/merge_requests/{{ $json.mrIid }}/discussions","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"body","value":"={{ $json.text }}"},{"name":"position[position_type]","value":"text"},{"name":"position[old_path]","value":"={{ $json.oldPath }}"},{"name":"position[new_path]","value":"={{ $json.newPath }}"},{"name":"position[start_sha]","value":"={{ $json.startSha }}"},{"name":"position[head_sha]","value":"={{ $json.headSha }}"},{"name":"position[base_sha]","value":"={{ $json.baseSha }}"},{"name":"position[new_line]","value":"={{ $json.positionNewLine ?? '' }}"},{"name":"position[old_line]","value":"={{ $json.positionOldLine ?? '' }}"}]},"nodeCredentialType":"gitlabApi"},"credentials":{"gitlabApi":{"id":"jNWhLjAYuN421t1v","name":"GitLab account"}},"typeVersion":4.2},{"id":"726cc9e8-312f-4bac-b824-c0019a54cabe","name":"Sticky Note6","type":"n8n-nodes-base.stickyNote","position":[2320,-16],"parameters":{"color":7,"width":848,"height":592,"content":"## Decide what to publish\n\nPost only findings with `status = keep` and confidence at or above the configured threshold.\n\nIf a valid diff position is found, post an inline comment.\nOtherwise, post a reply comment in the trigger discussion."},"typeVersion":1},{"id":"49308ef9-c8a9-4480-9bf7-cb76200dc741","name":"Resolve GitLab Diff Position","type":"n8n-nodes-base.code","position":[3344,-224],"parameters":{"mode":"runOnceForEachItem","jsCode":"const diff = $('Combine Findings').first().json.gitDiff || '';\nconst targetLine = Number($json.line);\n\nfunction buildNewSideMap(gitDiff) {\n  const lines = gitDiff.replace(/\\n\\\\ No newline at end of file/g, '').split('\\n');\n\n  let oldLine = 0;\n  let newLine = 0;\n  const map = new Map();\n\n  for (const line of lines) {\n    const hunk = line.match(/^@@ -(\\d+)(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@/);\n    if (hunk) {\n      oldLine = Number(hunk[1]);\n      newLine = Number(hunk[2]);\n      continue;\n    }\n\n    if (line.startsWith('+++') || line.startsWith('---')) {\n      continue;\n    }\n\n    if (line.startsWith('+')) {\n      map.set(newLine, {\n        kind: 'added',\n        newLine,\n        oldLine: null,\n      });\n      newLine += 1;\n      continue;\n    }\n\n    if (line.startsWith('-')) {\n      oldLine += 1;\n      continue;\n    }\n\n    // context line\n    map.set(newLine, {\n      kind: 'context',\n      newLine,\n      oldLine,\n    });\n    oldLine += 1;\n    newLine += 1;\n  }\n\n  return map;\n}\n\nconst lineMap = buildNewSideMap(diff);\nconst pos = lineMap.get(targetLine);\n\nreturn {\n  ...$json,\n  positionKind: pos?.kind || 'unknown',\n  positionNewLine: pos?.newLine ?? null,\n  positionOldLine: pos?.oldLine ?? null,\n  canPostInline: !!pos\n};"},"typeVersion":2},{"id":"77fb631b-0c24-4bf4-a115-77b420b407ac","name":"Check Inline Position","type":"n8n-nodes-base.if","position":[3872,-224],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"692505f7-cf7f-457e-b0b0-6d200026be6d","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{$json.canPostInline}}","rightValue":""}]}},"typeVersion":2.3},{"id":"05e25cbd-06e6-44e9-a33f-3269835c552d","name":"Workflow Configuration","type":"n8n-nodes-base.set","position":[-1904,240],"parameters":{"options":{},"assignments":{"assignments":[{"id":"588e5976-88ab-4cff-8db7-5394f8bf59b2","name":"gitlabBaseUrl","type":"string","value":"https://gitlab.example.com/api/v4"},{"id":"c3a738df-33de-4cb7-af13-d3a42008b769","name":"reviewTriggerPhrase","type":"string","value":"+0"},{"id":"1bd7d1e8-1c9e-4c05-ab54-78a8b97f76ac","name":"minConfidenceToPost","type":"number","value":75},{"id":"570ecfa2-f25c-4810-8c74-8af77c19f07c","name":"reviewStartedMessage","type":"string","value":"🔍 I'm reviewing the code right now. Please hang tight for a moment."},{"id":"a4fcbea2-ea1d-4931-b6ff-35a0245c04a4","name":"noIssuesMessage","type":"string","value":"🟢 The changes look good this time!"},{"id":"77ba45e7-b313-45a3-bfb8-05323d66a5d0","name":"summaryMessage","type":"string","value":"✅ Review complete!"}]},"includeOtherFields":true},"typeVersion":3.4},{"id":"b3812b08-44e5-48dc-9e52-1c885051b13d","name":"Sticky Note7","type":"n8n-nodes-base.stickyNote","position":[-448,-112],"parameters":{"color":7,"width":464,"height":560,"content":"## Prepare review context\n\nConvert each diff into a clean review payload with file paths, code snippets, merge request metadata, and diff SHAs needed later for GitLab comments."},"typeVersion":1},{"id":"1d5b16f8-004b-4040-b426-751ebad11b7c","name":"Sticky Note8","type":"n8n-nodes-base.stickyNote","position":[3248,-592],"parameters":{"color":7,"width":1408,"height":656,"content":"## Publish review comments\n\nResolve the GitLab diff position for each verified finding and post the final review comment.\n\nIf a valid inline position is available, create an inline diff discussion.\nOtherwise, post a reply comment in the trigger discussion."},"typeVersion":1},{"id":"e877d584-a678-4c86-9645-dcb0872dd440","name":"Sticky Note9","type":"n8n-nodes-base.stickyNote","position":[3248,224],"parameters":{"color":7,"width":656,"height":608,"content":"## Post a summary reply\n\nAlways reply to the trigger discussion with either a completion message or a no-issues message.\nInline and fallback review comments are posted separately."},"typeVersion":1},{"id":"5653a6fb-b1a1-4e70-bbf5-6bb8d709fa0d","name":"Sticky Note10","type":"n8n-nodes-base.stickyNote","position":[800,-112],"parameters":{"color":7,"width":592,"height":576,"content":"## Merge reviewer outputs\n\nCombine findings from all reviewers, remove obvious duplicates, and keep the file and merge request context for final verification."},"typeVersion":1},{"id":"17e3c9d5-0f05-4b66-adb5-7da2d903a8c1","name":"Post Fallback Reply","type":"n8n-nodes-base.httpRequest","position":[4416,-160],"parameters":{"url":"={{ $('Workflow Configuration').first().json.gitlabBaseUrl }}/projects/{{ $json.projectId }}/merge_requests/{{ $json.mrIid }}/discussions/{{ $json.discussionId }}/notes","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","authentication":"predefinedCredentialType","bodyParameters":{"parameters":[{"name":"body","value":"={{ $json.fallbackBody }}"}]},"nodeCredentialType":"gitlabApi"},"credentials":{"gitlabApi":{"id":"jNWhLjAYuN421t1v","name":"GitLab account"}},"typeVersion":4.2},{"id":"8300ae3d-115d-44d3-8717-fa123959d1ba","name":"Build Fallback Comment","type":"n8n-nodes-base.code","position":[4192,-160],"parameters":{"mode":"runOnceForEachItem","jsCode":"const iconMap = {\n  high: '🔴',\n  medium: '🟡',\n  low: '🔵',\n};\n\nconst severity = ($json.final_severity || 'low').toLowerCase();\nconst icon = iconMap[severity] || '🔵';\n\nreturn {\n  ...$json,\n  fallbackBody: [\n    `${icon} General review comment (exact diff line could not be resolved)`,\n    '',\n    `**${$json.title}**`,\n    $json.comment,\n    '',\n    `File: ${$json.path || $json.newPath || $json.oldPath || 'unknown'}`\n  ].join('\\n')\n};"},"typeVersion":2}],"active":false,"pinData":{},"settings":{"callerPolicy":"workflowsFromSameOwner","timeSavedMode":"fixed","availableInMCP":false,"executionOrder":"v1","executionTimeout":300,"timeSavedPerExecution":5},"versionId":"9e8d2b52-6272-431e-86b5-f691e835270b","connections":{"Analyze Bugs":{"main":[[{"node":"Merge Reviewer Results","type":"main","index":0}]]},"Verifier Model":{"ai_languageModel":[[{"node":"Verify Findings","type":"ai_languageModel","index":0}]]},"Verify Findings":{"main":[[{"node":"Normalize Verified Findings","type":"main","index":0}]]},"Combine Findings":{"main":[[{"node":"Verify Findings","type":"main","index":0}]]},"Bug Reviewer Model":{"ai_languageModel":[[{"node":"Analyze Bugs","type":"ai_languageModel","index":0}]]},"Split Changed Files":{"main":[[{"node":"Filter Supported Diffs","type":"main","index":0}]]},"Build Inline Comment":{"main":[[{"node":"Check Inline Position","type":"main","index":0}]]},"Check Findings Exist":{"main":[[{"node":"Build Summary Comment","type":"main","index":0},{"node":"Split Verified Findings","type":"main","index":0}],[{"node":"Build No-Issues Comment","type":"main","index":0}]]},"Build Summary Comment":{"main":[[{"node":"Post Summary Reply","type":"main","index":0}]]},"Check Inline Position":{"main":[[{"node":"Post Inline Review Comment","type":"main","index":0}],[{"node":"Build Fallback Comment","type":"main","index":0}]]},"Analyze Security Risks":{"main":[[{"node":"Merge Reviewer Results","type":"main","index":1}]]},"Build Fallback Comment":{"main":[[{"node":"Post Fallback Reply","type":"main","index":0}]]},"Filter Supported Diffs":{"main":[[{"node":"Prepare Review Context","type":"main","index":0}]]},"Merge Reviewer Results":{"main":[[{"node":"Combine Findings","type":"main","index":0}]]},"Prepare Review Context":{"main":[[{"node":"Analyze Security Risks","type":"main","index":0},{"node":"Analyze Bugs","type":"main","index":0},{"node":"Analyze Maintainability Risks","type":"main","index":0}]]},"Workflow Configuration":{"main":[[{"node":"Check Review Trigger Comment","type":"main","index":0}]]},"Build No-Issues Comment":{"main":[[{"node":"Post Summary Reply","type":"main","index":0}]]},"Parse Bug Review Output":{"ai_outputParser":[[{"node":"Analyze Bugs","type":"ai_outputParser","index":0}]]},"Security Reviewer Model":{"ai_languageModel":[[{"node":"Analyze Security Risks","type":"ai_languageModel","index":0}]]},"Split Verified Findings":{"main":[[{"node":"Filter Publishable Findings","type":"main","index":0}]]},"GitLab Discussion Webhook":{"main":[[{"node":"Workflow Configuration","type":"main","index":0}]]},"Parse Verification Output":{"ai_outputParser":[[{"node":"Verify Findings","type":"ai_outputParser","index":0}]]},"Post Inline Review Comment":{"main":[[]]},"Fetch Merge Request Changes":{"main":[[{"node":"Split Changed Files","type":"main","index":0}]]},"Filter Publishable Findings":{"main":[[{"node":"Resolve GitLab Diff Position","type":"main","index":0}]]},"Normalize Verified Findings":{"main":[[{"node":"Check Findings Exist","type":"main","index":0}]]},"Check Review Trigger Comment":{"main":[[{"node":"Fetch Merge Request Changes","type":"main","index":0},{"node":"Post Review Started Reply","type":"main","index":0}]]},"Parse Security Review Output":{"ai_outputParser":[[{"node":"Analyze Security Risks","type":"ai_outputParser","index":0}]]},"Resolve GitLab Diff Position":{"main":[[{"node":"Build Inline Comment","type":"main","index":0}]]},"Analyze Maintainability Risks":{"main":[[{"node":"Merge Reviewer Results","type":"main","index":2}]]},"Maintainability Reviewer Model":{"ai_languageModel":[[{"node":"Analyze Maintainability Risks","type":"ai_languageModel","index":0}]]},"Parse Maintainability Review Output":{"ai_outputParser":[[{"node":"Analyze Maintainability Risks","type":"ai_outputParser","index":0}]]}}},"lastUpdatedBy":1,"workflowInfo":{"nodeCount":45,"nodeTypes":{"n8n-nodes-base.if":{"count":5},"n8n-nodes-base.set":{"count":1},"n8n-nodes-base.code":{"count":8},"n8n-nodes-base.merge":{"count":1},"n8n-nodes-base.webhook":{"count":1},"n8n-nodes-base.splitOut":{"count":2},"n8n-nodes-base.stickyNote":{"count":10},"n8n-nodes-base.httpRequest":{"count":5},"@n8n/n8n-nodes-langchain.agent":{"count":4},"@n8n/n8n-nodes-langchain.lmChatAzureOpenAi":{"count":4},"@n8n/n8n-nodes-langchain.outputParserStructured":{"count":4}}},"status":"published","readyToDemo":null,"user":{"name":"kazunori","username":"kazunori-kasajima","bio":"Engineer at Explorer Inc. creating practical automation and AI workflows for real-world team use.","verified":false,"links":[""],"avatar":"https://gravatar.com/avatar/6389f5b69e34ab299aef70009d62b277282802b76acab0b1fc8294e268709193?r=pg&d=retro&size=200"},"nodes":[{"id":19,"icon":"file:httprequest.svg","name":"n8n-nodes-base.httpRequest","codex":{"data":{"alias":["API","Request","URL","Build","cURL"],"resources":{"generic":[{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/","icon":"📈","label":"Automatically pulling and visualizing data with n8n"},{"url":"https://n8n.io/blog/learn-how-to-automatically-cross-post-your-content-with-n8n/","icon":"✍️","label":"Learn how to automatically cross-post your content with n8n"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/running-n8n-on-ships-an-interview-with-maranics/","icon":"🛳","label":"Running n8n on ships: An interview with Maranics"},{"url":"https://n8n.io/blog/what-are-apis-how-to-use-them-with-no-code/","icon":" 🪢","label":"What are APIs and how to use them with no code"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/world-poetry-day-workflow/","icon":"📜","label":"Celebrating World Poetry Day with a daily poem in Telegram"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/automate-designs-with-bannerbear-and-n8n/","icon":"🎨","label":"Automate Designs with Bannerbear and n8n"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/","icon":"📱","label":"Building an expense tracking app in 10 minutes"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/how-to-use-the-http-request-node-the-swiss-army-knife-for-workflow-automation/","icon":"🧰","label":"How to use the HTTP Request Node - The Swiss Army Knife for Workflow Automation"},{"url":"https://n8n.io/blog/learn-how-to-use-webhooks-with-mattermost-slash-commands/","icon":"🦄","label":"Learn how to use webhooks with Mattermost slash commands"},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/","icon":"📈","label":"A low-code bitcoin ticker built with QuestDB and n8n.io"},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/automations-for-activists/","icon":"✨","label":"How Common Knowledge use workflow automation for activism"},{"url":"https://n8n.io/blog/creating-scheduled-text-affirmations-with-n8n/","icon":"🤟","label":"Creating scheduled text affirmations with n8n"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"output\"]","defaults":{"name":"HTTP Request","color":"#0004F5"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00MCAyMEM0MCA4Ljk1MzE0IDMxLjA0NjkgMCAyMCAwQzguOTUzMTQgMCAwIDguOTUzMTQgMCAyMEMwIDMxLjA0NjkgOC45NTMxNCA0MCAyMCA0MEMzMS4wNDY5IDQwIDQwIDMxLjA0NjkgNDAgMjBaTTIwIDM2Ljk0NThDMTguODg1MiAzNi45NDU4IDE3LjEzNzggMzUuOTY3IDE1LjQ5OTggMzIuNjk4NUMxNC43OTY0IDMxLjI5MTggMTQuMTk2MSAyOS41NDMxIDEzLjc1MjYgMjcuNjg0N0gyNi4xODk4QzI1LjgwNDUgMjkuNTQwMyAyNS4yMDQ0IDMxLjI5MDEgMjQuNTAwMiAzMi42OTg1QzIyLjg2MjIgMzUuOTY3IDIxLjExNDggMzYuOTQ1OCAyMCAzNi45NDU4Wk0xMi45MDY0IDIwQzEyLjkwNjQgMjEuNjA5NyAxMy4wMDg3IDIzLjE2NCAxMy4yMDAzIDI0LjYzMDVIMjYuNzk5N0MyNi45OTEzIDIzLjE2NCAyNy4wOTM2IDIxLjYwOTcgMjcuMDkzNiAyMEMyNy4wOTM2IDE4LjM5MDMgMjYuOTkxMyAxNi44MzYgMjYuNzk5NyAxNS4zNjk1SDEzLjIwMDNDMTMuMDA4NyAxNi44MzYgMTIuOTA2NCAxOC4zOTAzIDEyLjkwNjQgMjBaTTIwIDMuMDU0MTlDMjEuMTE0OSAzLjA1NDE5IDIyLjg2MjIgNC4wMzA3OCAyNC41MDAxIDcuMzAwMzlDMjUuMjA2NiA4LjcxNDA4IDI1LjgwNzIgMTAuNDA2NyAyNi4xOTIgMTIuMzE1M0gxMy43NTAxQzE0LjE5MzMgMTAuNDA0NyAxNC43OTQyIDguNzEyNTQgMTUuNDk5OCA3LjMwMDY0QzE3LjEzNzcgNC4wMzA4MyAxOC44ODUxIDMuMDU0MTkgMjAgMy4wNTQxOVpNMzAuMTQ3OCAyMEMzMC4xNDc4IDE4LjQwOTkgMzAuMDU0MyAxNi44NjE3IDI5LjgyMjcgMTUuMzY5NUgzNi4zMDQyQzM2LjcyNTIgMTYuODQyIDM2Ljk0NTggMTguMzk2NCAzNi45NDU4IDIwQzM2Ljk0NTggMjEuNjAzNiAzNi43MjUyIDIzLjE1OCAzNi4zMDQyIDI0LjYzMDVIMjkuODIyN0MzMC4wNTQzIDIzLjEzODMgMzAuMTQ3OCAyMS41OTAxIDMwLjE0NzggMjBaTTI2LjI3NjcgNC4yNTUxMkMyNy42MzY1IDYuMzYwMTkgMjguNzExIDkuMTMyIDI5LjM3NzQgMTIuMzE1M0gzNS4xMDQ2QzMzLjI1MTEgOC42NjggMzAuMTA3IDUuNzgzNDYgMjYuMjc2NyA0LjI1NTEyWk0xMC42MjI2IDEyLjMxNTNINC44OTI5M0M2Ljc1MTQ3IDguNjY3ODQgOS44OTM1MSA1Ljc4MzQxIDEzLjcyMzIgNC4yNTUxM0MxMi4zNjM1IDYuMzYwMjEgMTEuMjg5IDkuMTMyMDEgMTAuNjIyNiAxMi4zMTUzWk0zLjA1NDE5IDIwQzMuMDU0MTkgMjEuNjAzIDMuMjc3NDMgMjMuMTU3NSAzLjY5NDg0IDI0LjYzMDVIMTAuMTIxN0M5Ljk0NjE5IDIzLjE0MiA5Ljg1MjIyIDIxLjU5NDMgOS44NTIyMiAyMEM5Ljg1MjIyIDE4LjQwNTcgOS45NDYxOSAxNi44NTggMTAuMTIxNyAxNS4zNjk1SDMuNjk0ODRDMy4yNzc0MyAxNi44NDI1IDMuMDU0MTkgMTguMzk3IDMuMDU0MTkgMjBaTTI2LjI3NjYgMzUuNzQyN0MyNy42MzY1IDMzLjYzOTMgMjguNzExIDMwLjg2OCAyOS4zNzc0IDI3LjY4NDdIMzUuMTA0NkMzMy4yNTEgMzEuMzMyMiAzMC4xMDY4IDM0LjIxNzkgMjYuMjc2NiAzNS43NDI3Wk0xMy43MjM0IDM1Ljc0MjdDOS44OTM2OSAzNC4yMTc5IDYuNzUxNTUgMzEuMzMyNCA0Ljg5MjkzIDI3LjY4NDdIMTAuNjIyNkMxMS4yODkgMzAuODY4IDEyLjM2MzUgMzMuNjM5MyAxMy43MjM0IDM1Ljc0MjdaIiBmaWxsPSIjM0E0MkU5Ii8+Cjwvc3ZnPgo="},"displayName":"HTTP Request","typeVersion":4,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":20,"icon":"fa:map-signs","name":"n8n-nodes-base.if","codex":{"data":{"alias":["Router","Filter","Condition","Logic","Boolean","Branch"],"details":"The IF node can be used to implement binary conditional logic in your workflow. You can set up one-to-many conditions to evaluate each item of data being inputted into the node. That data will either evaluate to TRUE or FALSE and route out of the node accordingly.\n\nThis node has multiple types of conditions: Bool, String, Number, and Date & Time.","resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/create-a-toxic-language-detector-for-telegram/","icon":"🤬","label":"Create a toxic language detector for Telegram in 4 step"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/automation-for-maintainers-of-open-source-projects/","icon":"🏷️","label":"How to automatically manage contributions to open-source projects"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.if/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow"]}}},"group":"[\"transform\"]","defaults":{"name":"If","color":"#408000"},"iconData":{"icon":"map-signs","type":"icon"},"displayName":"If","typeVersion":2,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":24,"icon":"file:merge.svg","name":"n8n-nodes-base.merge","codex":{"data":{"alias":["Join","Concatenate","Wait"],"resources":{"generic":[{"url":"https://n8n.io/blog/how-to-sync-data-between-two-systems/","icon":"🏬","label":"How to synchronize data between two systems (one-way vs. two-way sync"},{"url":"https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/","icon":"🎫","label":"Supercharging your conference registration process with n8n"},{"url":"https://n8n.io/blog/migrating-community-metrics-to-orbit-using-n8n/","icon":"📈","label":"Migrating Community Metrics to Orbit using n8n"},{"url":"https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/","icon":"👦","label":"Build your own virtual assistant with n8n: A step by step guide"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.merge/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow","Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Merge"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTc3XzUxOCkiPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTAgNDhDMCAyMS40OTAzIDIxLjQ5MDMgMCA0OCAwSDExMkMxMzguNTEgMCAxNjAgMjEuNDkwMyAxNjAgNDhWNTZIMTk2LjI1MkMyNDAuNDM1IDU2IDI3Ni4yNTIgOTEuODE3MiAyNzYuMjUyIDEzNlYxOTJDMjc2LjI1MiAyMTQuMDkxIDI5NC4xNjEgMjMyIDMxNi4yNTIgMjMySDM1MlYyMjRDMzUyIDE5Ny40OSAzNzMuNDkgMTc2IDQwMCAxNzZINDY0QzQ5MC41MSAxNzYgNTEyIDE5Ny40OSA1MTIgMjI0VjI4OEM1MTIgMzE0LjUxIDQ5MC41MSAzMzYgNDY0IDMzNkg0MDBDMzczLjQ5IDMzNiAzNTIgMzE0LjUxIDM1MiAyODhWMjgwSDMxNi4yNTJDMjk0LjE2MSAyODAgMjc2LjI1MiAyOTcuOTA5IDI3Ni4yNTIgMzIwVjM3NkMyNzYuMjUyIDQyMC4xODMgMjQwLjQzNSA0NTYgMTk2LjI1MiA0NTZIMTYwVjQ2NEMxNjAgNDkwLjUxIDEzOC41MSA1MTIgMTEyIDUxMkg0OEMyMS40OTAzIDUxMiAwIDQ5MC41MSAwIDQ2NFY0MDBDMCAzNzMuNDkgMjEuNDkwMyAzNTIgNDggMzUySDExMkMxMzguNTEgMzUyIDE2MCAzNzMuNDkgMTYwIDQwMFY0MDhIMTk2LjI1MkMyMTMuOTI1IDQwOCAyMjguMjUyIDM5My42NzMgMjI4LjI1MiAzNzZWMzIwQzIyOC4yNTIgMjk0Ljc4NCAyMzguODU5IDI3Mi4wNDQgMjU1Ljg1MyAyNTZDMjM4Ljg1OSAyMzkuOTU2IDIyOC4yNTIgMjE3LjIxNiAyMjguMjUyIDE5MlYxMzZDMjI4LjI1MiAxMTguMzI3IDIxMy45MjUgMTA0IDE5Ni4yNTIgMTA0SDE2MFYxMTJDMTYwIDEzOC41MSAxMzguNTEgMTYwIDExMiAxNjBINDhDMjEuNDkwMyAxNjAgMCAxMzguNTEgMCAxMTJWNDhaTTEwNCA0OEMxMDguNDE4IDQ4IDExMiA1MS41ODE3IDExMiA1NlYxMDRDMTEyIDEwOC40MTggMTA4LjQxOCAxMTIgMTA0IDExMkg1NkM1MS41ODE3IDExMiA0OCAxMDguNDE4IDQ4IDEwNFY1NkM0OCA1MS41ODE3IDUxLjU4MTcgNDggNTYgNDhIMTA0Wk00NTYgMjI0QzQ2MC40MTggMjI0IDQ2NCAyMjcuNTgyIDQ2NCAyMzJWMjgwQzQ2NCAyODQuNDE4IDQ2MC40MTggMjg4IDQ1NiAyODhINDA4QzQwMy41ODIgMjg4IDQwMCAyODQuNDE4IDQwMCAyODBWMjMyQzQwMCAyMjcuNTgyIDQwMy41ODIgMjI0IDQwOCAyMjRINDU2Wk0xMTIgNDA4QzExMiA0MDMuNTgyIDEwOC40MTggNDAwIDEwNCA0MDBINTZDNTEuNTgxNyA0MDAgNDggNDAzLjU4MiA0OCA0MDhWNDU2QzQ4IDQ2MC40MTggNTEuNTgxNyA0NjQgNTYgNDY0SDEwNEMxMDguNDE4IDQ2NCAxMTIgNDYwLjQxOCAxMTIgNDU2VjQwOFoiIGZpbGw9IiM1NEI4QzkiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTc3XzUxOCI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="},"displayName":"Merge","typeVersion":3,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":38,"icon":"fa:pen","name":"n8n-nodes-base.set","codex":{"data":{"alias":["Set","JS","JSON","Filter","Transform","Map"],"resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/automatically-pulling-and-visualizing-data-with-n8n/","icon":"📈","label":"Automatically pulling and visualizing data with n8n"},{"url":"https://n8n.io/blog/database-monitoring-and-alerting-with-n8n/","icon":"📡","label":"Database Monitoring and Alerting with n8n"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/building-an-expense-tracking-app-in-10-minutes/","icon":"📱","label":"Building an expense tracking app in 10 minutes"},{"url":"https://n8n.io/blog/the-ultimate-guide-to-automate-your-video-collaboration-with-whereby-mattermost-and-n8n/","icon":"📹","label":"The ultimate guide to automate your video collaboration with Whereby, Mattermost, and n8n"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/learn-to-build-powerful-api-endpoints-using-webhooks/","icon":"🧰","label":"Learn to Build Powerful API Endpoints Using Webhooks"},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/a-low-code-bitcoin-ticker-built-with-questdb-and-n8n-io/","icon":"📈","label":"A low-code bitcoin ticker built with QuestDB and n8n.io"},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Data Transformation"]}}},"group":"[\"input\"]","defaults":{"name":"Edit Fields"},"iconData":{"icon":"pen","type":"icon"},"displayName":"Edit Fields (Set)","typeVersion":3,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":47,"icon":"file:webhook.svg","name":"n8n-nodes-base.webhook","codex":{"data":{"alias":["HTTP","API","Build","WH"],"resources":{"generic":[{"url":"https://n8n.io/blog/learn-how-to-automatically-cross-post-your-content-with-n8n/","icon":"✍️","label":"Learn how to automatically cross-post your content with n8n"},{"url":"https://n8n.io/blog/running-n8n-on-ships-an-interview-with-maranics/","icon":"🛳","label":"Running n8n on ships: An interview with Maranics"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/what-are-apis-how-to-use-them-with-no-code/","icon":" 🪢","label":"What are APIs and how to use them with no code"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/how-a-digital-strategist-uses-n8n-for-online-marketing/","icon":"💻","label":"How a digital strategist uses n8n for online marketing"},{"url":"https://n8n.io/blog/the-ultimate-guide-to-automate-your-video-collaboration-with-whereby-mattermost-and-n8n/","icon":"📹","label":"The ultimate guide to automate your video collaboration with Whereby, Mattermost, and n8n"},{"url":"https://n8n.io/blog/how-to-automatically-give-kudos-to-contributors-with-github-slack-and-n8n/","icon":"👏","label":"How to automatically give kudos to contributors with GitHub, Slack, and n8n"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/creating-custom-incident-response-workflows-with-n8n/","label":"How to automate every step of an incident response workflow"},{"url":"https://n8n.io/blog/learn-to-build-powerful-api-endpoints-using-webhooks/","icon":"🧰","label":"Learn to Build Powerful API Endpoints Using Webhooks"},{"url":"https://n8n.io/blog/learn-how-to-use-webhooks-with-mattermost-slash-commands/","icon":"🦄","label":"Learn how to use webhooks with Mattermost slash commands"},{"url":"https://n8n.io/blog/how-goomer-automated-their-operations-with-over-200-n8n-workflows/","icon":"🛵","label":"How Goomer automated their operations with over 200 n8n workflows"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"trigger\"]","defaults":{"name":"Webhook"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCI+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTM1IDM3Yy0yLjIgMC00LTEuOC00LTRzMS44LTQgNC00IDQgMS44IDQgNC0xLjggNC00IDQiLz48cGF0aCBmaWxsPSIjMzc0NzRmIiBkPSJNMzUgNDNjLTMgMC01LjktMS40LTcuOC0zLjdsMy4xLTIuNWMxLjEgMS40IDIuOSAyLjMgNC43IDIuMyAzLjMgMCA2LTIuNyA2LTZzLTIuNy02LTYtNmMtMSAwLTIgLjMtMi45LjdsLTEuNyAxTDIzLjMgMTZsMy41LTEuOSA1LjMgOS40YzEtLjMgMi0uNSAzLS41IDUuNSAwIDEwIDQuNSAxMCAxMFM0MC41IDQzIDM1IDQzIi8+PHBhdGggZmlsbD0iIzM3NDc0ZiIgZD0iTTE0IDQzQzguNSA0MyA0IDM4LjUgNCAzM2MwLTQuNiAzLjEtOC41IDcuNS05LjdsMSAzLjlDOS45IDI3LjkgOCAzMC4zIDggMzNjMCAzLjMgMi43IDYgNiA2czYtMi43IDYtNnYtMmgxNXY0SDIzLjhjLS45IDQuNi01IDgtOS44IDgiLz48cGF0aCBmaWxsPSIjZTkxZTYzIiBkPSJNMTQgMzdjLTIuMiAwLTQtMS44LTQtNHMxLjgtNCA0LTQgNCAxLjggNCA0LTEuOCA0LTQgNCIvPjxwYXRoIGZpbGw9IiMzNzQ3NGYiIGQ9Ik0yNSAxOWMtMi4yIDAtNC0xLjgtNC00czEuOC00IDQtNCA0IDEuOCA0IDQtMS44IDQtNCA0Ii8+PHBhdGggZmlsbD0iI2U5MWU2MyIgZD0ibTE1LjcgMzQtMy40LTIgNS45LTkuN2MtMi0xLjktMy4yLTQuNS0zLjItNy4zIDAtNS41IDQuNS0xMCAxMC0xMHMxMCA0LjUgMTAgMTBjMCAuOS0uMSAxLjctLjMgMi41bC0zLjktMWMuMS0uNS4yLTEgLjItMS41IDAtMy4zLTIuNy02LTYtNnMtNiAyLjctNiA2YzAgMi4xIDEuMSA0IDIuOSA1LjFsMS43IDF6Ii8+PC9zdmc+"},"displayName":"Webhook","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":565,"icon":"fa:sticky-note","name":"n8n-nodes-base.stickyNote","codex":{"data":{"alias":["Comments","Notes","Sticky"],"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"input\"]","defaults":{"name":"Sticky Note","color":"#FFD233"},"iconData":{"icon":"sticky-note","type":"icon"},"displayName":"Sticky Note","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":834,"icon":"file:code.svg","name":"n8n-nodes-base.code","codex":{"data":{"alias":["cpde","Javascript","JS","Python","Script","Custom Code","Function"],"details":"The Code node allows you to execute JavaScript in your workflow.","resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers","Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Code"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="},"displayName":"Code","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":1119,"icon":"fa:robot","name":"@n8n/n8n-nodes-langchain.agent","codex":{"data":{"alias":["LangChain","Chat","Conversational","Plan and Execute","ReAct","Tools"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Agents","Root Nodes"]}}},"group":"[\"transform\"]","defaults":{"name":"AI Agent","color":"#404040"},"iconData":{"icon":"robot","type":"icon"},"displayName":"AI Agent","typeVersion":3,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]},{"id":1179,"icon":"fa:code","name":"@n8n/n8n-nodes-langchain.outputParserStructured","codex":{"data":{"alias":["json","zod"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.outputparserstructured/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Output Parsers"]}}},"group":"[\"transform\"]","defaults":{"name":"Structured Output Parser"},"iconData":{"icon":"code","type":"icon"},"displayName":"Structured Output Parser","typeVersion":1,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]},{"id":1239,"icon":"file:splitOut.svg","name":"n8n-nodes-base.splitOut","codex":{"data":{"alias":["Split","Nested","Transform","Array","List","Item"],"details":"","resources":{"generic":[],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitout/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Split Out"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJub25lIj48ZyBmaWxsPSIjOUI2REQ1IiBjbGlwLXBhdGg9InVybCgjYSkiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTQ4MCAxNDhjMC02LjYyNy01LjM3My0xMi0xMi0xMkgzMjJjLTYuNjI3IDAtMTIgNS4zNzMtMTIgMTJ2MjRjMCA2LjYyNyA1LjM3MyAxMiAxMiAxMmgxNDZjNi42MjcgMCAxMi01LjM3MyAxMi0xMnptMCA5NmMwLTYuNjI3LTUuMzczLTEyLTEyLTEySDMyMmMtNi42MjcgMC0xMiA1LjM3My0xMiAxMnYyNGMwIDYuNjI3IDUuMzczIDEyIDEyIDEyaDE0NmM2LjYyNyAwIDEyLTUuMzczIDEyLTEyem0wIDk2YzAtNi42MjctNS4zNzMtMTItMTItMTJIMzIyYy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0YzAgNi42MjcgNS4zNzMgMTIgMTIgMTJoMTQ2YzYuNjI3IDAgMTItNS4zNzMgMTItMTJ6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBkPSJNNDM4IDc2YzAgNi42MjctNS4zNzMgMTItMTIgMTJIMzA5Ljc4M2MtMTcuNjczIDAtMzIgMTQuMzI3LTMyIDMydjU2YzAgMjYuOTc4LTEwLjI3MiA1MS41NTctMjcuMTE5IDcwLjAzOS01LjA1NSA1LjU0NS01LjA1NSAxNC4zNzcgMCAxOS45MjIgMTYuODQ3IDE4LjQ4MiAyNy4xMTkgNDMuMDYxIDI3LjExOSA3MC4wMzl2NTZjMCAxNy42NzMgMTQuMzI3IDMyIDMyIDMySDQyNmM2LjYyNyAwIDEyIDUuMzczIDEyIDEydjI0YzAgNi42MjctNS4zNzMgMTItMTIgMTJIMzA5Ljc4M2MtNDQuMTgzIDAtODAtMzUuODE3LTgwLTgwdi01NmMwLTMwLjkyOC0yNS4wNzItNTYtNTYtNTZhNS43ODMgNS43ODMgMCAwIDEtNS43ODMtNS43ODN2LTM2LjQzNGE1Ljc4MyA1Ljc4MyAwIDAgMSA1Ljc4My01Ljc4M2MzMC45MjggMCA1Ni0yNS4wNzIgNTYtNTZ2LTU2YzAtNDQuMTgzIDM1LjgxNy04MCA4MC04MEg0MjZjNi42MjcgMCAxMiA1LjM3MyAxMiAxMnoiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMzYgMjQ0YzAtNi42MjctNS4zNzMtMTItMTItMTJIMTJjLTYuNjI3IDAtMTIgNS4zNzMtMTIgMTJ2MjRjMCA2LjYyNyA1LjM3MyAxMiAxMiAxMmgxMTJjNi42MjcgMCAxMi01LjM3MyAxMi0xMnoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik01MTIgMEgwdjUxMmg1MTJ6Ii8+PC9jbGlwUGF0aD48L2RlZnM+PC9zdmc+"},"displayName":"Split Out","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":1253,"icon":"file:azure.svg","name":"@n8n/n8n-nodes-langchain.lmChatAzureOpenAi","codex":{"data":{"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatazureopenai/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Language Models","Root Nodes"],"Language Models":["Chat Models (Recommended)"]}}},"group":"[\"transform\"]","defaults":{"name":"Azure OpenAI Chat Model"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTYiIGhlaWdodD0iMjQyIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iNTguOTcyJSIgeDI9IjM3LjE5MSUiIHkxPSI3LjQxMSUiIHkyPSIxMDMuNzYyJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzExNEE4QiIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzA2NjlCQyIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJiIiB4MT0iNTkuNzE5JSIgeDI9IjUyLjY5MSUiIHkxPSI1Mi4zMTMlIiB5Mj0iNTQuODY0JSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1vcGFjaXR5PSIuMyIvPjxzdG9wIG9mZnNldD0iNy4xJSIgc3RvcC1vcGFjaXR5PSIuMiIvPjxzdG9wIG9mZnNldD0iMzIuMSUiIHN0b3Atb3BhY2l0eT0iLjEiLz48c3RvcCBvZmZzZXQ9IjYyLjMlIiBzdG9wLW9wYWNpdHk9Ii4wNSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1vcGFjaXR5PSIwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImMiIHgxPSIzNy4yNzklIiB4Mj0iNjIuNDczJSIgeTE9IjQuNiUiIHkyPSI5OS45NzklIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjM0NDQkY0Ii8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjMjg5MkRGIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHBhdGggZmlsbD0idXJsKCNhKSIgZD0iTTg1LjM0My4wMDNoNzUuNzUzTDgyLjQ1NyAyMzNhMTIuMDggMTIuMDggMCAwIDEtMTEuNDQyIDguMjE2SDEyLjA2QTEyLjA2IDEyLjA2IDAgMCAxIC42MzMgMjI1LjMwM0w3My44OTggOC4yMTlBMTIuMDggMTIuMDggMCAwIDEgODUuMzQzIDB6Ii8+PHBhdGggZmlsbD0iIzAwNzhENCIgZD0iTTE5NS40MjMgMTU2LjI4Mkg3NS4yOTdhNS41NiA1LjU2IDAgMCAwLTMuNzk2IDkuNjI3bDc3LjE5IDcyLjA0N2ExMi4xNCAxMi4xNCAwIDAgMCA4LjI4IDMuMjZoNjguMDJ6Ii8+PHBhdGggZmlsbD0idXJsKCNiKSIgZD0iTTg1LjM0My4wMDNhMTEuOTggMTEuOTggMCAwIDAtMTEuNDcxIDguMzc2TC43MjMgMjI1LjEwNWExMi4wNDUgMTIuMDQ1IDAgMCAwIDExLjM3IDE2LjExMmg2MC40NzVhMTIuOTMgMTIuOTMgMCAwIDAgOS45MjEtOC40MzdsMTQuNTg4LTQyLjk5MSA1Mi4xMDUgNDguNmExMi4zMyAxMi4zMyAwIDAgMCA3Ljc1NyAyLjgyOGg2Ny43NjZsLTI5LjcyMS04NC45MzUtODYuNjQzLjAyTDE2MS4zNy4wMDN6Ii8+PHBhdGggZmlsbD0idXJsKCNjKSIgZD0iTTE4Mi4wOTggOC4yMDdBMTIuMDYgMTIuMDYgMCAwIDAgMTcwLjY3LjAwM0g4Ni4yNDVjNS4xNzUgMCA5Ljc3MyAzLjMwMSAxMS40MjggOC4yMDRMMTcwLjk0IDIyNS4zYTEyLjA2MiAxMi4wNjIgMCAwIDEtMTEuNDI4IDE1LjkyaDg0LjQyOWExMi4wNjIgMTIuMDYyIDAgMCAwIDExLjQyNS0xNS45MnoiLz48L3N2Zz4="},"displayName":"Azure OpenAI Chat Model","typeVersion":1,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]}],"categories":[{"id":5,"name":"Engineering"},{"id":49,"name":"AI Summarization"}],"image":[]}}