AutomationFlowsAI & RAG › Generate Sprint Summary with OpenAI

Generate Sprint Summary with OpenAI

Original n8n title: Sprint Summary

sprint-summary. Uses openAi. Webhook trigger; 3 nodes.

Webhook trigger★☆☆☆☆ complexityAI-powered3 nodesOpenAI
AI & RAG Trigger: Webhook Nodes: 3 Complexity: ★☆☆☆☆ AI nodes: yes Added:

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
{
  "name": "Sprint Summary",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "sprint-summary",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        0,
        0
      ],
      "id": "050ce8c6-cc3e-44e4-89e5-8944f45c6a3f",
      "name": "Webhook"
    },
    {
      "parameters": {
        "url": "={{ $env.JIRA_BASE_URL + '/rest/api/3/search/jql?jql=project=' + ($env.JIRA_PROJECT_KEY || 'JAN') + '&maxResults=100&fields=summary,status,assignee' }}",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "jiraSoftwareCloudApi",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        208,
        0
      ],
      "id": "683a50d8-34d8-4676-b49d-de179005998f",
      "name": "Get Jira Issues",
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const fullResponse = $input.item.json;\nconst issues = fullResponse.issues || [];\n\nconst statusCount = {};\n\nissues.forEach(issue => {\n  const status = issue.fields?.status?.name;\n  if (status) {\n    statusCount[status] = (statusCount[status] || 0) + 1;\n  }\n});\n\nconst total = issues.length;\nconst done = statusCount['Done'] || 0;\nconst completion = total > 0 ? Math.round((done / total) * 100) : 0;\nconst filled = Math.round(completion / 5);\nconst empty = 20 - filled;\nconst progressBar = '\u2588'.repeat(filled) + '\u2591'.repeat(empty);\nconst statusLines = Object.entries(statusCount)\n  .map(([status, count]) => `\u2022 ${status}: ${count}`)\n  .join('\\n') || '\u2022 No statuses found';\n\nconst message = `\ud83d\udcca *Board Summary (JAN)*\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n\ud83d\udcc8 Completion: ${completion}%\n\\`${progressBar}\\`\n\n\ud83d\udcca *Status Breakdown*\n${statusLines}\n- Total Issues: ${total}\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501`;\n\nreturn [{ json: { message, completion, statusCount, total } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        416,
        0
      ],
      "id": "35177461-58d4-4fb1-8b40-b3909c8a466b",
      "name": "Build Summary"
    },
    {
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "={{ $env.SLACK_DEFAULT_CHANNEL_ID }}",
          "mode": "id"
        },
        "text": "={{ $json.message }}",
        "otherOptions": {}
      },
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        624,
        0
      ],
      "id": "d0031467-09a7-4519-b74a-089cc5fb16b7",
      "name": "Send a message",
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Get Jira Issues",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Jira Issues": {
      "main": [
        [
          {
            "node": "Build Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Summary": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "availableInMCP": false
  },
  "versionId": "8b68d01e-6c0a-4dd1-8e44-18fe77649521",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "4l82s__0vHKpkxRh4qlXU",
  "tags": []
}

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

sprint-summary. Uses openAi. Webhook trigger; 3 nodes.

Source: https://github.com/emilioCode/scrum-bot-n8n/blob/51fc37a85d4b8a9030da07d6f98dbd9b8c321880/flows/sprint-summary.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

Image Generation API. Uses respondToWebhook, stickyNote, openAi. Webhook trigger; 7 nodes.

OpenAI
AI & RAG

scrum-master-bot. Uses openAi. Webhook trigger; 7 nodes.

OpenAI
AI & RAG

• Webhook → urlscan.io → GPT-4o mini → Gmail • Payload example: • urlscan.io returns a Scan ID and raw JSON. • AI node classifies the scan as malicious / suspicious / benign, assigns a 1-10 risk score

Url Scan Io, Gmail, OpenAI
AI & RAG

Brand Finder and Contacter. Uses openAi, respond, gmail. Webhook trigger; 7 nodes.

OpenAI, Respond, Gmail
AI & RAG

Generate audio from text using OpenAI - text-to-speech Workflow. Uses respondToWebhook, stickyNote, openAi. Webhook trigger; 5 nodes.

OpenAI