# Telegram bot for a contact form: build or skip?

Build your own Telegram bot for a website form with a short Cloudflare Worker, or skip the bot. Working code, chat ID steps, and the token mistake to avoid.

Author: Formgong
Published: 2026-10-03
Language: en
Canonical: https://formgong.com/en/blog/telegram-bot-for-contact-form/

You can send a contact form to Telegram with your own bot. Create it in @BotFather, find your chat ID, and forward the form from a small server function that calls sendMessage. The bot token must stay on the server. If you do not want to run that code, a form backend with built-in Telegram delivery does the same job without a bot.

## Three ways to get form leads into Telegram

Ask Bolt, Lovable or ChatGPT how to send a contact form to Telegram, and the usual answer is “build your own bot”. That works. But it is only one of three options:

- **Your own bot and a small server function.** Free on most hosts and fully yours. You write and maintain about 25 lines of code.

- **An automation tool** such as Zapier, Make or n8n. A webhook step receives the form, a Telegram step posts it. No code, but one more account and its own pricing.

- **A form backend with Telegram built in.** You change the form's `action` and connect a chat. No bot and no server code. Formgong works this way, and so does Formspree with its Telegram plugin.

This guide builds the first option end to end. Then it shows what the code does not cover, so you can choose with open eyes.

## 1. Create the bot and find your chat ID

- Open **@BotFather** in Telegram and send `/newbot`. Pick a name and a username that ends in `bot`.

- BotFather replies with a token like `123456789:AAH…`. Treat it like a password.

- Open your new bot and press **Start**. A bot cannot write to you before you do this.

- In a browser, open `https://api.telegram.org/bot<TOKEN>/getUpdates`. Find `"chat":{"id":…}`. That number is your chat ID.

For a team group, add the bot to the group and send `/start@your_bot` there. Group IDs are negative numbers, such as `-1001234567890`. Keep the minus sign.

## 2. Forward the form with a Cloudflare Worker

The form needs a server that holds the token and calls the Bot API. A Cloudflare Worker is the smallest option. The Workers Free plan includes 100,000 requests a day (checked 03.10.2026). The same code also fits a Supabase Edge Function or a Netlify Function.

The Worker reads the form, drops bot traffic caught by a hidden honeypot field, trims long values, and sends plain text. Plain text avoids escaping problems with names like `O'Brien <3`. A Telegram message holds up to 4,096 characters, so the message field is cut at 3,000.

```javascript
// src/index.js: receives the form and posts it to Telegram
export default {
  async fetch(request, env) {
    if (request.method !== "POST") return new Response("POST only", { status: 405 });
    const form = await request.formData();
    // Honeypot: people never see this field, bots fill it in.
    if (form.get("botcheck")) return Response.redirect(env.THANK_YOU_URL, 303);
    const name = String(form.get("name") ?? "").slice(0, 200);
    const email = String(form.get("email") ?? "").slice(0, 200);
    const message = String(form.get("message") ?? "").slice(0, 3000);
    if (!email || !message) return new Response("Email and message are required", { status: 400 });
    const text = `New enquiry\nName: ${name}\nEmail: ${email}\n\n${message}`;
    const sent = await fetch(`https://api.telegram.org/bot${env.TELEGRAM_BOT_TOKEN}/sendMessage`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ chat_id: env.TELEGRAM_CHAT_ID, text }),
    });
    if (!sent.ok) return new Response("Could not deliver the message", { status: 502 });
    return Response.redirect(env.THANK_YOU_URL, 303);
  },
};
```

**Deploy commands and secrets**

```bash
npm create cloudflare@latest contact-to-telegram
cd contact-to-telegram
# paste the Worker code into src/index.js, then:
npx wrangler secret put TELEGRAM_BOT_TOKEN
npx wrangler secret put TELEGRAM_CHAT_ID
# add to wrangler.jsonc: "vars": { "THANK_YOU_URL": "https://example.com/thanks" }
npx wrangler deploy
```

**The HTML form that posts to the Worker**

```html
<form action="https://contact-to-telegram.YOUR-SUBDOMAIN.workers.dev" method="POST">
  <label>Name <input name="name" autocomplete="name"></label>
  <label>Email <input type="email" name="email" required autocomplete="email"></label>
  <label>Message <textarea name="message" required></textarea></label>
  <input type="text" name="botcheck" tabindex="-1" autocomplete="off" hidden>
  <button type="submit">Send</button>
</form>
```

## Never put the bot token in the browser

Some generated code calls `api.telegram.org` straight from the page. It seems to work in the preview. But anyone can open the page source, copy the token and use your bot: send messages in its name, read its updates, or change its webhook.

Keep the token in a server secret, as in the commands above. If a token has already shipped in frontend code, send `/revoke` to BotFather and set the new token as a secret. The same applies to Bolt and Lovable projects: ask the builder to move the call into a backend function and store the token in its secrets.

## What a home-made bot does not do

The Worker above is a working minimum. Before you rely on it for real leads, know its gaps:

- **No copy of the lead.** If Telegram is down or the chat ID is wrong, the visitor sees an error and the message exists nowhere else. Add storage or an email step if leads matter.

- **Thin spam protection.** A honeypot stops simple bots only. Add Cloudflare Turnstile or rate limits when spam starts.

- **One chat, no status.** Several chats, “done” buttons or reminders about leads nobody answered mean more code.

- **Limits.** Telegram asks bots to send no more than about one message per second to one chat and 20 messages a minute to a group. A contact form rarely gets close.

- **Maintenance.** Token rotation, error alerts and updates are now your job.

## Skip the bot: connect Telegram to the form

If you only need each submission in a chat, a form backend saves you the bot and the Worker. With Formgong:

- Get a free form key on [formgong.com](/en/#top) and confirm your email.

- Point the form at Formgong: set `action="https://formgong.com/submit"` and add the key as a hidden field. Your design stays the same.

- In the form settings, open Telegram and press connect. The Formgong bot opens; press Start. For a group, add the bot and send the `/connect` code shown in settings.

Each lead is also saved in your inbox and sent by email. Spam is filtered before it reaches the chat. Telegram is included on the Free plan with 300 submissions a month; see [pricing](/en/#pricing). The step-by-step guide is [how to send website form submissions to Telegram](/en/blog/website-form-to-telegram/). To compare services that offer Telegram, see the [form backend comparison](/en/compare/).

## Frequently asked questions

### Is it safe to put a Telegram bot token in website code?

No. Anyone who views the page source can copy the token and control the bot. Keep it in a server secret and call the Bot API from a server function. If it has leaked, revoke it in BotFather.

### How do I find my Telegram chat ID?

Press Start in a chat with your bot, then open the getUpdates URL with your token in a browser. The chat id in the response is the one to use. For a group, send /start@your_bot in the group; group IDs are negative.

### Can the bot post form submissions to a group?

Yes. Add the bot to the group, read the group ID from getUpdates, and use it as chat_id. Telegram limits bots to about 20 messages a minute in one group.

### Is a Cloudflare Worker free for a contact form?

For most sites, yes. The Workers Free plan includes 100,000 requests a day, as checked on 3 October 2026. A contact form uses one request per submission.

### Do I need my own bot to get leads in Telegram?

No. Form backends such as Formgong connect a chat to the form through their own bot. You only change the form's action and press connect in the settings.

## Sources and documentation

- [Telegram Bot API: sendMessage](https://core.telegram.org/bots/api#sendmessage)
- [Telegram Bot FAQ: limits](https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this)
- [Telegram: BotFather](https://core.telegram.org/bots/features#botfather)
- [Cloudflare Workers pricing](https://developers.cloudflare.com/workers/platform/pricing/)
- [Cloudflare Workers secrets](https://developers.cloudflare.com/workers/configuration/secrets/)
- [Formgong documentation](https://formgong.com/en/docs/)

[Get a form key](https://formgong.com/en/#top)
