No description
  • Python 97.5%
  • Dockerfile 2.5%
Find a file
2026-07-29 07:41:35 +00:00
.dockerignore SNDS Slack export 2026-07-29 07:41:35 +00:00
.env.example SNDS Slack export 2026-07-29 07:41:35 +00:00
.gitignore SNDS Slack export 2026-07-29 07:41:35 +00:00
Dockerfile SNDS Slack export 2026-07-29 07:41:35 +00:00
README.md SNDS Slack export 2026-07-29 07:41:35 +00:00
snds_to_slack.py SNDS Slack export 2026-07-29 07:41:35 +00:00

snds-to-slack

Pulls the Microsoft Smart Network Data Services daily data export and posts a digest to Slack.

The container runs once and exits — scheduling belongs to cron, a systemd timer, or a k8s CronJob.

Message

One message per run, one line per IP:

SNDS report 2026-07-28

:large_yellow_circle: zoo  168.119.192.202  YELLOW  (3102,2204,2201,0.1)
:red_circle: smukfest  168.119.192.207  RED  (6014,2261,2944,0.1)

The name before the IP is the first label of its PTR record (frieda.hetzner.venuemanager.netfrieda), falling back to the IP if no PTR resolves. The tuple is (RCPT commands, DATA commands, message recipients, complaint rate). Complaint rate < 0.1% is reported as 0.1.

Routing

The complete message always goes to SLACK_CHANNEL_GREEN. If any IP in the export is YELLOW, RED, or an unrecognised status, the same complete message also goes to SLACK_CHANNEL_RED. If both variables name the same channel, it is posted once.

Configuration

Copy .env.example to .env and fill it in:

Variable Required Purpose
SNDS_KEY yes Automated Data Access key from the SNDS portal
SLACK_WEBHOOK_URI yes Incoming webhook URL
SLACK_CHANNEL_GREEN yes Channel that receives every report
SLACK_CHANNEL_RED yes Channel that additionally receives non-GREEN reports
SLACK_NAME no Bot display name, defaults to SNDS

The channel and username overrides in the payload only take effect on a legacy Incoming Webhook. A webhook created through a modern Slack app is bound to one channel and will ignore both — in that case use two webhooks or a legacy one.

Environment variables take precedence over .env, so docker run --env-file works either way.

Running

docker build -t snds-to-slack .

# print the message and target channels, post nothing
docker run --rm --env-file .env snds-to-slack --dry-run

# post for real
docker run --rm --env-file .env snds-to-slack

Without Docker: python3 snds_to_slack.py --dry-run (Python 3.9+, no dependencies).

Scheduling

The SNDS reporting window closes at 09:00 UTC, so run shortly after:

5 10 * * * docker run --rm --env-file /home/rune/development/snds-to-slack/.env snds-to-slack

Exit codes

Code Meaning
0 Posted, or the export was empty (nothing is posted on an empty export)
1 Could not fetch SNDS data, or a Slack post failed
2 Missing required configuration

As of 2026 SNDS Automated Data Access keys expire after roughly 30 days. A sudden run of exit-code-1 failures usually means an expired SNDS_KEY rather than an outage — regenerate it in the SNDS portal.

Testing

SNDS_TEST_FILE=/path/to/sample.csv reads the export from a local file instead of the network, which makes the all-GREEN and malformed-row paths testable without live data.