Steps
-
Create the application and copy the token
Open the Discord Developer Portal, press New Application and give it a name. On the Bot page copy the token. The token is your bot's password: if it leaks, click Regenerate to revoke it.
If the bot reads the text of messages, also switch on the Message Content Intent on the same page, under Privileged Gateway Intents. Without it the bot gets empty values in the text fields of messages, with a few exceptions.
-
Invite the bot to your server
In the Developer Portal open OAuth2, URL Generator, tick the
botscope and the permissions the bot needs, then open the link and pick a server. You need the Manage Server permission on that server. -
Install discord.py
discord.py needs Python 3.8 or higher. A virtual environment keeps its packages apart from the system's.
$ sudo apt install -y python3-venv $ mkdir ~/bot && cd ~/bot $ python3 -m venv .venv $ .venv/bin/pip install -U discord.py
-
Put the token in .env
Keep the token out of the code. The file is readable by you only, and git never sees it.
$ echo 'DISCORD_TOKEN=<your token>' > .env $ chmod 600 .env $ echo '.env' >> .gitignore
-
Write the bot
This bot answers
$hello. It follows the quickstart in the discord.py documentation, with the token read from the environment. Save it asbot.py.# bot.py import os import discord intents = discord.Intents.default() intents.message_content = True client = discord.Client(intents=intents) @client.event async def on_ready(): print(f"Logged in as {client.user}") @client.event async def on_message(message): if message.author == client.user: return if message.content.startswith("$hello"): await message.channel.send("Hello!") client.run(os.environ["DISCORD_TOKEN"]) -
Run it once by hand
Load the token, start the script and write
$helloin a channel the bot can see. It must answer. Stop it withCtrl+C.$ set -a; source .env; set +a $ .venv/bin/python bot.py Logged in as CoffeeHelper#1234
-
Make it a systemd service
Create the unit file, then enable it.
Restart=alwaysbrings the bot back after a crash, andenablestarts it on every boot. Replacedevwith your user name.$ sudo nano /etc/systemd/system/discord-bot.service [Unit] Description=My Discord bot After=network-online.target Wants=network-online.target [Service] User=dev WorkingDirectory=/home/dev/bot EnvironmentFile=/home/dev/bot/.env ExecStart=/home/dev/bot/.venv/bin/python bot.py Restart=always RestartSec=5 [Install] WantedBy=multi-user.target $ sudo systemctl daemon-reload $ sudo systemctl enable --now discord-bot
Why the host must not sleep
Discord talks to a bot over the Gateway, a WebSocket connection that the bot keeps open with heartbeats. If the line drops, the bot can Resume and get the events it missed, but only if it reconnects in time. Otherwise it starts a new session, and the events in between are not replayed.
This is where a sleeping host breaks the bot. The bot holds its connection and makes only outgoing requests, and an outgoing request does not wake a sleeping Uno computer. A bot on a sleeping computer stays offline until something else wakes it.
What keeps a Discord bot online on Uno
Uno computers sleep after 10 minutes with nothing to do and wake on the first request. Uno's own guide says where a bot like this belongs: anything that must hold connections, such as a bot on long polling, a game server or a queue consumer, belongs on a computer that does not go to sleep on its own. Two switches do it:
- In the console: on the computer's page in the console, Economy mode off: the computer stays on until you put it to sleep.
- Over the API: PATCH /api/v1/boxes/{id}/sleep-policy with {"always_on":true}: the computer never goes down on its own.
| Computer set not to sleep | Computer that sleeps when idle | Slash commands over HTTP | |
|---|---|---|---|
| Bot stays online | yes | no, offline while asleep | no bot connection to keep |
| A message wakes the host | not needed | no | yes, the request is incoming |
| Reads message text | yes, with the intent | only while awake | no, commands and buttons only |
| Take it when | The bot talks in channels or watches them | Never for a chat bot | The bot only answers commands |
- Uno's guide does not say a running bot keeps the computer awake by itself. Do not count on it: set the computer not to sleep.
If the bot only has slash commands
Discord can send commands and button clicks to a web address instead of the open connection. Interactions come either through the Gateway or to this address, never both. Then no bot has to stay connected, and an HTTP request to one of your computer's apps wakes it.
- You must send the first response within 3 seconds. After a sleep the first command waits for the wake-up (median 118 ms in our measurement of 3 October 2026), so send a deferred reply first if your handler is slow.
- Discord signs each request with Ed25519. Verify the
X-Signature-Ed25519header, and answer the PING Discord sends when you save the address with a PONG.
The public https address is covered in the bot hosting guide. Protocol: interactions.
Check that it works
Check the status and watch the log while you write to the bot. Then leave it alone for longer than 10 minutes and write to it again. If it still answers, the host stays on.
$ sudo systemctl status discord-bot Active: active (running) $ journalctl -u discord-bot -f
The short way: let the agent build and run it
Describe the bot to the agent in Uno Work and it writes and runs the code on your computer. You skip steps 3 to 7. Uno Work in the cloud starts with Plus, and the computer still has to be set not to sleep.
Plus: $20 a month
Common problems
The bot is online, then goes offline after a while
sudo systemctl status discord-bot. If the computer slept, set it not to sleep as above. A restart brings the bot back, but not the messages it missed.The bot refuses to start and the error mentions privileged intents
intents.message_content = True.Can I use discord.js instead?
new Client({ intents: [GatewayIntentBits.Guilds] }) and ends with client.login(token). See the discord.js guide.A host for your bot, from $5 a month
A Linux computer with root. Set it not to sleep and the bot stays connected; move up a plan any time.
Small
A Telegram bot, a VPN, a small backend
$5/ month
- 1 vCPU · 1 GB
- 15 GB disk
- 25 GB cloud storage
- 5 boosts a month
Plus
Agents that work with your laptop closed
$20/ month
- 4 vCPU · 4 GB
- 40 GB disk
- 100 GB cloud storage
- Uno Work in the cloud
Pro
A product in production, a second MacBook
$70/ month
- 16 vCPU · 16 GB
- 120 GB disk
- 300 GB cloud storage
- Speed of a MacBook Air M4
Max
A team and many agents at once
$200/ month
- 32 vCPU · 48 GB
- 300 GB disk
- 1,024 GB cloud storage
- 5 public IPv4
Add Uno AI to any plan: 40 h of AI work a month on Small, 100 h on Plus, unlimited on Max. Today: GLM-5.3 Flash and MiMo v2.6 Pro. Or sign in with your own Claude or ChatGPT.