Gmail을 위한 Jira 자동 스프린트 리포트
중급
이것은Content Creation, Multimodal AI분야의자동화 워크플로우로, 11개의 노드를 포함합니다.주로 Set, Code, Jira, Gmail, ScheduleTrigger 등의 노드를 사용하며. 통해Gmail向利益相关者보내기Jira자동화冲刺보고서
사전 요구사항
- •Google 계정 및 Gmail API 인증 정보
사용된 노드 (11)
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
"id": "4b7zzdwKKLNoIiMy",
"meta": {
"instanceId": "0430772da25f7bca29bf5ef2b251086a85fb4096503a6f781526d32befd038d6",
"templateCredsSetupCompleted": true
},
"name": "Generate Jira automatic sprint report for Gmail",
"tags": [
{
"id": "3T7uxjPBNibzqJlE",
"name": "Google",
"createdAt": "2025-08-18T07:15:32.460Z",
"updatedAt": "2025-08-18T07:15:32.460Z"
},
{
"id": "7awkAmV9dEBwVz7l",
"name": "sprint report",
"createdAt": "2025-09-25T16:00:40.741Z",
"updatedAt": "2025-09-25T16:00:40.741Z"
},
{
"id": "EYNbAs3Q9sg9NksG",
"name": "Jira",
"createdAt": "2025-09-10T10:47:53.750Z",
"updatedAt": "2025-09-10T10:47:53.750Z"
},
{
"id": "eAzNESqLUWwWMrE9",
"name": "gmail",
"createdAt": "2025-08-18T07:16:22.709Z",
"updatedAt": "2025-08-18T07:16:22.709Z"
}
],
"nodes": [
{
"id": "e63fae5a-8ccf-4812-bbc8-05e30cd99eb1",
"name": "이메일 알림",
"type": "n8n-nodes-base.gmail",
"position": [
1312,
0
],
"webhookId": "40883792-d8eb-4d1e-89a4-97ede636627f",
"parameters": {
"sendTo": "youremail@gmail.com",
"message": "=Hello, \nThis is your current sprint report\n\n{{$json.html}}\n<p><a href=\"https://yourdomain.atlassian.net/jira/software/c/projects/TES/boards/3\">See the sprint in Jira</a></p>\n",
"options": {},
"subject": "=Your Sprint Report"
},
"credentials": {
"gmailOAuth2": {
"id": "M9FwThxXdSZG2WNo",
"name": "Gmail account"
}
},
"typeVersion": 2.1,
"alwaysOutputData": false
},
{
"id": "21fed4c4-f686-4fc1-8255-32c76382b377",
"name": "다수 이슈 가져오기",
"type": "n8n-nodes-base.jira",
"position": [
416,
0
],
"parameters": {
"options": {
"jql": "project = your project AND sprint in openSprints()",
"fields": "summary,status,assignee,priority,issuetype,labels,created,updated,customfield_10016,customfield_10020"
},
"operation": "getAll",
"returnAll": true
},
"credentials": {
"jiraSoftwareCloudApi": {
"id": "WL78MSYPg2KS2Y5X",
"name": "Jira SW Cloud account 3"
}
},
"typeVersion": 1
},
{
"id": "c46a19f2-7c08-44a4-9e91-60d32b9c31ae",
"name": "스티커 노트1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-336,
-464
],
"parameters": {
"color": 3,
"width": 304,
"height": 176,
"content": "## Required\n\n• Jira Cloud project (API email + API token)\n• Gmail credential"
},
"typeVersion": 1
},
{
"id": "a4db27d8-d430-4798-8ffc-c8e71d414897",
"name": "스티커 노트",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
-464
],
"parameters": {
"width": 640,
"height": 704,
"content": "## 1) Trigger and Normalize \n\nTrigger: Scheduled run (e.g., every Friday at 17:00)\n\nData Processing:\n- Fetch issues from Jira with JQL: project = <KEY> AND sprint in openSprints()\n- Select relevant fields: summary, status, assignee, priority, story points, sprint, created, updated\n- Validate presence of critical fields (story points, sprint info)\n- Normalize empty values (e.g., “Unassigned”, “Not defined”)\n\nBest Practices:\nPerform validation and normalization here so later metrics and reports don’t break if a field is missing."
},
"typeVersion": 1
},
{
"id": "3c26641b-e1e7-46d9-97f4-03d44934ec43",
"name": "스티커 노트2",
"type": "n8n-nodes-base.stickyNote",
"position": [
640,
-464
],
"parameters": {
"color": 5,
"width": 352,
"height": 704,
"content": "## 2) Calculate Metrics\n\nAction: Aggregate data into KPIs\n\nKey Metrics:\n- Issues by status (To Do / In Progress / Done)\n- Story points: completed vs total\n- Blockers count (priority = High / label = blocker)\n- Sprint timeline (start / end date)\n\nBest Practices:\nKeep calculations in a dedicated node to make debugging easier and allow quick adjustments (e.g., adding new KPIs)."
},
"typeVersion": 1
},
{
"id": "5ddc63f8-f59c-4b08-a5f4-c3b7a35e7d45",
"name": "스티커 노트3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1008,
-464
],
"parameters": {
"color": 4,
"width": 464,
"height": 704,
"content": "## 3) Generate Report & Send Notification\n\nAction: Build an HTML report\n\nContents:\n- Sprint name + dates\n- Metrics overview (done vs total issues, SP, blockers)\n- Table of all issues (key, summary, status, assignee, priority, SP)\n- Links to Jira tickets\n\nBest Practices:\nUse a clean HTML template with inline CSS for email compatibility.\n\n \n\nAction: Send reporting email\n\nRecipients: Person who needs it\n\nInformation: include all information relevant to the sprint status\n"
},
"typeVersion": 1
},
{
"id": "7d410e39-680b-483c-af58-43a86eb0e3dd",
"name": "주간 트리거",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
0,
0
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
5
],
"triggerAtHour": 17
}
]
}
},
"typeVersion": 1.2
},
{
"id": "cc836891-9da3-45eb-805e-2e1875332ac6",
"name": "Jira 및 이메일 설정",
"type": "n8n-nodes-base.set",
"position": [
208,
0
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "{\n \"values\": {\n \"jiraBaseUrl\": \"https://yourdomain.atlassian.net\",\n \"jiraEmail\": \"youremail@gmail.com\",\n \"jiraApiToken\": \"ATATT3xFfGF0p65qwDvypM5e-...\",\n \"projectKey\": \"yourkey\",\n \"emailRecipients\": \"yourrecipient@gmail.com\"\n }\n}\n"
},
"typeVersion": 3.4
},
{
"id": "6ace04d2-c0dd-494e-8c6a-6c96fca7490c",
"name": "유효성 검사 및 오류 처리",
"type": "n8n-nodes-base.code",
"position": [
672,
0
],
"parameters": {
"jsCode": "const SP = 'customfield_10016';\nconst SPRINT = 'customfield_10020';\n\nconst items = $input.all();\n\nconst out = items.map(i => {\n const it = i.json || {};\n const f = it.fields || {};\n const sprintObj = Array.isArray(f[SPRINT]) ? f[SPRINT][0] : f[SPRINT]; // souvent tableau\n\n return {\n key: it.key,\n summary: f.summary || '',\n status: f.status?.name || '—',\n statusCategory: f.status?.statusCategory?.name || '—',\n assignee: f.assignee?.displayName || 'Unassigned',\n priority: f.priority?.name || 'Undefined',\n sp: Number(f[SP] || 0),\n\n sprint: sprintObj?.name || '—',\n sprintStart: sprintObj?.startDate || null,\n sprintEnd: sprintObj?.endDate || null,\n\n created: f.created || null,\n updated: f.updated || null,\n labels: f.labels || [],\n };\n});\n\nreturn out.map(x => ({ json: x }));\n"
},
"typeVersion": 2
},
{
"id": "b86c2c98-b12c-410a-a837-46c6d974d3ba",
"name": "메트릭 계산",
"type": "n8n-nodes-base.code",
"position": [
880,
0
],
"parameters": {
"jsCode": "const rows = $input.all().map(i => i.json);\nif (!rows.length) return [{ json: { isEmpty: true, message: 'Aucun ticket' } }];\n\nconst low = s => (s||'').toLowerCase();\n\nconst total = rows.length;\nconst done = rows.filter(r => low(r.status) === 'done').length;\nconst inProgress = rows.filter(r => low(r.status) === 'in progress').length;\nconst toDo = rows.filter(r => low(r.status) === 'to do').length;\n\nconst spTotal = rows.reduce((a,r)=>a+(r.sp||0),0);\nconst spDone = rows.filter(r=>low(r.status)==='done').reduce((a,r)=>a+(r.sp||0),0);\n\nconst blockers = rows.filter(r =>\n (r.priority||'').toLowerCase()==='highest' ||\n /blocked|impediment/i.test(r.status) ||\n (r.labels||[]).map(low).includes('blocked')\n).length;\n\nconst firstWithSprint = rows.find(r => r.sprint && r.sprint !== '—');\nconst sprintName = firstWithSprint?.sprint || 'Sprint en cours';\nconst sprintEnd = firstWithSprint?.sprintEnd || null;\n\nreturn [{\n json: {\n sprintName, sprintEnd,\n counts: { total, done, inProgress, toDo },\n storyPoints: { total: spTotal, done: spDone, rate: spTotal ? Math.round(100*spDone/spTotal) : 0 },\n blockers,\n issues: rows,\n reportDate: new Date().toLocaleDateString('fr-FR'),\n reportTime: new Date().toLocaleTimeString('fr-FR'),\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "579c77db-15fb-4ae3-a523-0df994024737",
"name": "HTML 보고서 생성",
"type": "n8n-nodes-base.code",
"position": [
1088,
0
],
"parameters": {
"jsCode": "const d = $json;\n\nfunction row(t){\n return `<tr>\n <td><a href=\"https:/yourdomain.atlassian.net/browse/${t.key}\">${t.key}</a></td>\n <td>${t.summary || ''}</td>\n <td>${t.status || ''}</td>\n <td>${t.assignee || 'Unassigned'}</td>\n <td>${t.priority || 'Undefined'}</td>\n <td style=\"text-align:right\">${t.sp || 0}</td>\n </tr>`;\n}\n\nconst table = `<table border=\"1\" cellspacing=\"0\" cellpadding=\"6\" style=\"border-collapse:collapse;width:100%\">\n <tr>\n <th>Key</th>\n <th>Summary</th>\n <th>Status</th>\n <th>Assignee</th>\n <th>Priority</th>\n <th>SP</th>\n </tr>\n ${(d.issues || []).map(row).join('')}\n</table>`;\n\nconst header = `<p><b>Tickets</b>: ${d.counts.done}/${d.counts.total}\n — <b>Story Points</b>: ${d.storyPoints.done}/${d.storyPoints.total} (${d.storyPoints.rate}%)\n — <b>Blockers</b>: ${d.blockers}</p>`;\n\nconst meta = `<p style=\"color:#6b7280\">\nGenerated on ${d.reportDate} ${d.reportTime}${\n d.sprintEnd ? ` — Planned end: ${new Date(d.sprintEnd).toLocaleDateString('en-GB')}` : ''\n}</p>`;\n\nreturn [{ json: { html: `<h2>Sprint Report — ${d.sprintName}</h2>${meta}${header}${table}` } }];\n"
},
"typeVersion": 2
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "7e8eaceb-500f-431c-92dc-bcdf5e39c926",
"connections": {
"7d410e39-680b-483c-af58-43a86eb0e3dd": {
"main": [
[
{
"node": "cc836891-9da3-45eb-805e-2e1875332ac6",
"type": "main",
"index": 0
}
]
]
},
"21fed4c4-f686-4fc1-8255-32c76382b377": {
"main": [
[
{
"node": "6ace04d2-c0dd-494e-8c6a-6c96fca7490c",
"type": "main",
"index": 0
}
]
]
},
"b86c2c98-b12c-410a-a837-46c6d974d3ba": {
"main": [
[
{
"node": "579c77db-15fb-4ae3-a523-0df994024737",
"type": "main",
"index": 0
}
]
]
},
"579c77db-15fb-4ae3-a523-0df994024737": {
"main": [
[
{
"node": "e63fae5a-8ccf-4812-bbc8-05e30cd99eb1",
"type": "main",
"index": 0
}
]
]
},
"cc836891-9da3-45eb-805e-2e1875332ac6": {
"main": [
[
{
"node": "21fed4c4-f686-4fc1-8255-32c76382b377",
"type": "main",
"index": 0
}
]
]
},
"6ace04d2-c0dd-494e-8c6a-6c96fca7490c": {
"main": [
[
{
"node": "b86c2c98-b12c-410a-a837-46c6d974d3ba",
"type": "main",
"index": 0
}
]
]
}
}
}자주 묻는 질문
이 워크플로우를 어떻게 사용하나요?
위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.
이 워크플로우는 어떤 시나리오에 적합한가요?
중급 - 콘텐츠 제작, 멀티모달 AI
유료인가요?
이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.
관련 워크플로우 추천
Groq, Gemini, Slack 승인 시스템을 사용한 RSS에서 Medium 자동 게시
Groq, Gemini 및 Slack 승인 시스템을 통한 RSS에서 Medium 발행 자동화 워크플로
If
Set
Code
+
If
Set
Code
41 노드ObisDev
콘텐츠 제작
YouTube 비디오 기반 자율 블로그 게시
ChatGPT, Sheets, Apify, Pexels, WordPress를 사용하여 YouTube 비디오를 자동으로 블로그에 게시합니다.
If
Set
Code
+
If
Set
Code
80 노드Oriol Seguí
콘텐츠 제작
fraud 방지 잠재 고객 캡처 및 성장 시스템
AI 평점, 테이블 추적, 다중 채널 알림을 통해防欺诈 잠재 고객을捕获하고 키우습니다.
If
Set
Code
+
If
Set
Code
28 노드Jitesh Dugar
콘텐츠 제작
완전한 B2B 판매 프로세스: Apollo 잠재 고객 생성, Mailgun 프로모션 및 AI 응답 관리
완전한 B2B 판매 프로세스: Apollo 잠재 고객 생성, Mailgun 확장 및 AI 응답 관리
If
Set
Code
+
If
Set
Code
116 노드Paul
콘텐츠 제작
Perplexity와 OpenAI를 사용하여 소셜 미디어에 AI 뉴스 비디오 콘텐츠 아이디어를 생성
Perplexity와 OpenAI를 사용하여 소셜 미디어에 AI 뉴스 비디오 내용을 창의적으로 생성
Set
Code
Gmail
+
Set
Code
Gmail
18 노드Gain FLow AI
콘텐츠 제작
AI로운 LinkedIn 콘텐츠 엔진(n8n + OpenAI + Perplexity + Replicate)
연구 기반의 LinkedIn 게시물을 OpenAI, Perplexity, 인공审核으로 만들기
If
Set
Code
+
If
Set
Code
28 노드Alberto Bordoni
콘텐츠 제작
워크플로우 정보
난이도
중급
노드 수11
카테고리2
노드 유형6
저자
Yassin Zehar
@yassinzeharDigital & IT Project Manager | Data-oriented | Agile certified (PSM I, PSPO I) | Paris
외부 링크
n8n.io에서 보기 →
이 워크플로우 공유