AutomationFlowsSlack & Telegram › Automated Slack-to-jira Issue Creation with Attachments

Automated Slack-to-jira Issue Creation with Attachments

ByRahul Joshi @rahul08 on n8n.io

Automatically convert structured Slack messages into Jira issues with parsed titles, descriptions, and priorities. This workflow also downloads file attachments from Slack (e.g., screenshots, logs, or documents) and uploads them directly into the created Jira issue. It then…

Event trigger★★★★☆ complexity19 nodesSlack TriggerJiraSlackHTTP Request
Slack & Telegram Trigger: Event Nodes: 19 Complexity: ★★★★☆ Added:
Automated Slack-to-jira Issue Creation with Attachments — n8n workflow card showing Slack Trigger, Jira, Slack integration

This workflow corresponds to n8n.io template #8813 — we link there as the canonical source.

This workflow follows the HTTP Request → Slack recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "UWaBGGumTuGmryJq",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automated Slack-to-Jira Issue Creation with Attachments",
  "tags": [
    {
      "id": "SHQpff6D2VUAhiBO",
      "name": "slack-integration",
      "createdAt": "2025-09-03T10:01:17.871Z",
      "updatedAt": "2025-09-03T10:01:17.871Z"
    },
    {
      "id": "us8CC0JZKBaYTMbE",
      "name": "automation",
      "createdAt": "2025-09-03T10:01:17.853Z",
      "updatedAt": "2025-09-03T10:01:17.853Z"
    }
  ],
  "nodes": [
    {
      "id": "9a2f9325-f367-4178-b57f-da06ce268aa3",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1472,
        2544
      ],
      "parameters": {
        "color": 5,
        "height": 320,
        "content": "Purpose: Attaches downloaded files to created Jira issue\n\nFunction: Uploads binary file data to \nspecific Jira ticket\n\nUse Case: Preserves screenshots/documentation from Slack in Jira\n\nInput: Jira issue key + file binary data\nResult: File becomes viewable in Jira issue"
      },
      "typeVersion": 1
    },
    {
      "id": "45ca44bb-fcf5-4892-8915-b5b561d489ee",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        800,
        2240
      ],
      "parameters": {
        "color": 3,
        "height": 320,
        "content": "Purpose: Downloads files from Slack using private URLs\n\nFunction: Fetches attachment data with Slack bot token authentication\n\nUse Case: Retrieves screenshots/files to attach to Jira issue\nAuthentication: Bearer YOUR_TOKEN_HERE in header\n\nResponse: File data in binary format"
      },
      "typeVersion": 1
    },
    {
      "id": "a9b50384-69f7-4325-b209-9b8b0980d4fd",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -96,
        3088
      ],
      "parameters": {
        "color": 6,
        "height": 272,
        "content": "Purpose: Creates new Jira issue with parsed data\n\nFunction: Submits ticket to specified Jira project.\n\nUse Case: Automatically creates trackable issues from Slack reports\n\nOutput: Jira issue details including unique issue key"
      },
      "typeVersion": 1
    },
    {
      "id": "89199791-4879-47be-8d99-f6b5be1eb3e2",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        2480
      ],
      "parameters": {
        "color": 2,
        "height": 384,
        "content": "Purpose: Extracts structured issue details from Slack message text\n\nFunction: Uses regex to parse Title, Description, Priority from message\n\nUse Case: Converts \"Title: X Description: Y Priority: Z\" format to structured data\nKey Features:\n\nExtracts title, description, priority using regex patterns\nMaps Slack priorities (high/medium/low) to Jira format"
      },
      "typeVersion": 1
    },
    {
      "id": "618371b4-bf61-4a9e-b76a-8081716eef8c",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -896,
        2544
      ],
      "parameters": {
        "height": 352,
        "content": "Purpose: Monitors specific Slack channel for new messages\n\nFunction: Automatically triggers workflow when message posted\n\nUse Case: Captures issue reports from  channel.\n\nConfiguration: Listens for message events only\n\nOutput: Raw Slack message data with text, user, files, timestamps"
      },
      "typeVersion": 1
    },
    {
      "id": "bcabc988-0058-4e65-8e1e-cf7d32dacfec",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        2976
      ],
      "parameters": {
        "color": 4,
        "height": 224,
        "content": "Purpose: Sends confirmation message back to Slack\n\nFunction: Posts success notification in tickets channel\n\nUse Case: Confirms issue creation and provides Jira tracking info"
      },
      "typeVersion": 1
    },
    {
      "id": "31b4df31-3567-40b3-b44d-06a2f9e5abcd",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        2592
      ],
      "parameters": {
        "color": 3,
        "height": 288,
        "content": "Purpose: Splits multiple attachments into individual items for processing\n\nFunction: Loops through each attachment one by one\n\nUse Case: Handles multiple file uploads from Slack message\n\nOutput: Individual attachment items that can be processed sequentially"
      },
      "typeVersion": 1
    },
    {
      "id": "9c766474-c73f-4579-a938-e7a02e7e88e2",
      "name": "Sticky Note - Split Files",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        2512
      ],
      "parameters": {
        "color": 5,
        "height": 240,
        "content": "NEW: Splits all files into individual batches\n\nPurpose: Processes each attachment separately\n\nFunction: Takes files array and creates one execution per file\n\nBenefit: Enables uploading multiple attachments to Jira"
      },
      "typeVersion": 1
    },
    {
      "id": "df70376c-d7cd-48ae-a90d-f9ae05647257",
      "name": "Slack Trigger",
      "type": "n8n-nodes-base.slackTrigger",
      "position": [
        -720,
        2912
      ],
      "parameters": {
        "options": {},
        "trigger": [
          "message"
        ],
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09CVLMSF3R",
          "cachedResultName": "issue-smarteremr"
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "65a9703b-d356-442c-99a5-8d2351843374",
      "name": "Prepare Files for Processing",
      "type": "n8n-nodes-base.code",
      "position": [
        400,
        2784
      ],
      "parameters": {
        "jsCode": "// Extract files from Parse Message and prepare them for batch processing\nconst parseMessageData = $('Parse Message into Jira Format').first().json;\nconst jiraIssueData = $('Create Jira Issue').first().json;\n\nconsole.log('Parse Message Data:', JSON.stringify(parseMessageData, null, 2));\nconsole.log('Jira Issue Data:', JSON.stringify(jiraIssueData, null, 2));\n\n// Extract files from the attachments array (not files array)\nconst files = parseMessageData.attachments || [];\nconst jiraIssueKey = jiraIssueData.key;\n\nconsole.log(`Found ${files.length} files to process`);\nconsole.log('Jira Issue Key:', jiraIssueKey);\n\n// Return each file as a separate item with the Jira issue key\nconst items = files.map((file, index) => {\n  return {\n    fileId: file.id,\n    fileName: file.name || file.title || `file_${index}`,\n    fileUrl: file.url, // Use the url property from your attachments\n    jiraIssueKey: jiraIssueKey,\n    fileIndex: index,\n    totalFiles: files.length,\n    originalFile: file\n  };\n});\n\nconsole.log('Prepared items for batch processing:', JSON.stringify(items, null, 2));\n\nreturn items;"
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "3b52b68f-beb7-4f72-a1db-439761d9235a",
      "name": "Split Files into Batches",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        624,
        2784
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "23c27f8e-283e-4247-9103-1cf5b8052801",
      "name": "Upload Attachment to Jira",
      "type": "n8n-nodes-base.jira",
      "position": [
        1296,
        2736
      ],
      "parameters": {
        "issueKey": "={{ $('Split Files into Batches').item.json.jiraIssueKey }}",
        "resource": "issueAttachment"
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "749ae50d-dec2-4245-a560-24b689250fdc",
      "name": "checking message",
      "type": "n8n-nodes-base.if",
      "position": [
        -496,
        2912
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0eb704ae-11e8-4588-a0fb-02b1f7c1cde7",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.text }}",
              "rightValue": "title"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e74b893a-4c33-4de3-bc1e-d82f2f792e7a",
      "name": "Reply to Channel On Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        848,
        2784
      ],
      "parameters": {
        "text": "=\u2705 Jira Issue Created Successfully!\n\n\ud83c\udfab Issue Key: https://herevivekpatidar.atlassian.net/browse/{{ $('Create Jira Issue').item.json.key }}\n\n\ud83d\udcdd Title: {{ $('Parse Message into Jira Format').item.json.summary }} \n\n\ud83d\udcdd Description:{{ $('Parse Message into Jira Format').item.json.extractedData.descriptionMatch }}\n\n\ud83d\udccb issueType: {{ $('Parse Message into Jira Format').item.json.issueTypeName }}\n\n\u26a1Priority: {{ $('Parse Message into Jira Format').item.json.priority }}\n\n\ud83d\udcce Attachments: {{ $('Parse Message into Jira Format').item.json.files.length }} file(s) uploaded\n\nThank you for reporting this issue!",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09D7N4MXFF",
          "cachedResultName": "tickets"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "68fa2a54-85a5-42cb-99c1-3a6c398a7226",
      "name": "Parse Message into Jira Format",
      "type": "n8n-nodes-base.code",
      "position": [
        -272,
        2912
      ],
      "parameters": {
        "jsCode": "// Enhanced Parse Slack message - handles both plain text and rich text blocks\nconst message = $input.first().json;\nlet text = message.text || '';\nconst user = message.user || '';\nconst channel = message.channel || '';\nconst files = message.files || [];\nconst timestamp = message.ts || '';\nconst blocks = message.blocks || [];\n\nconsole.log('Original text length:', text.length);\nconsole.log('Blocks found:', blocks.length);\nconsole.log('Files found:', files.length);\n\n// Extract text from rich text blocks if available (this gives us complete text)\nif (blocks && blocks.length > 0) {\n  let richText = '';\n  \n  blocks.forEach(block => {\n    if (block.type === 'rich_text' && block.elements) {\n      block.elements.forEach(element => {\n        if (element.type === 'rich_text_section' && element.elements) {\n          element.elements.forEach(textElement => {\n            if (textElement.type === 'text') {\n              richText += textElement.text || '';\n            }\n          });\n        } else if (element.type === 'rich_text_list' && element.elements) {\n          // Handle bullet points and lists\n          element.elements.forEach(listItem => {\n            if (listItem.elements) {\n              richText += '\\n\u2022 ';\n              listItem.elements.forEach(listTextElement => {\n                if (listTextElement.type === 'text') {\n                  richText += listTextElement.text || '';\n                }\n              });\n            }\n          });\n        }\n      });\n    }\n  });\n  \n  // Use rich text if it's longer and contains more content\n  if (richText.length > text.length) {\n    console.log('Using rich text content (length:', richText.length, ')');\n    text = richText;\n  }\n}\n\nconsole.log('Final text length:', text.length);\nconsole.log('Text preview:', text.substring(0, 200) + '...');\n\n// Log file details for debugging\nfiles.forEach((file, index) => {\n  console.log(`File ${index}:`, {\n    id: file.id,\n    name: file.name,\n    mimetype: file.mimetype,\n    size: file.size,\n    filetype: file.filetype\n  });\n});\n\n// Robust regex patterns for title*:* format with flexible spacing\nconst titleMatch = text.match(/title\\s*\\*?\\s*:\\s*\\*?\\s*([^\\n]*?)(?=\\s*(?:\\n|$))/i);\n\n// For description, capture everything after description*:* until we hit priority: or type:\nconst descriptionMatch = text.match(/description\\s*\\*?\\s*:\\s*\\*?\\s*([\\s\\S]*?)(?=\\s*priority\\s*\\*?\\s*:\\s*\\*?|$)/i);\n\n// Priority - capture just the value after priority:\nconst priorityMatch = text.match(/priority\\s*\\*?\\s*:\\s*\\*?\\s*([^\\n]*?)(?=\\s*(?:\\n|$))/i);\n\n// Type - capture just the value after type:\nconst typeMatch = text.match(/type\\s*\\*?\\s*:\\s*\\*?\\s*([^\\n]*?)(?=\\s*(?:\\n|$))/i);\n\n// Enhanced text cleaning function\nconst cleanText = (str) => {\n  if (!str) return null;\n  \n  return str\n    .replace(/^\\s*[\\*_\\-\\+=]*\\s*/, '') // Remove leading special characters\n    .replace(/\\s*[\\*_\\-\\+=]*\\s*$/, '') // Remove trailing special characters\n    .replace(/\\*+/g, '') // Remove asterisks\n    .replace(/_{2,}/g, '') // Remove multiple underscores\n    .replace(/^\\s+/gm, '') // Remove leading whitespace from lines\n    .replace(/\\s+$/gm, '') // Remove trailing whitespace from lines\n    .replace(/\\n\\s*\\n+/g, '\\n\\n') // Normalize multiple newlines\n    .trim();\n};\n\n// Clean and extract values\nconst extractedTitle = titleMatch ? cleanText(titleMatch[1]) : null;\nconst extractedDescription = descriptionMatch ? cleanText(descriptionMatch[1]) : null;\nconst extractedPriority = priorityMatch ? cleanText(priorityMatch[1]) : null;\nconst extractedType = typeMatch ? cleanText(typeMatch[1]) : null;\n\n// Enhanced logging\nconsole.log('=== EXTRACTION RESULTS ===');\nconsole.log('Title match:', !!titleMatch, '- Value:', extractedTitle);\nconsole.log('Description match:', !!descriptionMatch, '- Length:', extractedDescription ? extractedDescription.length : 0);\nconsole.log('Priority match:', !!priorityMatch, '- Value:', extractedPriority);\nconsole.log('Type match:', !!typeMatch, '- Value:', extractedType);\n\n// Smart fallback logic\nconst summary = (extractedTitle && extractedTitle.length > 3) ? \n               extractedTitle : 'Issue reported from Slack';\n\nconst description = (extractedDescription && extractedDescription.length > 5) ? \n                   extractedDescription : 'No description provided';\n\n// Enhanced priority parsing\nconst determinePriority = (priorityText) => {\n  if (!priorityText) return 'medium';\n  \n  const lowerPriority = priorityText.toLowerCase().trim();\n  const cleanPriority = lowerPriority.replace(/[^\\w\\s]/g, '').trim();\n  \n  if (['critical', 'urgent', 'highest', 'blocker'].includes(cleanPriority)) return 'critical';\n  if (['high'].includes(cleanPriority)) return 'high';\n  if (['medium', 'med', 'normal', 'moderate'].includes(cleanPriority)) return 'medium';\n  if (['low', 'lowest', 'minor'].includes(cleanPriority)) return 'low';\n  \n  if (cleanPriority.includes('critical') || cleanPriority.includes('urgent')) return 'critical';\n  if (cleanPriority.includes('high')) return 'high';\n  if (cleanPriority.includes('low')) return 'low';\n  \n  return 'medium';\n};\n\n// Enhanced issue type parsing\nconst determineIssueType = (typeText) => {\n  if (!typeText) return 'enhancement';\n  \n  const lowerType = typeText.toLowerCase().trim();\n  const cleanType = lowerType.replace(/[^\\w\\s]/g, '').trim();\n  \n  const typeMapping = {\n    'bug': 'bug', 'issue': 'bug', 'defect': 'bug', 'error': 'bug', 'problem': 'bug',\n    'feature': 'feature', 'story': 'feature', 'request': 'feature', 'new': 'feature',\n    'enhancement': 'enhancement', 'improvement': 'enhancement', 'modify': 'enhancement', \n    'change': 'enhancement', 'update': 'enhancement', 'enhance': 'enhancement',\n    'task': 'task', 'todo': 'task', 'work': 'task', 'chore': 'task',\n    'epic': 'epic'\n  };\n  \n  if (typeMapping[cleanType]) return typeMapping[cleanType];\n  \n  for (const [key, value] of Object.entries(typeMapping)) {\n    if (cleanType.includes(key)) return value;\n  }\n  \n  return 'enhancement';\n};\n\nconst priority = determinePriority(extractedPriority);\nconst issueType = determineIssueType(extractedType);\n\n// Map to Jira values with IDs\nconst priorityMapping = {\n  'critical': { name: 'Highest', id: '1' },\n  'high': { name: 'High', id: '2' },\n  'medium': { name: 'Medium', id: '3' },\n  'low': { name: 'Low', id: '4' }\n};\nconst jiraPriorityObj = priorityMapping[priority] || priorityMapping['medium'];\nconst jiraPriority = jiraPriorityObj.name;\nconst jiraPriorityId = jiraPriorityObj.id;\n\nconst issueTypeMapping = {\n  'bug': '10041',\n  'feature': '10004',\n  'enhancement': '10008',\n  'task': '10008',\n  'epic': '10000'\n};\nconst jiraIssueType = issueTypeMapping[issueType] || '10008';\n\n// Enhanced file processing\nconst attachments = files.map(file => {\n  let downloadUrl = null;\n  \n  if (file.url_private_download && file.url_private_download.startsWith('https://')) {\n    downloadUrl = file.url_private_download;\n  } else if (file.url_private && file.url_private.startsWith('https://')) {\n    downloadUrl = file.url_private;\n  } else if (file.permalink && file.permalink.startsWith('https://')) {\n    downloadUrl = file.permalink;\n  } else if (file.url_download && file.url_download.startsWith('https://')) {\n    downloadUrl = file.url_download;\n  }\n  \n  const isVideo = file.mimetype && file.mimetype.startsWith('video/') || \n                  ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv'].includes(file.filetype?.toLowerCase());\n  const isLargeFile = file.size && file.size > 10485760;\n  \n  return {\n    id: file.id || 'unknown',\n    name: file.name || file.title || 'unnamed_file',\n    url: downloadUrl,\n    size: file.size || 0,\n    mimetype: file.mimetype || 'application/octet-stream',\n    filetype: file.filetype || 'unknown',\n    isVideo: isVideo,\n    isLargeFile: isLargeFile,\n    sizeFormatted: file.size ? `${(file.size / 1024 / 1024).toFixed(2)} MB` : 'Unknown size'\n  };\n}).filter(att => att.url);\n\n// Create clean Jira description\nlet jiraDescription = '';\n\nif (extractedDescription) {\n  jiraDescription = extractedDescription + '\\n\\n';\n}\n\n// Add metadata\njiraDescription += `**Reported by:** <@${user}>\\n`;\njiraDescription += `**Channel:** <#${channel}>\\n`;\njiraDescription += `**Timestamp:** ${new Date(parseFloat(timestamp) * 1000).toISOString()}`;\n\n// Add attachments info if present\nif (attachments.length > 0) {\n  jiraDescription += '\\n\\n**Attachments:**\\n';\n  attachments.forEach((att, index) => {\n    jiraDescription += `${index + 1}. ${att.name} (${att.sizeFormatted})`;\n    if (att.isVideo) jiraDescription += ' [VIDEO]';\n    if (att.isLargeFile) jiraDescription += ' [LARGE FILE]';\n    jiraDescription += '\\n';\n  });\n}\n\nreturn {\n  summary,\n  description: jiraDescription,\n  priority: jiraPriority,\n  priorityId: jiraPriorityId,\n  issueType: jiraIssueType,\n  issueTypeName: issueType,\n  reporter: user,\n  attachments,\n  originalText: text,\n  \n  // Clear extraction results\n  extractedData: {\n    titleMatch: extractedTitle,\n    descriptionMatch: extractedDescription,\n    priorityMatch: extractedPriority,\n    typeMatch: extractedType,\n    \n    // Debugging info\n    parsing: {\n      titleFound: !!titleMatch,\n      descriptionFound: !!descriptionMatch,\n      priorityFound: !!priorityMatch,\n      typeFound: !!typeMatch,\n      titleLength: extractedTitle ? extractedTitle.length : 0,\n      descriptionLength: extractedDescription ? extractedDescription.length : 0,\n      usedRichText: blocks.length > 0\n    }\n  },\n  \n  files: {\n    totalFiles: files.length,\n    validAttachments: attachments.length,\n    videoFiles: attachments.filter(att => att.isVideo).length,\n    largeFiles: attachments.filter(att => att.isLargeFile).length,\n    attachmentDetails: attachments.map(att => ({\n      name: att.name,\n      size: att.sizeFormatted,\n      type: att.filetype,\n      isVideo: att.isVideo,\n      isLarge: att.isLargeFile\n    }))\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "a16fadd8-597b-4791-9737-14a22a578d55",
      "name": "Create Jira Issue",
      "type": "n8n-nodes-base.jira",
      "position": [
        -48,
        2912
      ],
      "parameters": {
        "project": {
          "__rl": true,
          "mode": "list",
          "value": "10001",
          "cachedResultName": "Kanban"
        },
        "summary": "={{ $('Parse Message into Jira Format').item.json.summary }}",
        "issueType": {
          "__rl": true,
          "mode": "list",
          "value": "10006",
          "cachedResultName": "Task"
        },
        "additionalFields": {
          "assignee": {
            "__rl": true,
            "mode": "list",
            "value": "712020:d36fa274-fdb6-45c4-a2c5-8c53a89342d4",
            "cachedResultName": "Vivek Patidar"
          },
          "reporter": {
            "__rl": true,
            "mode": "list",
            "value": "712020:d36fa274-fdb6-45c4-a2c5-8c53a89342d4",
            "cachedResultName": "Vivek Patidar"
          },
          "description": "={{ $('Parse Message into Jira Format').item.json.extractedData.descriptionMatch }}"
        }
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a543ed0b-81a9-4391-a239-82d6d5b06cc1",
      "name": "Check Attachments",
      "type": "n8n-nodes-base.if",
      "position": [
        176,
        2912
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition1",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $('Parse Message into Jira Format').item.json.files.totalFiles }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "cbe776cf-6812-43d0-a9d3-034688b23f98",
      "name": "Get File Info",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        848,
        2592
      ],
      "parameters": {
        "url": "=https://slack.com/api/files.info?file={{ $json.fileId }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{$credentials.slackApi.accessToken}}"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "29408946-d34e-46d6-90fc-50e8477e8f2f",
      "name": "Download Attachment",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1072,
        2592
      ],
      "parameters": {
        "url": "={{ $json.file.url_private_download }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{$credentials.slackApi.accessToken}}"
            }
          ]
        }
      },
      "typeVersion": 4.1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9d97b85d-0648-470a-8c5a-ed257f4ac92d",
  "connections": {
    "Get File Info": {
      "main": [
        [
          {
            "node": "Download Attachment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack Trigger": {
      "main": [
        [
          {
            "node": "checking message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "checking message": {
      "main": [
        [
          {
            "node": "Parse Message into Jira Format",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Attachments": {
      "main": [
        [
          {
            "node": "Prepare Files for Processing",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reply to Channel On Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Jira Issue": {
      "main": [
        [
          {
            "node": "Check Attachments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Attachment": {
      "main": [
        [
          {
            "node": "Upload Attachment to Jira",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Files into Batches": {
      "main": [
        [
          {
            "node": "Reply to Channel On Slack",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get File Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Attachment to Jira": {
      "main": [
        [
          {
            "node": "Split Files into Batches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Files for Processing": {
      "main": [
        [
          {
            "node": "Split Files into Batches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Message into Jira Format": {
      "main": [
        [
          {
            "node": "Create Jira Issue",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Automatically convert structured Slack messages into Jira issues with parsed titles, descriptions, and priorities. This workflow also downloads file attachments from Slack (e.g., screenshots, logs, or documents) and uploads them directly into the created Jira issue. It then…

Source: https://n8n.io/workflows/8813/ — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

Type in Slack. Walk away. Get a professional PDF report and a structured Excel fix sheet delivered to Google Drive and posted back in your Slack thread — fully automated, zero manual work.

Compression, HTTP Request, Google Drive +3
Slack & Telegram

This workflow automates the full company enrichment pipeline: Simply import CSV company lists to Slack and save time on enrichment and CRM maintenance. It processes uploaded files, extracts company do

Slack Trigger, Slack, HTTP Request +3
Slack & Telegram

This workflow is an AI-powered roto matte generation and first-pass compositing pipeline designed for VFX production. It transforms structured roto requests into multiple high-precision matte passes u

HTTP Request, Slack, Error Trigger +4
Slack & Telegram

This n8n template from Intuz provides a complete and automated solution for preparing and delivering context-rich briefings directly to attendees before every meeting.

Google Calendar Trigger, Notion, GitHub +3
Slack & Telegram

This workflow enables seamless, bidirectional communication between WhatsApp and Slack using n8n. It automates the reception, processing, and forwarding of messages (text, media, and documents) betwee

WhatsApp Trigger, Slack, Slack Trigger +2