Guides / Telegram bot
Host a Telegram bot 24/7
A Telegram bot can get its messages in two ways. With long polling your bot asks Telegram for updates, so it needs no open ports and works on any plan straight away. With webhooks Telegram connects to you, which needs a domain. Start with long polling unless you know you need webhooks.
1. Create the bot
In Telegram, message @BotFather, send /newbot and follow the steps. It gives you a token. Treat it like a password: anyone who has it controls your bot.
2. Install it on your server
apt update && apt install -y python3-venv
useradd -r -m -d /opt/tgbot tgbot
sudo -u tgbot python3 -m venv /opt/tgbot/venv
sudo -u tgbot /opt/tgbot/venv/bin/pip install python-telegram-bot
echo "TELEGRAM_TOKEN=your-token-here" > /opt/tgbot/bot.env
chown tgbot: /opt/tgbot/bot.env && chmod 600 /opt/tgbot/bot.env
Save this small example as /opt/tgbot/bot.py, or use your own code:
import os
from telegram.ext import ApplicationBuilder, CommandHandler
async def start(update, context):
await update.message.reply_text("Hello from my natbox server")
app = ApplicationBuilder().token(os.environ["TELEGRAM_TOKEN"]).build()
app.add_handler(CommandHandler("start", start))
app.run_polling()
3. Keep it running
Save as /etc/systemd/system/tgbot.service:
[Unit]
Description=Telegram bot
After=network-online.target
Wants=network-online.target
[Service]
User=tgbot
WorkingDirectory=/opt/tgbot
EnvironmentFile=/opt/tgbot/bot.env
ExecStart=/opt/tgbot/venv/bin/python bot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
systemctl daemon-reload && systemctl enable --now tgbot
journalctl -u tgbot -f
Send /start to your bot. It should answer. It now starts on boot and restarts after a crash.
Using webhooks instead
Telegram only sends webhooks to ports 80, 88, 443 and 8443, so a forwarded port such as 10001 does not work. On natbox, use a domain instead: link it and set up HTTPS, then have nginx or Caddy pass the webhook path to your bot on a local port. Port 443 reaches your server through our domain routing.
Good to know
- Run only one copy of a polling bot at a time. Telegram rejects a second one with a conflict error.
- Do not put the token in your code or a public repository. If it leaks, get a new one from
@BotFather. - Watch memory on the Graphs tab: the RAM limit is hard, with no swap.
Recommended plan: Nano is enough for most small bots.