Vercel events, delivered to Discord, Telegram, Slack, ntfy, or Gotify.
apps/docs is the hosted guide. apps/api is the relay people run themselves.
Pushes to master publish ghcr.io/versend/versend (linux/amd64 and linux/arm64). The first package is private. Set it to public under the repository's Packages page, or add ghcr.io as a registry in Portainer.
In Portainer: Stacks → Add stack → Web editor. Paste this, then set WEBHOOK_INTEGRATION_SECRET and at least one destination in the stack environment variables.
services:
versend:
image: ghcr.io/versend/versend:latest
container_name: versend
restart: unless-stopped
ports:
- "3000:3000"
environment:
NODE_ENV: production
PORT: "3000"
WEBHOOK_INTEGRATION_SECRET: ${WEBHOOK_INTEGRATION_SECRET}
DISCORD_WEBHOOK_URL: ${DISCORD_WEBHOOK_URL:-}
DISCORD_WEBHOOK_USERNAME: ${DISCORD_WEBHOOK_USERNAME:-Versend}
DISCORD_WEBHOOK_AVATAR_URL: ${DISCORD_WEBHOOK_AVATAR_URL:-}
TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN:-}
TELEGRAM_CHAT_ID: ${TELEGRAM_CHAT_ID:-}
SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL:-}
NTFY_URL: ${NTFY_URL:-}
NTFY_TOKEN: ${NTFY_TOKEN:-}
GOTIFY_URL: ${GOTIFY_URL:-}
GOTIFY_TOKEN: ${GOTIFY_TOKEN:-}
FILTER_EVENTS: ${FILTER_EVENTS:-}
FILTER_EVENTS_EXCLUDE: ${FILTER_EVENTS_EXCLUDE:-}
FILTER_TARGETS: ${FILTER_TARGETS:-}
RATE_LIMIT_REQUESTS: ${RATE_LIMIT_REQUESTS:-60}
RATE_LIMIT_WINDOW_SECONDS: ${RATE_LIMIT_WINDOW_SECONDS:-60}POST /hooks/vercel receives the Vercel webhook. GET /health lists configured destinations.
bun install
bun run devThe API reads apps/api/.env through Varlock. The schema is apps/api/.env.schema. The API is a Bun process, from Hono's Bun guide. It is not a Vercel project.