Skip to main content

Real-time Deployment Notifications with n8n and Slack

Introduction
#

Knowing when deployments happen - and whether they succeed or fail - is critical for any team. This tutorial shows you how to send rich, informative deployment notifications to Slack using n8n.

Download the Workflow
Get the ready-to-use workflow from our n8n Workflow Gallery.

Prerequisites
#

  • An n8n instance with public webhook URL
  • Slack workspace with incoming webhooks enabled
  • CI/CD pipeline that can send webhooks (GitHub Actions, GitLab CI, Jenkins, etc.)

Workflow Overview
#

1
CI/CD Webhook → n8n → Format Message → Slack

Step-by-Step Setup
#

Step 1: Create the Webhook Endpoint
#

  1. Add a Webhook node
  2. Set HTTP Method to POST
  3. Set path to deployment-notify
  4. Response Mode: On Received (immediate acknowledgment)

Your CI/CD will send payloads like:

1
2
3
4
5
6
7
8
9
{
  "status": "success",
  "environment": "production",
  "version": "v1.2.3",
  "commit": "abc123",
  "deployer": "john",
  "timestamp": "2025-01-15T10:30:00Z",
  "url": "https://myapp.com"
}

Step 2: Format the Message
#

Add a Set node to prepare Slack formatting:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const status = $json.status;
const emoji = status === 'success' ? '✅' : '❌';
const color = status === 'success' ? 'good' : 'danger';

return {
  emoji: emoji,
  color: color,
  status: status,
  environment: $json.environment,
  version: $json.version,
  commit: $json.commit,
  deployer: $json.deployer,
  url: $json.url
};

Step 3: Send to Slack
#

Add a Slack node with a rich attachment:

Channel: #deployments

Attachments:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[
  {
    "color": "{{ $json.color }}",
    "blocks": [
      {
        "type": "header",
        "text": {
          "type": "plain_text",
          "text": "{{ $json.emoji }} Deployment {{ $json.status | capitalize }}"
        }
      },
      {
        "type": "section",
        "fields": [
          {
            "type": "mrkdwn",
            "text": "*Environment:*\n{{ $json.environment }}"
          },
          {
            "type": "mrkdwn",
            "text": "*Version:*\n{{ $json.version }}"
          },
          {
            "type": "mrkdwn",
            "text": "*Commit:*\n`{{ $json.commit }}`"
          },
          {
            "type": "mrkdwn",
            "text": "*Deployed by:*\n{{ $json.deployer }}"
          }
        ]
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "View Deployment"
            },
            "url": "{{ $json.url }}"
          }
        ]
      }
    ]
  }
]

Integrating with CI/CD
#

GitHub Actions
#

Add to your workflow:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
- name: Notify Deployment
  if: always()
  run: |
    curl -X POST ${{ secrets.N8N_WEBHOOK_URL }} \
      -H "Content-Type: application/json" \
      -d '{
        "status": "${{ job.status }}",
        "environment": "production",
        "version": "${{ github.ref_name }}",
        "commit": "${{ github.sha }}",
        "deployer": "${{ github.actor }}",
        "url": "https://myapp.com"
      }'

GitLab CI
#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
notify:
  stage: notify
  script:
    - |
      curl -X POST $N8N_WEBHOOK_URL \
        -H "Content-Type: application/json" \
        -d "{
          \"status\": \"$CI_JOB_STATUS\",
          \"environment\": \"$CI_ENVIRONMENT_NAME\",
          \"version\": \"$CI_COMMIT_TAG\",
          \"commit\": \"$CI_COMMIT_SHA\",
          \"deployer\": \"$GITLAB_USER_LOGIN\"
        }"
  when: always

Jenkins
#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
post {
    always {
        script {
            def payload = [
                status: currentBuild.result,
                environment: 'production',
                version: env.BUILD_TAG,
                commit: env.GIT_COMMIT,
                deployer: env.BUILD_USER
            ]
            httpRequest(
                url: env.N8N_WEBHOOK_URL,
                httpMode: 'POST',
                contentType: 'APPLICATION_JSON',
                requestBody: groovy.json.JsonOutput.toJson(payload)
            )
        }
    }
}

Enhanced Features
#

Route by Environment
#

Send production deployments to #production-alerts, staging to #dev:

1
2
3
const channel = $json.environment === 'production'
  ? '#production-alerts'
  : '#dev';

Add Rollback Button
#

Include a rollback action for failed deployments:

1
2
3
4
5
6
{
  "type": "button",
  "text": { "type": "plain_text", "text": "🔄 Rollback" },
  "style": "danger",
  "url": "https://your-rollback-endpoint"
}

Thread Replies
#

Update the same thread with deployment progress:

  1. Store the message ts from the first notification
  2. Use thread_ts parameter in subsequent messages

Troubleshooting
#

Message Not Appearing
#

  • Check Slack webhook URL is correct
  • Verify channel exists and bot has access

Formatting Issues
#

  • Test JSON in Slack’s Block Kit Builder
  • Check for unescaped characters

Missing Data
#

  • Log the incoming webhook payload
  • Ensure CI/CD sends all required fields

Conclusion
#

Rich deployment notifications keep your team informed without requiring them to check dashboards. With n8n, you can customize notifications to include exactly the information your team needs.

Download the complete workflow from our n8n Workflow Gallery.