Skip to content

Commit 31884be

Browse files
ismoilovdevmlclaude
andcommitted
Improve webhook alert messages and fix Job URLs
Improvements: - ✅ Fixed Job event URLs - now opens correct job page (/-/jobs/{id}) - 📊 Added duration info for Pipeline and Job events - 📝 Enhanced Push events with commit list (first 3 commits) - 🎨 Better MR messages with action-specific emojis - 💅 Improved formatting with bold labels and code blocks - 🔨 Better Job status messages with stage and duration Before: View Details → Project page After: View Details → Specific Job page ✅ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent eebac8d commit 31884be

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

src/app/api/webhook/gitlab/route.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,12 @@ function formatEventMessage(payload: WebhookPayload): {
283283
switch (payload.object_kind) {
284284
case 'pipeline': {
285285
const p = payload as PipelinePayload;
286+
const duration = p.object_attributes.duration
287+
? `\n⏱️ Duration: ${Math.floor(p.object_attributes.duration / 60)}m ${p.object_attributes.duration % 60}s`
288+
: '';
286289
return {
287290
title: `Pipeline ${p.object_attributes.status.toUpperCase()}`,
288-
message: `📦 Project: ${projectName}\n🔢 Pipeline: #${p.object_attributes.id}\n🌿 Branch: ${p.object_attributes.ref}\n📊 Status: ${p.object_attributes.status}\n👤 Triggered by: ${userName}`,
291+
message: `📦 *Project:* ${projectName}\n🔢 *Pipeline:* #${p.object_attributes.id}\n🌿 *Branch:* \`${p.object_attributes.ref}\`\n📊 *Status:* ${p.object_attributes.status.toUpperCase()}${duration}\n👤 *By:* ${userName}`,
289292
url: p.object_attributes.web_url,
290293
status: p.object_attributes.status,
291294
};
@@ -294,19 +297,31 @@ function formatEventMessage(payload: WebhookPayload): {
294297
case 'push': {
295298
const p = payload as PushPayload;
296299
const branch = p.ref.replace('refs/heads/', '');
300+
const commits = p.commits?.slice(0, 3) || [];
301+
const commitList = commits.map(c => ` • ${c.title}`).join('\n');
302+
const moreCommits = p.total_commits_count > 3 ? `\n ... and ${p.total_commits_count - 3} more` : '';
297303
return {
298-
title: `Push to ${branch}`,
299-
message: `📦 Project: ${projectName}\n🌿 Branch: ${branch}\n📝 Commits: ${p.total_commits_count}\n👤 Pushed by: ${userName}`,
304+
title: `📤 Push to ${branch}`,
305+
message: `📦 *Project:* ${projectName}\n🌿 *Branch:* \`${branch}\`\n📝 *Commits:* ${p.total_commits_count}\n${commitList}${moreCommits}\n👤 *By:* ${userName}`,
300306
url: payload.project?.web_url || '',
301307
status: 'push',
302308
};
303309
}
304310

305311
case 'merge_request': {
306312
const mr = payload as MergeRequestPayload;
313+
const actionEmoji = {
314+
open: '📂',
315+
close: '🔒',
316+
reopen: '🔓',
317+
update: '🔄',
318+
merge: '🔀',
319+
approved: '✅',
320+
unapproved: '❌',
321+
}[mr.object_attributes.action] || '📝';
307322
return {
308-
title: `Merge Request ${mr.object_attributes.action}`,
309-
message: `📦 Project: ${projectName}\n📝 MR: !${mr.object_attributes.iid} - ${mr.object_attributes.title}\n🌿 ${mr.object_attributes.source_branch}${mr.object_attributes.target_branch}\n📊 State: ${mr.object_attributes.state}\n👤 By: ${userName}`,
323+
title: `${actionEmoji} MR ${mr.object_attributes.action.toUpperCase()}`,
324+
message: `📦 *Project:* ${projectName}\n📝 *MR:* !${mr.object_attributes.iid} - ${mr.object_attributes.title}\n🌿 *Branch:* \`${mr.object_attributes.source_branch}\`\`${mr.object_attributes.target_branch}\`\n📊 *State:* ${mr.object_attributes.state}\n👤 *By:* ${userName}`,
310325
url: mr.object_attributes.url,
311326
status: mr.object_attributes.state,
312327
};
@@ -325,10 +340,16 @@ function formatEventMessage(payload: WebhookPayload): {
325340

326341
case 'build': {
327342
const job = payload as JobPayload;
343+
const jobUrl = payload.project?.web_url
344+
? `${payload.project.web_url}/-/jobs/${job.build_id}`
345+
: '';
346+
const duration = job.build_duration
347+
? `\n⏱️ *Duration:* ${Math.floor(job.build_duration / 60)}m ${job.build_duration % 60}s`
348+
: '';
328349
return {
329-
title: `Job ${job.build_status.toUpperCase()}`,
330-
message: `📦 Project: ${projectName}\n🔨 Job: ${job.build_name}\n📊 Stage: ${job.build_stage}\n📊 Status: ${job.build_status}\n🌿 Branch: ${job.ref}\n👤 By: ${userName}`,
331-
url: payload.project?.web_url || '',
350+
title: `🔨 Job ${job.build_status.toUpperCase()}`,
351+
message: `📦 *Project:* ${projectName}\n🔨 *Job:* ${job.build_name}\n📊 *Stage:* ${job.build_stage}\n📊 *Status:* ${job.build_status.toUpperCase()}\n🌿 *Branch:* \`${job.ref}\`${duration}\n👤 *By:* ${userName}`,
352+
url: jobUrl,
332353
status: job.build_status,
333354
};
334355
}

0 commit comments

Comments
 (0)