# Telegram

- Tool: FlutterFlow
- Difficulty: Intermediate
- Time required: 30 minutes
- Last updated: July 2026

## TL;DR

Connect FlutterFlow to Telegram by building an API Group that calls the Telegram Bot API's `sendMessage` endpoint. Create a bot via @BotFather, add the API Group in FlutterFlow's left nav, and wire an Action to trigger outbound messages. For any production app, route the bot token through a Firebase Cloud Function — the token ships inside the compiled app bundle otherwise.

## Send Telegram Alerts from Your FlutterFlow App

Telegram's Bot API is one of the most accessible messaging APIs available: it's 100% free, has no per-message cost, and authentication is a single URL-embedded token — no OAuth dance required. For a FlutterFlow founder, the killer use-case is push order alerts, signup notifications, or payment confirmations to an admin Telegram chat the moment something happens in the app. Because the Bot API is a plain HTTPS REST call, it works perfectly in FlutterFlow's web preview and Test Mode — no native plugin needed.

The integration has two layers. The simple layer is outbound: FlutterFlow calls `POST /bot{token}/sendMessage` with a `chat_id` and `text`, and the message appears instantly. The rate limit is generous — roughly 30 messages per second overall and 1 message per second per chat — and Telegram imposes no monthly fees or message quotas. The important caveat is that the bot token sits in the compiled app bundle, which is a security concern for any consumer-facing product.

The upgrade path is a Firebase Cloud Function acting as a thin proxy: your FlutterFlow app calls the function URL with the message params, and the function calls Telegram with the token stored server-side as an environment variable. This keeps the credential off the device. For inbound messages — when users reply to the bot or send commands — FlutterFlow cannot be the webhook receiver; you need a Cloud Function registered via Telegram's `setWebhook` that writes incoming updates to Firestore, which your FlutterFlow app reads via a real-time listener.

## Before you start

- A Telegram account to create and own the bot
- A FlutterFlow project (any plan — this uses the API Calls panel, available on all plans)
- A Firebase project configured in FlutterFlow (needed for the Firestore data layer and optional Cloud Function proxy)
- Numeric chat_id of the target chat — obtain this from an inbound update or via @userinfobot before sending your first message

## Step-by-step guide

### 1. Create a Telegram bot and copy the bot token

Open Telegram and search for @BotFather. Start a chat with it and send the command `/newbot`. BotFather will ask for a display name (e.g., 'MyApp Alerts') and then a username ending in `_bot` (e.g., `myapp_alerts_bot`). Once confirmed, BotFather replies with a message containing your bot token — a string that looks like `7123456789:AAF-xxxxxxxxxxxxxxxxxxxxx`. Copy that token and store it somewhere secure for now (a password manager or a temporary note). This token is the only credential Telegram's Bot API needs. One important restriction: Telegram forbids your bot from sending a direct message to any user who has not first started the bot by pressing /start — so for outbound DMs to app users, you need to capture their chat_id at the moment they initiate the conversation. For admin-channel notifications (sending to a private group or channel you control), this restriction doesn't apply — add the bot to the channel as an admin and use the channel's negative chat_id.

**Expected result:** You have a bot token (format: `1234567890:AAF-...`) and a target chat_id ready to use.

### 2. Add a Telegram API Group and sendMessage call in FlutterFlow

In your FlutterFlow project, click API Calls in the left navigation panel. Click the + Add button and choose Create API Group. Name the group 'Telegram'. Set the Base URL to `https://api.telegram.org`. Leave Authentication as None — Telegram embeds the token in the URL path, not in an auth header. Now click + Add API Call inside the Telegram group. Name it 'SendMessage'. Set the Method to POST. In the API URL field, enter `/bot[token]/sendMessage` — but you'll turn `[token]` into a variable: go to the Variables tab, add a variable named `token` of type String, then reference it in the URL as `/bot[token]/sendMessage` using FlutterFlow's variable syntax. Add two more variables: `chat_id` (String) and `text` (String). In the Body tab, set body type to JSON. Add a key `chat_id` mapped to the variable `[chat_id]` and a key `text` mapped to `[text]`. Optionally add `parse_mode` with a default value of `MarkdownV2` to enable bold/italic formatting. In the Response & Test tab, enter test values for token, chat_id, and text (the chat_id of your admin channel and a short test message), then click Test API Call. A successful response returns {"ok": true, "result": {...}}. You should see the message appear in your Telegram chat immediately.

```
{
  "method": "POST",
  "url": "https://api.telegram.org/bot[token]/sendMessage",
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "chat_id": "[chat_id]",
    "text": "[text]",
    "parse_mode": "MarkdownV2"
  }
}
```

**Expected result:** The API Call test returns `{"ok": true}` and a message appears in the target Telegram chat.

### 3. Wire the sendMessage call to a button Action in your FlutterFlow UI

Select the button or widget in your FlutterFlow UI that should trigger the Telegram message. Open the Actions panel on the right side and click + Add Action. Choose Backend/API Call from the action type list. Select the Telegram API Group, then the SendMessage call. You'll now see a field for each variable (token, chat_id, text). For `token`, you can temporarily hard-code the bot token as a constant in App Settings → App Values — name the constant `TELEGRAM_BOT_TOKEN` and use it here. For `chat_id`, set a fixed value or bind it to a page state variable that holds the admin channel's chat_id. For `text`, bind it to a combination of text and data fields — for example, `New order #[OrderID] placed by [UserEmail]` — using FlutterFlow's dynamic text builder. Add a Snackbar action after the API Call to show 'Notification sent!' to the user as confirmation. Test in Run Mode by clicking the button and verifying the message arrives in Telegram. Because this is a plain HTTPS call, it works in the web preview without any native plugin setup.

**Expected result:** Tapping the button in Run Mode sends a Telegram message to the configured chat and the success Snackbar appears.

### 4. Move the bot token to a Firebase Cloud Function (recommended for production)

Storing the bot token in FlutterFlow's App Values or as a URL variable means it ships inside the compiled Android APK and iOS IPA — anyone who extracts the app bundle can read it. For any real product, the correct pattern is a Firebase Cloud Function that holds the token as an environment variable and acts as a proxy. Deploy the function shown below using your Firebase project's CLI (or paste it into the Firebase console's inline editor). The function accepts `chat_id` and `text` as a JSON body, calls Telegram server-side, and returns the result. Back in FlutterFlow, update your Telegram API Group: change the Base URL to your Cloud Function URL (e.g., `https://us-central1-your-project.cloudfunctions.net`) and update the SendMessage call to POST to `/sendTelegram` with only `chat_id` and `text` — the token is no longer in FlutterFlow at all. Now even if someone reverse-engineers your app, they only find the function URL, not the credential. The function URL itself is unauthenticated in the example below — for extra security, add Firebase Auth token validation in the function and include the user's ID token in the FlutterFlow API Call header.

```
// Firebase Cloud Function: functions/index.js
const functions = require('firebase-functions');
const axios = require('axios');

exports.sendTelegram = functions.https.onRequest(async (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  if (req.method === 'OPTIONS') {
    res.set('Access-Control-Allow-Methods', 'POST');
    res.set('Access-Control-Allow-Headers', 'Content-Type');
    return res.status(204).send('');
  }

  const BOT_TOKEN = functions.config().telegram.token;
  const { chat_id, text } = req.body;

  if (!chat_id || !text) {
    return res.status(400).json({ error: 'chat_id and text are required' });
  }

  try {
    const response = await axios.post(
      `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`,
      { chat_id, text, parse_mode: 'HTML' }
    );
    return res.status(200).json(response.data);
  } catch (err) {
    return res.status(500).json({ error: err.message });
  }
});
```

**Expected result:** The Cloud Function URL responds to a POST with a 200 and `{"ok": true}`. FlutterFlow calls the function URL instead of Telegram directly, and the bot token no longer appears anywhere in the app bundle.

### 5. Receive inbound messages via a webhook Cloud Function and Firestore

FlutterFlow apps cannot receive inbound webhooks — they run on end-user devices, not on a server with a stable URL. To read Telegram messages sent to your bot (user commands, replies, support requests), you need a second Firebase Cloud Function that acts as the webhook receiver. First, deploy the function and note its HTTPS URL. Then register it with Telegram by calling the `setWebhook` endpoint once: `GET https://api.telegram.org/bot{TOKEN}/setWebhook?url={FUNCTION_URL}`. From that point, Telegram sends every incoming update to your function as a POST request. The function extracts the `message` object (with `from.id` as the user's chat_id, `text` as the message content, and `date` as the Unix timestamp) and writes it to a Firestore collection — for example, `telegram_updates`. In FlutterFlow, add a Backend Query to any page that binds to the `telegram_updates` collection. A ListView widget renders the messages in real time using Firestore's live listener. To reply to a user, use the outbound sendMessage call (from Step 3) with the `from.id` captured from Firestore as the chat_id. This pattern gives you a fully functional Telegram inbox in your FlutterFlow app. If RapidDev's team can help you wire this up quickly, you can book a free scoping call at rapidevelopers.com/contact.

```
// Firebase Cloud Function: Telegram webhook receiver
exports.telegramWebhook = functions.https.onRequest(async (req, res) => {
  const update = req.body;
  if (update.message) {
    const msg = update.message;
    await admin.firestore().collection('telegram_updates').add({
      chat_id: msg.chat.id,
      from_id: msg.from.id,
      username: msg.from.username || '',
      text: msg.text || '',
      timestamp: admin.firestore.FieldValue.serverTimestamp()
    });
  }
  return res.status(200).send('OK');
});
```

**Expected result:** Sending a message to your bot in Telegram creates a new document in the `telegram_updates` Firestore collection within seconds, and it appears in the FlutterFlow ListView in real time.

## Best practices

- Never hardcode the bot token directly in FlutterFlow's API Group URL for consumer-facing apps — proxy through a Firebase Cloud Function and store the token in `functions.config()` or Firebase Secret Manager.
- Capture every user's Telegram chat_id from their first /start message via the webhook Cloud Function and store it in Firestore — you cannot DM a user who has not initiated the conversation.
- Add the `parse_mode` parameter (HTML or MarkdownV2) so you can format alerts with bold, links, and line breaks; keep messages under 4,096 characters (Telegram's message length limit).
- For bulk channel notifications, add spacing or batching in the Cloud Function — the 1 message/second per-chat limit triggers 429 errors if you blast multiple messages in quick succession.
- Use Telegram group channels with a private negative chat_id for admin notifications rather than a bot's personal chat — this makes it easy to add multiple team members as channel members without sharing individual chat_ids.
- Validate that FlutterFlow sends non-empty text before triggering the API Call — a blank `text` field returns a 400 error from Telegram.
- For the webhook Cloud Function, always return HTTP 200 to Telegram even if your processing logic fails — if Telegram gets a non-200 response repeatedly, it will retry and eventually disable the webhook.

## Use cases

### E-commerce app that pings an admin Telegram channel on new orders

When a customer completes a purchase in the FlutterFlow app, an action chain calls the Telegram API (or a Cloud Function) with the order details, chat_id of the ops channel, and formatted Markdown text. The admin sees the order number, amount, and product within seconds. No app refresh, no email — just an instant channel ping.

Prompt example:

```
When the user taps 'Place Order' and the Supabase insert succeeds, send a Telegram message to chat_id '-100xxxxxxxxxx' with the order ID and total amount.
```

### SaaS platform that notifies a Telegram group on new sign-ups

Every time a new user registers via Firebase Auth in the FlutterFlow app, a Cloud Function fires and sends a Telegram message to the founders' private group with the user's email and registration timestamp. The team monitors growth without opening any dashboard.

Prompt example:

```
After a successful user registration, call the Cloud Function endpoint that sends 'New sign-up: {email} at {timestamp}' to the Telegram admin group.
```

### Support bot that collects user feedback via Telegram commands

A Cloud Function hosts a Telegram webhook that captures user messages. The FlutterFlow app displays these messages from a Firestore collection in a simple inbox list view, letting the founder respond through a separate admin interface.

Prompt example:

```
Show a list of all inbound Telegram messages stored in the 'telegram_messages' Firestore collection, sorted by timestamp descending.
```

## Troubleshooting

### API Call returns `{"ok": false, "error_code": 401, "description": "Unauthorized"}`

Cause: The bot token is wrong, missing, or has been revoked by BotFather.

Solution: Open @BotFather in Telegram, send /mybots, select your bot, then 'API Token' to confirm the current token. If the token was revoked (e.g., you generated a new one), update it in FlutterFlow's API Group URL variable or in the Cloud Function's config.

### API Call returns `{"ok": false, "error_code": 400, "description": "Bad Request: chat not found"}`

Cause: The chat_id is incorrect, or the bot has not been added to the group/channel, or the user has never started the bot.

Solution: For groups/channels, add the bot as an admin first, then call `getUpdates` to retrieve the actual numeric chat_id (it starts with a minus sign for groups). For direct messages to users, they must first send /start to the bot — you cannot initiate a DM with a user who has not started a conversation.

### The bot receives no webhook updates even though `setWebhook` returned `{"ok": true}`

Cause: Either the Cloud Function URL is not publicly accessible, the SSL certificate is invalid (Telegram requires HTTPS), or there is a conflict with `getUpdates` polling (you can't use both simultaneously).

Solution: Verify the Cloud Function URL returns a 200 when you POST to it directly from a browser or Postman. Firebase Cloud Function URLs are always HTTPS, so SSL should be fine. If you were previously using `getUpdates` polling, call `deleteWebhook` first, then re-register with `setWebhook`.

### Messages send correctly in FlutterFlow's Test Mode (web) but fail in a real Android/iOS build

Cause: This is unlikely for a plain HTTPS API call, but if you're calling a Cloud Function on `localhost` during development, the mobile build cannot reach a local server.

Solution: Ensure you're using the deployed Cloud Function URL (e.g., `https://us-central1-your-project.cloudfunctions.net/sendTelegram`) rather than a localhost development URL. Re-test on a real device after deploying the function.

## Frequently asked questions

### Is the Telegram Bot API free to use?

Yes, completely free. Telegram charges nothing for Bot API usage — no per-message fees, no monthly costs, and no quotas beyond the rate limit (~30 messages/second overall, ~1 message/second per chat). This makes it ideal for high-volume internal notifications from a FlutterFlow app.

### Do I need a FlutterFlow paid plan to use the API Calls panel?

No. FlutterFlow's API Calls panel is available on all plans including the Free plan. You can build and test the Telegram sendMessage call without any subscription. Firebase Cloud Functions do require a Firebase Blaze (pay-as-you-go) plan, but they include a generous free tier that covers most small apps.

### Can I send messages to multiple chat_ids from one API Call?

Telegram's `sendMessage` endpoint accepts one chat_id per call. To notify multiple chats (e.g., several admin users), you need to loop through chat_ids and fire a separate API Call or Cloud Function request for each one. Do this inside the Cloud Function with a short delay between calls to stay under the rate limit.

### Why can't I receive Telegram messages directly in FlutterFlow?

FlutterFlow compiles to a Flutter client app that runs on the user's device. Telegram delivers inbound updates to a server-side webhook URL — a permanently-addressable HTTPS endpoint. A mobile or web app running on a device doesn't have a stable public URL, so it cannot be a webhook receiver. The correct architecture is a Firebase Cloud Function as the webhook endpoint that writes updates to Firestore, which the FlutterFlow app reads via a real-time listener.

### Can my bot send photos, files, or buttons, not just text?

Yes. The Telegram Bot API supports `sendPhoto`, `sendDocument`, `sendAudio`, and interactive inline keyboards (`reply_markup`). Add additional API Calls to your Telegram API Group for each method you need. The FlutterFlow setup is the same — just change the endpoint and body fields to match the specific method's parameters.

---

Source: https://www.rapidevelopers.com/flutterflow-integrations/telegram
© RapidDev — https://www.rapidevelopers.com/flutterflow-integrations/telegram
