You want to send automated messages to a Discord channel at scheduled times. A cron job running on a Linux server can trigger a webhook URL that posts messages to Discord. This setup lets you send daily reports, server alerts, or any periodic notification without manual effort. This article explains how to create a Discord webhook, write a script that sends data to it, and schedule that script with cron.
Key Takeaways: Sending Discord Webhooks via Cron
- Server Settings > Integrations > Webhooks: Create a webhook URL that posts messages to a specific channel.
- curl command with JSON payload: Send a POST request with content-type application/json to the webhook URL.
- crontab -e: Schedule the script to run at any interval using cron syntax.
What a Discord Webhook Is and How It Works
A Discord webhook is a simple way to send messages to a Discord channel from an external source. You create a webhook URL inside a server channel, and any application that sends a properly formatted HTTP POST request to that URL can post a message. The message can include text, embeds, file attachments, and mentions. No bot token or OAuth is required. The webhook acts like a user account that posts messages under the webhook name and avatar you set during creation.
Prerequisites for Sending Webhooks From Cron
Before you start, you need three things. First, a Discord server where you have the Manage Webhooks permission. Second, a Linux or Unix server where you can edit crontab and execute scripts. Third, the curl command must be installed on that server. Most Linux distributions include curl by default. If it is missing, install it with your package manager, for example sudo apt install curl on Debian or Ubuntu.
How Cron Scheduling Works
Cron is a time-based job scheduler in Unix-like operating systems. You define a schedule using five fields: minute, hour, day of month, month, and day of week. A cron job runs a command or script at the times you specify. For example, 0 9 runs a job every day at 9:00 AM. The cron daemon executes the job in a minimal environment, so you must use absolute paths for scripts and commands.
Steps to Create and Schedule a Discord Webhook With Cron
Step 1: Create a Webhook in Discord
- Open Server Settings
Right-click your server name in the left sidebar and select Server Settings. If you do not see this option, you do not have the Manage Server permission. - Go to Integrations
In the left menu of Server Settings, click Integrations. Then click the Webhooks button. - Create a Webhook
Click the Create Webhook button. A new webhook entry appears with a default name and avatar. - Set the Channel and Name
Click the webhook entry to expand it. Under Channel, select the text channel where messages will appear. Under Name, type a display name such as Server Alerts. You can also upload a custom avatar. - Copy the Webhook URL
Click the Copy Webhook URL button. The URL looks likehttps://discord.com/api/webhooks/1234567890/abcdefg. Save this URL in a secure place. Anyone with this URL can post messages to the channel.
Step 2: Write a Script That Sends the Webhook
Create a shell script that uses curl to send a POST request to the webhook URL. The minimal payload is a JSON object with a content field. Below is a complete example script named send-discord.sh.
#!/bin/bash
WEBHOOK_URL="https://discord.com/api/webhooks/1234567890/abcdefg"
MESSAGE="Hello from cron job at $(date)"
curl -H "Content-Type: application/json" \
-X POST \
-d "{\"content\":\"$MESSAGE\"}" \
$WEBHOOK_URL
Replace the WEBHOOK_URL value with the URL you copied. Save the file and make it executable with chmod +x send-discord.sh. Test the script by running ./send-discord.sh from the terminal. You should see the message appear in your Discord channel.
Step 3: Advanced Payloads With Embeds
You can send richer messages using Discord embed objects. An embed can include a title, description, color bar, fields, footer, and timestamp. Below is an example script that sends an embed.
#!/bin/bash
WEBHOOK_URL="https://discord.com/api/webhooks/1234567890/abcdefg"
curl -H "Content-Type: application/json" \
-X POST \
-d '{
"embeds": [{
"title": "Daily Report",
"description": "Server status for $(date)",
"color": 5814783,
"fields": [
{"name": "CPU Load", "value": "0.45", "inline": true},
{"name": "Memory Usage", "value": "3.2 GB / 8 GB", "inline": true}
],
"footer": {"text": "Cron Job"},
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
}]
}' \
$WEBHOOK_URL
The color value is a decimal representation of a hex color. For example, 5814783 corresponds to the hex color #58B9FF. Use a color converter to find the decimal value for any color.
Step 4: Schedule the Script With Cron
- Open the Crontab Editor
Runcrontab -ein your terminal. If this is the first time, you may be asked to choose an editor. Select nano or vim. - Add a Cron Job Line
At the bottom of the file, add a line that defines the schedule and the script path. Use the absolute path to the script. For example, to run the script every day at 9 AM:0 9 /home/username/send-discord.sh - Save and Exit
In nano, press Ctrl+O to save, then Ctrl+X to exit. In vim, press Esc, type:wq, and press Enter. Cron installs the new schedule and starts running the job at the specified times.
Step 5: Verify the Cron Job Is Running
Check the cron log to see if the job ran. On most systems, cron logs are written to /var/log/syslog or /var/log/cron. Search for your script name with grep send-discord /var/log/syslog. You can also add a simple log file inside your script by appending a line like echo "$(date): Message sent" >> /home/username/cron.log.
Common Issues When Sending Webhooks From Cron
Script Runs From Terminal But Not From Cron
Cron runs with a limited PATH environment variable. If curl is not in the default PATH, the script fails. Use the full path to curl in your script. Find it by running which curl — typically /usr/bin/curl. Replace curl with /usr/bin/curl in the script. Also, use absolute paths for all file references.
Webhook URL Is Exposed in the Script
Storing the webhook URL in a script file is a security risk if the script is readable by other users. Set restrictive permissions with chmod 700 send-discord.sh. Alternatively, store the URL in an environment variable and reference it in the script. Add the variable to your crontab with WEBHOOK_URL=your_url before the job line, then use $WEBHOOK_URL in the script.
JSON Payload Is Malformed
If the Discord API returns a 400 Bad Request, the JSON payload is invalid. Common mistakes include missing commas, unescaped double quotes inside strings, or trailing commas in arrays. Validate your JSON with a tool like jq. Run echo 'your_json' | jq . to see parsing errors.
Rate Limiting From Frequent Posts
Discord enforces rate limits on webhook requests. The limit is 30 requests per 60 seconds per webhook. If your cron job runs more often than once per two seconds, you may receive 429 Too Many Requests responses. Schedule your cron job at intervals of at least two seconds or implement retry logic with exponential backoff.
Cron Scheduling Patterns vs Discord Webhook Payload Types
| Item | Simple Text Message | Embed with Fields |
|---|---|---|
| Payload size | Small, under 2000 characters | Larger, up to 6000 characters total |
| Use case | Quick alerts or status updates | Detailed reports with structured data |
| curl complexity | Simple single-line JSON | Multi-line JSON with nested objects |
| Color support | No | Yes, via color field |
| Multiple fields | No | Up to 25 fields |
You now have a working system that sends Discord messages automatically using cron. The webhook URL and curl script handle the communication. To extend this setup, consider adding conditional logic in the script to send different messages based on server metrics. A useful next step is to include file attachments by using the multipart/form-data content type instead of JSON.