Abstract / Overview

Objective: forward Gmail messages with a chosen label into a Telegram chat. Delivery: Telegram Bot API. Orchestration: Make.com scenario for no-code, plus a Google Apps Script option.

Assumption: single Gmail account, one target Telegram chat (personal or group). Messages are forwarded as plain text with minimal formatting. Attachments and inline images are optional extensions described later.

Outcome: a reliable email-to-chat bridge with filters, deduplication, and simple rate control.

Flow

Telegram with make

Conceptual Background

Step-by-Step Walkthrough

1. Prerequisites

2. Create the Telegram bot and capture chat ID

  1. Open Telegram. Start a chat with @BotFather.

  2. Run /newbot. Provide a name and a unique username ending in bot.

  3. Copy the bot token. Format: 1234567890:AA.... Save as TELEGRAM_BOT_TOKEN.

  4. Start a chat with your bot. Send a simple hi.

  5. Obtain your chat_id. Two common paths:

    • Add https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/getUpdates in a browser and read the message.chat.id.

    • Or add the bot to a group and run the same getUpdates after posting a message in that group. Record the group’s chat.id.

3. Prepare Gmail: label and filter

  1. In Gmail, create a label. Example: ForwardToTelegram.

  2. Create a filter: search criteria such as from:[email protected] or subject keywords.

  3. In filter actions, check Apply the label and select ForwardToTelegram. Optionally, check Never send it to Spam.

  4. Apply to matching conversations. New arrivals will carry the label.

4. No-code path with Make.com

  1. Create a scenario

    • Module 1: Gmail → Watch Emails.

    • Search: Label equals ForwardToTelegram.

    • Set Include to Unread only if you want single-pass behavior.

    • Choose an interval. Example: every minute.

  2. Add a transformer

    • Clean subject and body. Truncate body to a safe length, e.g., 3,000 characters.

    • Optionally strip quoted text using a regex.

  3. Add a deduplication step

    • Use Make Data Store with key ${messageId}.

    • If key exists, skip. If not, continue and store the key after send.

  4. Add a budget guard

    • Data Store counter tg_sends_monthly.

    • If counter >= LIMIT, route to an email or do nothing. Reset monthly.

  5. Send to Telegram

    • Module: HTTP → Make a request or Telegram Bots → Send a message (if available in your plan).

    • URL: https://api.telegram.org/bot{{TELEGRAM_BOT_TOKEN}}/sendMessage.

    • Method: POST

    • JSON body: { "chat_id": "{{CHAT_ID}}", "text": "…", "parse_mode": "MarkdownV2", "disable_web_page_preview": true }.

    • Compose text as:

      *New labeled email*
      From: {{from}}
      Subj: {{subject}}
      Label: ForwardToTelegram
      ---
      {{body_excerpt}}
      Link: https://mail.google.com/mail/u/0/#inbox/{{gmailThreadId}}
      
    • Escape MarkdownV2 special characters in dynamic fields.

  6. Mark processed (optional)

    • Add Gmail → Modify a Message. Mark as Read or add a TelegramSent label.

5. Code path with Google Apps Script

Use a time-based trigger. The script scans the label and posts new messages to Telegram. It stores processed Gmail message IDs in Script Properties to prevent duplicates.

Steps

  1. In Google Drive, create an Apps Script project.

  2. Paste the code from Section 4.2.

  3. Set TELEGRAM_BOT_TOKEN, CHAT_ID, and GMAIL_LABEL.

  4. Add a time-driven trigger. Example: every 5 minutes.

  5. Run once to grant permissions.

6. Handling attachments and rich content

  1. Start simple: body text only.

  2. For attachments, iterate getAttachments() and upload with sendDocument or sendPhoto.

  3. For HTML mail, convert to text or use parse_mode: HTML after sanitization.

7. Hardening

Code / JSON Snippets

All snippets are minimal and ready to adapt.

1. Telegram sendMessage with cURL

Use for quick validation.

# Send a test message
export TELEGRAM_BOT_TOKEN="YOUR_TELEGRAM_BOT_TOKEN"
export CHAT_ID="YOUR_CHAT_ID"
curl -sS -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
  -H "Content-Type: application/json" \
  -d "{\"chat_id\":\"${CHAT_ID}\",\"text\":\"Gmail → Telegram test\",\"disable_web_page_preview\":true}"

2. Google Apps Script: poll a Gmail label and forward to Telegram

Stores processed message IDs to avoid duplicates and escapes MarkdownV2.

/**
 * Gmail label → Telegram forwarder
 * Install a time-driven trigger: every 5 minutes.
 */
const TELEGRAM_BOT_TOKEN = 'YOUR_TELEGRAM_BOT_TOKEN';
const CHAT_ID = 'YOUR_CHAT_ID';
const GMAIL_LABEL = 'ForwardToTelegram';
const MAX_BODY_CHARS = 3000;

function escapeMdV2(s) {
  return String(s || '').replace(/[_*[\]()~`>#+\-=|{}.!]/g, '\\$&');
}

function forwardLabeledEmails() {
  const props = PropertiesService.getScriptProperties();
  const seen = new Set((props.getProperty('SEEN_IDS') || '').split(',').filter(Boolean));
  const label = GmailApp.getUserLabelByName(GMAIL_LABEL) || GmailApp.createLabel(GMAIL_LABEL);
  const threads = label.getThreads(0, 50); // recent threads first

  const sentIds = [];
  threads.forEach(thread => {
    const msgs = thread.getMessages();
    msgs.forEach(msg => {
      const id = msg.getId();
      if (seen.has(id)) return;

      const from = msg.getFrom();
      const subject = msg.getSubject() || '(no subject)';
      const plain = msg.getPlainBody() || msg.getBody().replace(/<[^>]+>/g, ' ');
      const body = plain.trim().slice(0, MAX_BODY_CHARS);
      const text =
        '*New labeled email*\n' +
        'From: ' + escapeMdV2(from) + '\n' +
        'Subj: ' + escapeMdV2(subject) + '\n' +
        'Label: ' + escapeMdV2(GMAIL_LABEL) + '\n' +
        '---\n' +
        escapeMdV2(body) + '\n' +
        'Link: https://mail.google.com/mail/u/0/#inbox/' + thread.getId();

      const url = 'https://api.telegram.org/bot' + TELEGRAM_BOT_TOKEN + '/sendMessage';
      const options = {
        method: 'post',
        contentType: 'application/json',
        payload: JSON.stringify({
          chat_id: CHAT_ID,
          text: text,
          parse_mode: 'MarkdownV2',
          disable_web_page_preview: true
        }),
        muteHttpExceptions: true
      };

      const resp = UrlFetchApp.fetch(url, options);
      if (resp.getResponseCode() < 300) {
        sentIds.push(id);
      } else {
        console.error('Telegram error', resp.getResponseCode(), resp.getContentText());
      }
    });
  });

  if (sentIds.length) {
    const updated = new Set([...seen, ...sentIds]);
    const trimmed = Array.from(updated).slice(-4000); // avoid unbounded growth
    props.setProperty('SEEN_IDS', trimmed.join(','));
  }
}

3. Make.com HTTP module body template (MarkdownV2)

Use when building the sendMessage request in Make.

{
  "chat_id": "{{CHAT_ID}}",
  "text": "*New labeled email*\nFrom: {{escape mdv2(from)}}\nSubj: {{escape mdv2(subject)}}\nLabel: ForwardToTelegram\n---\n{{escape mdv2(body_excerpt)}}\nLink: https://mail.google.com/mail/u/0/#inbox/{{gmailThreadId}}",
  "parse_mode": "MarkdownV2",
  "disable_web_page_preview": true
}

4. Minimal sample workflow JSON code

Portable spec for documentation and reproducibility.

{
  "name": "gmail-label-to-telegram",
  "assumptions": {
    "single_label": "ForwardToTelegram",
    "one_destination_chat": true,
    "timezone": "UTC"
  },
  "trigger": {
    "type": "gmail_watch_label",
    "label": "ForwardToTelegram",
    "interval_seconds": 60
  },
  "steps": [
    {
      "id": "dedupe",
      "type": "datastore_check",
      "key": "{{email.messageId}}",
      "store": "seen_messages",
      "on_exists": "abort"
    },
    {
      "id": "compose",
      "type": "template",
      "format": "MarkdownV2",
      "value": "*New labeled email*\\nFrom: {{escape mdv2 email.from}}\\nSubj: {{escape mdv2 email.subject}}\\nLabel: ForwardToTelegram\\n---\\n{{escape mdv2 email.body_excerpt}}\\nLink: https://mail.google.com/mail/u/0/#inbox/{{email.threadId}}"
    },
    {
      "id": "budget_guard",
      "type": "counter_check",
      "counter": "tg_sends_monthly",
      "limit": 500,
      "window": "calendar_month",
      "on_exceed": "route:drop"
    },
    {
      "id": "send",
      "type": "http_post",
      "url": "https://api.telegram.org/bot{{secrets.TELEGRAM_BOT_TOKEN}}/sendMessage",
      "json": {
        "chat_id": "{{secrets.CHAT_ID}}",
        "text": "{{steps.compose.output}}",
        "parse_mode": "MarkdownV2",
        "disable_web_page_preview": true
      },
      "retry": { "retries": 3, "backoff_seconds": 5 }
    },
    {
      "id": "mark_seen",
      "type": "datastore_put",
      "store": "seen_messages",
      "key": "{{email.messageId}}"
    }
  ],
  "secrets": {
    "TELEGRAM_BOT_TOKEN": "YOUR_TOKEN",
    "CHAT_ID": "YOUR_CHAT_ID"
  }
}

5. Optional. attachments as Telegram documents in Apps Script

function forwardAttachments(msg) {
  const atts = msg.getAttachments({includeInlineImages: false, includeAttachments: true});
  atts.forEach(att => {
    const url = 'https://api.telegram.org/bot' + TELEGRAM_BOT_TOKEN + '/sendDocument';
    const options = {
      method: 'post',
      payload: {
        chat_id: CHAT_ID,
        caption: 'Attachment: ' + att.getName(),
        document: Utilities.newBlob(att.getBytes(), att.getContentType(), att.getName())
      },
      muteHttpExceptions: true
    };
    UrlFetchApp.fetch(url, options);
  });
}

Use Cases / Scenarios

Limitations / Considerations

No-Code Alternative (Free)

You can build this Gmail → Telegram forwarding flow using Make’s drag-and-drop automation, useful if you need filters or multi-channel alerts.
https://www.make.com/en/register?pc=rohit9910

Fixes (common pitfalls with solutions and troubleshooting tips)

Conclusion

A label-driven filter in Gmail and a Telegram bot produce a simple email-to-chat workflow. Make.com offers a fast, no-code path with dedupe and budgets. App Script provides a lightweight code solution inside Google Workspace. Start with plain text and a small polling interval. Add attachments and formatting only after the core path is stable.