# How to Host a Telegram Bot for Free with Webhooks (2026)

Host a Telegram bot for free with webhooks: why they beat polling, a complete bot in Node.js and Python, a secret-token check and a one-command deploy.

URL: https://blog.dockhosting.dev/host-telegram-bot
Published: 2026-10-24 · Updated: 2026-10-24 · Author: Doughmi ILYAS

## Summary

- Use webhooks, not polling: Telegram sends each update to your HTTPS URL, so your bot only works when there's a message.
- Because updates arrive as web requests, a webhook bot can run on DockHosting's Free plan: a sleeping app wakes on the next update.
- Protect the endpoint with secret_token: Telegram sends it in the X-Telegram-Bot-Api-Secret-Token header.

ort const meta = {
  title: "How to Host a Telegram Bot for Free with Webhooks (2026)",
  seoTitle: "Host a Telegram Bot for Free with Webhooks (2026)",
  description:
    "Host a Telegram bot for free with webhooks: why they beat polling, a complete bot in Node.js and Python, a secret-token check and a one-command deploy.",
  date: "2026-10-24",
  category: "Guides",
  tags: ["Telegram bot", "Webhooks", "Node.js", "Python", "Tutorial"],
  stack: ["telegram", "nodejs", "python"],
  tryLabel: "Telegram bot",
  command: "dock deploy",
  takeaways: [
    "Use webhooks, not polling: Telegram sends each update to your HTTPS URL, so your bot only works when there's a message.",
    "Because updates arrive as web requests, a webhook bot can run on DockHosting's Free plan: a sleeping app wakes on the next update.",
    "Protect the endpoint with secret_token: Telegram sends it in the X-Telegram-Bot-Api-Secret-Token header.",
  ],
  faq: [
    {
      q: "Can I host a Telegram bot for free?",
      a: "Yes, with webhooks. Telegram delivers each update as an HTTPS request, and on DockHosting's Free plan a sleeping app wakes on the next request, so the first reply after a quiet hour can take a few seconds. For instant replies all the time, Hobby ($4/month) is always on.",
    },
    {
      q: "Webhook or long polling: which should I use?",
      a: "Polling keeps a process asking Telegram for updates, so it must run all the time. Webhooks let Telegram push updates to your URL, which needs HTTPS but no always-running loop. For hosted bots, webhooks are simpler and cheaper.",
    },
    {
      q: "Does Telegram need HTTPS for webhooks?",
      a: "Yes. Every DockHosting app gets HTTPS automatically on its .dockhosting.cloud address, so the URL works as a webhook right away.",
    },
  ],
};

Telegram bots are among the easiest bots to host, if you use **webhooks**. Instead of your bot constantly asking Telegram "anything new?", Telegram **pushes** each message to an HTTPS URL you control. That means no always-running loop, and it means the bot can run on a free plan.

## Webhooks vs polling

| | Long polling (`getUpdates`) | Webhook (`setWebhook`) |
|---|---|---|
| How it works | Your bot asks Telegram for updates in a loop | Telegram POSTs updates to your URL |
| Needs a public HTTPS URL | No | Yes |
| Needs to run 24/7 | Yes | No (it can wake on request) |
| Good for | Local development | Production |

Every app on DockHosting gets an HTTPS URL like `https://mybot.dockhosting.cloud`, so the HTTPS requirement is already covered.

## 1. Create the bot

Message [@BotFather](https://t.me/BotFather) on Telegram, send `/newbot` and follow the prompts. You'll get a token like `123456:ABC-DEF…`.

> The token gives full control of your bot. Keep it in an environment variable (`BOT_TOKEN`) and never commit it.

## 2a. Node.js webhook bot

No bot library is needed: the [Bot API](https://core.telegram.org/bots/api) is plain HTTPS and JSON.

```js
// index.js
import express from "express";

const { BOT_TOKEN, WEBHOOK_SECRET, PORT = 3000 } = process.env;
const api = (method, body) =>
  fetch(`https://api.telegram.org/bot${BOT_TOKEN}/${method}`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify(body),
  });

const app = express();
app.use(express.json());

app.post("/telegram", async (req, res) => {
  // Reject anything that isn't from Telegram.
  if (req.get("X-Telegram-Bot-Api-Secret-Token") !== WEBHOOK_SECRET) return res.sendStatus(401);
  const msg = req.body.message;
  if (msg?.text) await api("sendMessage", { chat_id: msg.chat.id, text: `You said: ${msg.text}` });
  res.sendStatus(200);
});

app.get("/", (_, res) => res.send("ok"));
app.listen(PORT);
```

```json
{ "type": "module", "scripts": { "start": "node index.js" }, "dependencies": { "express": "^5" } }
```

## 2b. Python webhook bot (FastAPI)

```python
# main.py
import os
import httpx
from fastapi import FastAPI, Header, HTTPException, Request

TOKEN = os.environ["BOT_TOKEN"]
SECRET = os.environ["WEBHOOK_SECRET"]
app = FastAPI()

@app.post("/telegram")
async def telegram(request: Request, x_telegram_bot_api_secret_token: str = Header(None)):
    if x_telegram_bot_api_secret_token != SECRET:
        raise HTTPException(status_code=401)
    update = await request.json()
    msg = update.get("message") or {}
    if "text" in msg:
        async with httpx.AsyncClient() as client:
            await client.post(f"https://api.telegram.org/bot{TOKEN}/sendMessage",
                              json={"chat_id": msg["chat"]["id"], "text": f"You said: {msg['text']}"})
    return {"ok": True}
```

`requirements.txt`: `fastapi`, `uvicorn[standard]`, `httpx`. FastAPI projects are detected and run with Uvicorn for you. More in the [FastAPI deploy guide](/deploy-fastapi-app).

## 3. Deploy

```bash
curl -fsSL https://cli.dockhosting.dev/install.sh | sh   # Windows: irm https://cli.dockhosting.dev/install.ps1 | iex
dock login
dock deploy
```

In the project's environment variables, set `BOT_TOKEN` and a long random `WEBHOOK_SECRET` (letters, digits, `_` and `-`), then run `dock restart`.

## 4. Point Telegram at your URL

Run this once from your terminal, using your app's address:

```bash
curl "https://api.telegram.org/bot$BOT_TOKEN/setWebhook" \
  -d "url=https://mybot.dockhosting.cloud/telegram" \
  -d "secret_token=$WEBHOOK_SECRET"
```

Check it with `getWebhookInfo`, then message your bot. `dock logs` shows each request as it arrives.

## Free plan vs always on

On the **Free plan**, the app sleeps after 1 hour without requests. The next Telegram update wakes it, so the reply comes a few seconds later than usual. Telegram also retries updates that fail. For a bot people use all day, **Hobby ($4/month)** is always on and replies instantly.

Need a long-running bot that keeps a socket open instead? That's how Discord bots work: see [hosting a Discord bot 24/7](/host-discord-bot-24-7).

## FAQ

### Can I host a Telegram bot for free?

Yes, with webhooks. Telegram delivers each update as an HTTPS request, and on DockHosting's Free plan a sleeping app wakes on the next request, so the first reply after a quiet hour can take a few seconds. For instant replies all the time, Hobby ($4/month) is always on.

### Webhook or long polling: which should I use?

Polling keeps a process asking Telegram for updates, so it must run all the time. Webhooks let Telegram push updates to your URL, which needs HTTPS but no always-running loop. For hosted bots, webhooks are simpler and cheaper.

### Does Telegram need HTTPS for webhooks?

Yes. Every DockHosting app gets HTTPS automatically on its .dockhosting.cloud address, so the URL works as a webhook right away.
