Last verified: May 26, 2026. Tested against 7DTD V2.6 dedicated server (April 2026 Stable).
What changed in 2026: The dedicated server's telnet protocol is unchanged from V2.5, so existing bridges keep working through the V2.6 upgrade. Two security-relevant defaults shifted: telnet now binds to 127.0.0.1 on fresh installs (move your bridge to the same host or set TelnetAllowedIPs), and the default empty-password telnet is rejected at server start (set TelnetPassword explicitly). Discord's webhook API itself is stable; the rate-limit numbers below have not changed since 2023.
Pairing your 7 Days to Die server with a Discord guild keeps your community engaged when players are not logged in. The dev team has never shipped a native Discord integration; everything goes through third-party tools that watch the server log or hook the telnet console. Two patterns cover almost every use case:
This guide covers both, the four maintained tools that handle them in 2026, a ready-to-paste Python script for custom event forwarding, the channel layout that scales past 30 players, and the rate-limit traps that bite during Blood Moon nights.
| Discord Webhook (one-way) | Chat Bridge (two-way bot) | |
|---|---|---|
| Direction | Server → Discord | Server <-> Discord |
| What it sends | Server-generated events: player joins, deaths, restarts, level-ups, Blood Moon countdown | Live chat messages, both directions |
| Setup difficulty | Trivial: generate URL in Discord, paste into the tool | Moderate: needs a Discord bot user and telnet access |
| Discord side | No bot needed, just a webhook URL | Bot user with chat permissions |
| Server side | Anything that can POST HTTP | Tool that holds a persistent telnet connection |
| Best for | Status channels, "important events" feeds, automated alerts | Active communities where chat-while-at-work matters |
Most communities run both: a webhook for events plus a bridge for chat. The two are not mutually exclusive; CSMM (the most-used 7DTD server manager) handles both from a single install.
Discord webhooks are a built-in Discord feature. You do not need a bot, OAuth flow, or extra software on the Discord side. Just a URL that posts to a specific channel.
7D2D Server Bot). Optionally upload an avatar (the in-game cog or your community badge works well).To verify the URL works before wiring it into anything, post a test message with curl:
curl -X POST -H "Content-Type: application/json" \
-d '{"content":"Hello from 7D2D test."}' \
https://discord.com/api/webhooks/<your-webhook-id>/<your-token>
If the message lands in your channel, the URL works. If you get HTTP 401 or 404, the URL is wrong, expired, or was deleted in Discord. Generate a new one.
The dedicated server does not natively post to Discord. You need a layer that watches the server log or hooks the telnet chat, formats messages, and POSTs to the webhook (or runs a bot for bidirectional bridging). These four tools cover 99% of 7DTD Discord integrations in 2026:
Open-source, self-hosted web manager for 7DTD. Supports both Discord webhooks (event notifications, custom log-string detection, configurable event filters) and full bidirectional chat bridging via a Discord bot. The most feature-complete option that is actively maintained in 2026. GPL-3.0 licensed.
CSMM ships with prebuilt event types: player join/leave, death/respawn, level-up, base-claim, level-50 hits, chat messages, kicks/bans, and a flexible "match this log line" trigger for anything else. The Discord-side commands let admins kick/ban/give-item/teleport from a privileged channel.
Trade-off: CSMM itself runs on a Node.js + PostgreSQL stack and needs a small VPS or container alongside your game server. If you do not want a second service running, skip CSMM and use Dishorde or a script.
Discord bridge bot purpose-built for 7DTD. Logs into your Discord guild as a bot user, opens a telnet connection to the game server on port 8081, and bridges chat both ways. No web panel; no event filtering; no admin command UI; just chat. About 1500 lines of Node.js, easy to audit.
Best for a small community where the goal is "let people at work see the in-game chat." Lower operational burden than CSMM; less functionality.
ServerTools is the long-running 7DTD modlet that adds dozens of admin tooling features (zones, wallets, player tracking, anti-grief, plus much more). Its Discord_Bot tool turns the modlet into a webhook sender for ServerTools-internal events: zone breaches, player-killed-by-zombie-during-Blood-Moon, vault-overflow, etc.
ServerTools also requires Web_API to be enabled for the bot to talk to Discord. Configuration is XML files in the modlet's config directory; for a server already running ServerTools, this is the lowest-effort way to add Discord events.
Verify ServerTools is updated for V2.6 before installing on a 2026 server; the modlet's release cycle lags the base game by a few weeks after major patches.
If you want exact control over which events forward, write a 30-line script that connects to the telnet port, watches lines as they come in, and POSTs to the webhook. The example below is a complete Python implementation.
This is a complete working script that connects to the 7DTD telnet console, watches for player events, and forwards them to Discord. Replace the four variables at the top and run it on the same machine as the game server (or any machine that can reach the telnet port).
#!/usr/bin/env python3
# 7dtd-discord-webhook.py - minimal log-to-webhook forwarder.
# Requires: Python 3.8+; standard library only.
import telnetlib3
import asyncio
import urllib.request
import json
import re
# === Configure these ===
TELNET_HOST = "127.0.0.1"
TELNET_PORT = 8081
TELNET_PASS = "your_telnet_password_here"
WEBHOOK_URL = "https://discord.com/api/webhooks/<id>/<token>"
# ========================
# Regex patterns for events we care about. Tune to your taste.
EVENTS = {
"join": re.compile(r"Player connected, entityid=\d+, name='([^']+)'"),
"leave": re.compile(r"Player disconnected: EntityID=\d+, PlayerID='[^']+', OwnerID='[^']+', PlayerName='([^']+)'"),
"death": re.compile(r"died at\(([\-\d\., ]+)\)"),
"blood_moon":re.compile(r"Blood Moon is rising"),
"restart": re.compile(r"Saving and exiting server"),
}
def send_discord(message: str) -> None:
"""POST a message to Discord; swallow rate-limit errors."""
payload = json.dumps({"content": message}).encode("utf-8")
req = urllib.request.Request(
WEBHOOK_URL, data=payload,
headers={"Content-Type": "application/json"}
)
try:
urllib.request.urlopen(req, timeout=5).read()
except Exception as e:
# Rate-limit (429) or transient errors: log and continue.
print(f"Discord send failed: {e}")
def parse_line(line: str) -> None:
if m := EVENTS["join"].search(line):
send_discord(f":green_circle: **{m.group(1)}** joined the server.")
elif m := EVENTS["leave"].search(line):
send_discord(f":red_circle: **{m.group(1)}** left the server.")
elif EVENTS["blood_moon"].search(line):
send_discord(":warning: **Blood Moon is rising.** Brace yourselves.")
elif EVENTS["restart"].search(line):
send_discord(":arrows_counterclockwise: Server is restarting.")
async def main():
reader, writer = await telnetlib3.open_connection(
host=TELNET_HOST, port=TELNET_PORT,
connect_minwait=1.0, connect_maxwait=2.0,
)
# Authenticate.
writer.write(TELNET_PASS + "\n")
await writer.drain()
# Tail forever.
while True:
line = await reader.readline()
if not line:
await asyncio.sleep(1)
continue
parse_line(line.strip())
if __name__ == "__main__":
asyncio.run(main())
Install dependencies: pip install telnetlib3. Run with python3 7dtd-discord-webhook.py in a tmux/screen session or as a systemd service so it survives across game-server restarts.
What you can extend:
Player .* leveled up to level \d+) and forward to a #achievements channelembeds: []Blood Moon (Horde Night) generates a burst of player events: zombie hits, deaths, respawns, damage logs, level-ups. A naive forwarder hits Discord's webhook rate limit (5 messages per 2 seconds per webhook) within the first minute of horde combat and starts dropping messages.
Three mitigations, in order of complexity:
The events your community will actually engage with, ranked by community-management leverage:
| Event | Channel | Source | Why it matters |
|---|---|---|---|
| Server restart announcements | #server-status | Restart script + webhook curl | Players know what is happening; reduces "is the server down?" pings |
| Blood Moon imminent (24h, 1h, now) | #alerts | Custom script watching the day counter | Players in raid groups can coordinate |
| Player join/leave | #player-activity | Webhook from any tool | Friends see when each other are on |
| Player death | #player-activity | Webhook from any tool | Lighthearted; people laugh at each other |
| Level-up milestones (every 25 levels) | #achievements | Filter on log lines or ServerTools event | Recognition for progression |
| Crash and auto-restart | #admin-log | Watchdog script + webhook | Admins see crashes in real time |
| Admin command logging | #admin-log (private) | CSMM or ServerTools | Audit trail for community trust |
| Daily player count snapshot | #stats | Cron job that posts at midnight | Track community growth/decay over months |
For anything beyond a casual server, splitting events into purpose-specific channels makes them readable. The pattern that holds up past 30 players:
| Channel | What goes there | Volume |
|---|---|---|
#server-status | Restarts, planned downtime, "server is back up" notices | Low (a few per day) |
#in-game-chat | Two-way chat bridge (if running CSMM or Dishorde) | High during peak hours |
#alerts | Blood Moon countdown, scheduled events, mod-config warnings | Medium |
#player-activity | Joins, leaves, deaths, level-ups | High |
#achievements | Milestone level-ups (every 25 levels), trader rep maxed, blood-moon-survivor counts | Low |
#admin-log (private) | Admin commands run, bans, kicks, anti-cheat triggers, telnet auth attempts | Medium; admins only |
#tickets or #help | Player support requests. CSMM has a built-in ticket flow that posts here | Low-medium |
@everyone in-game and ping your entire server if you forward verbatim. Strip @ mentions, role IDs, and markdown control characters in your sender.#admin-log should be readable only by admin roles. Players do not need to see kick reasons or anti-cheat triggers.If your bridge tool or webhook script prints any of these, this is what they actually mean. Copy the message into a sub-section header and grep your logs.
HTTP 401 Unauthorized
{"message": "Invalid Webhook Token", "code": 50027}
Webhook URL was regenerated or deleted in Discord. Generate a new URL and update your tool's config. The previous URL is permanently dead; no amount of retry helps.
HTTP 429 Too Many Requests
{"message": "You are being rate limited.", "retry_after": 4.2, "global": false}
Per-webhook rate limit hit (5 requests per 2 seconds). The retry_after tells your sender how long to wait. The default X-RateLimit-Remaining response header is more useful than the body for proactive throttling - read it and stop sending before you hit the limit, not after.
HTTP 404 Not Found
{"message": "Unknown Webhook", "code": 10015}
Channel was deleted, the entire Discord server was deleted, or the webhook was removed from Server Settings > Integrations. Recreate the webhook and update.
telnet: connection refused
ERROR: cannot connect to 127.0.0.1:8081
Game server hasn't bound to telnet yet (still starting), telnet is disabled in serverconfig.xml (TelnetEnabled=false), or post-V2.6 the bind address moved to localhost and your bridge is on a different machine. Check TelnetEnabled, TelnetPort, and TelnetAllowedIPs in serverconfig.xml.
Bridge auth failed:
"Password incorrect" - server rejected telnet password
Telnet password in the bridge config doesn't match TelnetPassword in serverconfig.xml. Note: special characters in passwords sometimes need escaping in YAML/JSON bridge configs. Test with a simple alphanumeric password first; rotate to a strong one after confirming the bridge works.
Three suspects, in order:
You have two tools wired to the same webhook (e.g., CSMM and a custom script both forwarding joins). Pick one source per event; disable the other.
Telnet authentication for the bridge worked, but the bridge does not have permission to post in-game. The bridge user (whatever it is logged in as via telnet) needs admin permission in your serveradmin.xml. Add the bridge as permission_level="0".
Webhooks do not read history (they only POST). If you want history, you need a real bot user with the Read Messages scope. Switch from webhook to bot integration; CSMM and Dishorde both use bots.
The 7DTD V2.0 to V2.6 transition (during 2025-2026) broke many older Discord integration mods. If you find a guide that recommends a tool not listed above, it is probably abandoned. The maintained tools as of May 2026 are CSMM (active, GitHub commits weekly), Dishorde (active, smaller scope), and ServerTools (active, version-tracking V2.6).
Discord itself shipped two relevant changes in 2025-2026:
#player-activity on large servers. Posting joins/deaths to a forum thread instead of a flat channel keeps your Discord scrollable.