English
Building a Slack Webhook Mock Server with Golang: The Ultimate Debugging Tool for Offline Development

In a development environment without internet access, how can I efficiently debug a Slack Webhook integration?
Preface
In daily development, we often need to integrate with third-party services. Take Slack Webhook as an example: when your business system needs to send notifications to Slack, you usually need a real Slack Webhook URL for testing. However, in the following scenarios, this traditional approach will encounter challenges:
offline development environment: Unable to access the external network, unable to use the real Slack service
Frequent debugging: Every time, real Slack notifications need to be sent, which disturbs team members.
Lack of visualization: Unable to intuitively view the structure of the sent Payload
This article will introduce how to build a lightweight Slack Webhook Mock server, allowing you to efficiently debug Webhook integrations even in an offline environment.
Technology selection
This project uses the following technology stack:
| Technology | Purpose |
|---|---|
| Golang | A high-performance, compiled language, suitable for building microservices. |
| Gin | Lightweight web framework, simple and efficient |
| slack-go-webhook | Slack Webhook data structure definition |
Project structure:
slack-webhook-server/
├── go.mod
├── main.go
└── README.mdCore implementation
1. Data structure definition
First, we define a unified API response structure:
go
// Response defines the unified API response format
type Response struct {
Message string `json:"message"` // Response message, e.g. "OK"
Code int `json:"code"` // Business status code, e.g. 100100 for success
Data any `json:"data,omitempty"` // Response data, returned only when needed
}
const (
CodeWithSuccess = 100100
CodeWithFailed = 100101
)2. Mock server core code
go
package main
import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/fishfinal/slack-go-webhook"
"github.com/gin-gonic/gin"
)
func main() {
engine := gin.Default()
// Mock endpoint for receiving and displaying Slack webhook payloads
engine.POST("/webhook/mock/receiver", func(ctx *gin.Context) {
var payload *slack.Payload
err := ctx.ShouldBindJSON(&payload)
if err != nil {
ctx.JSON(http.StatusBadRequest, Response{
Message: "Invalid request parameters",
Code: CodeWithFailed,
})
return
}
marshal, err := json.MarshalIndent(payload, "", " ")
if err != nil {
ctx.JSON(http.StatusInternalServerError, Response{
Message: "Failed to marshal data",
Code: CodeWithFailed,
})
return
}
// Pretty-print the received payload for debugging purposes
fmt.Printf("\n--- Received Webhook at %s ---\n%s\n",
time.Now().Format(time.RFC3339),
string(marshal),
)
// Return success response to simulate Slack's behavior
ctx.JSON(http.StatusOK, Response{
Message: "OK",
Code: CodeWithSuccess,
})
})
fmt.Println("Mock Slack Webhook Server is running on :2769")
if err := engine.Run(":2769"); err != nil {
panic(err)
}
}3. Code Explanation
| component | Function Description |
|---|---|
gin.Default() | Create a Gin engine and automatically load the Logger and Recovery middleware. |
ShouldBindJSON() | Parse and bind JSON request to slack.Payload struct |
MarshalIndent() | Format the output for easier reading and debugging. |
Printf() | Print received logs with timestamps to the console. |
Deploy as a Systemd service
To ensure stable operation in production, we deploy it as a Systemd service.
1. Create a service file
ini
# /etc/systemd/system/slack-webhook-server.service
[Unit]
Description=Slack Webhook Server - Mock Slack webhook receiver for bot message testing
Documentation=https://github.com/fishfinal/slack-go-webhook
Requires=network-online.target
After=network-online.target
[Service]
Type=simple
WorkingDirectory=/var/lib/slack-webhook-server
User=slack-webhook
Group=slack-webhook
ExecStart=/usr/bin/slack-webhook-server
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
KillSignal=SIGTERM
Restart=on-failure
RestartSec=10s
LimitNOFILE=65536
LimitNPROC=4096
# Logging configuration
StandardOutput=append:/var/log/slack-webhook-server/access.log
StandardError=append:/var/log/slack-webhook-server/error.log
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/slack-webhook-server /var/log/slack-webhook-server
[Install]
WantedBy=multi-user.target2. Deployment command
bash
# Create user and directory
sudo useradd -r -s /bin/false slack-webhook
sudo mkdir -p /var/lib/slack-webhook-server
sudo mkdir -p /var/log/slack-webhook-server
sudo chown -R slack-webhook:slack-webhook /var/lib/slack-webhook-server
sudo chown -R slack-webhook:slack-webhook /var/log/slack-webhook-server
# Install binary files
sudo cp slack-webhook-server /usr/bin/
sudo chmod +x /usr/bin/slack-webhook-server
# Installation service
sudo cp slack-webhook-server.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable slack-webhook-server
sudo systemctl start slack-webhook-server3. Service Management
bash
# 查看状态
sudo systemctl status slack-webhook-server
# View logs
sudo journalctl -u slack-webhook-server -f
# Restart the service
sudo systemctl restart slack-webhook-serverTest verification
Send a test request using curl
bash
# Send a simple message
curl -X POST http://localhost:2769/webhook/mock/receiver \
-H "Content-Type: application/json" \
-d '{"text":"Hello from curl!"}'
# Send the complete Payload
curl -X POST http://localhost:2769/webhook/mock/receiver \
-H "Content-Type: application/json" \
-d '{
"text": "Hello from curl!",
"username": "CurlBot",
"channel": "#general",
"attachments": [
{
"title": "Deployment Status",
"text": "Application deployed successfully!",
"color": "#36a64f",
"fields": [
{"title": "Environment", "value": "Production", "short": true},
{"title": "Version", "value": "v2.1.0", "short": true}
]
}
]
}'Expected output
Server console output:
--- Received Webhook at 2026-06-25T14:30:25+08:00 ---
{
"username": "CurlBot",
"channel": "#general",
"text": "Hello from curl!",
"attachments": [
{
"title": "Deployment Status",
"text": "Application deployed successfully!",
"color": "#36a64f",
"fields": [
{"title": "Environment", "value": "Production", "short": true},
{"title": "Version", "value": "v2.1.0", "short": true}
]
}
]
}Client response:
json
{
"message": "OK",
"code": 100100
}Use Cases and Value
| Scene | Solution |
|---|---|
| offline development | The mock server runs entirely locally and does not require access to the external network. |
| Debug Payload | Formatted console output to intuitively view the request structure |
| Rapid iteration | Verify immediately after modifying business logic, no need for real Slack |
| Team collaboration | Unify the Mock service address to facilitate collaborative debugging among multiple people. |
| Safety isolation | Avoid sending test messages to the real Slack and disrupting team members. |
Summary
This article introduces how to use Golang and Gin to build a concise and efficient Slack Webhook Mock server. This tool solves the debugging pain points in offline development environments and has the following features:
lightweight: Single binary file with low memory usage
Easy to deploy: Supports Systemd services and can start automatically at boot
Observability: Print requests in real time on the console, and persist logs
Safety: Run as a non-root user, following the principle of least privilege
Further reading
I hope this blog post helps you debug Slack Webhook integrations more efficiently in an offline development environment.