Connect a Website to the Telegram Bot API Safely
A website form and a Telegram bot solve different parts of a workflow. Your application owns the submission; Telegram is a convenient notification channel. Keeping those responsibilities separate makes failures easier to
A website form and a Telegram bot solve different parts of a workflow. Your application owns the submission; Telegram is a convenient notification channel. Keeping those responsibilities separate makes failures easier to handle and keeps your bot token out of visitors' browsers.
Design the flow first
A practical flow is: validate the form on your server, save the submission, put a notification job in a queue, and send a short message to the team's Telegram chat. Return a response to the visitor once the submission is safely stored. The notification worker can run independently.
Avoid placing the bot token in HTML, frontend JavaScript, a public repository, logs, or a screenshot. Store it in your application's secrets system or environment. Use a separate test bot and test chat before connecting a production destination.
Create a bot and choose a destination
Use Telegram's official @botfather account to create a bot and obtain its token. The token controls the bot; revoke and replace it if exposed. For a private chat, a user must first start a conversation with the bot. For a group, add the bot and confirm it has permission to send messages.
Your application needs the destination's chat_id. In a test environment, send a message to the bot and inspect the chat object in an update returned by getUpdates. Group identifiers can be negative, so preserve the complete value. Treat the destination as server configuration, not as a form field supplied by an anonymous visitor.
Incoming updates can be delivered by webhook or retrieved with long polling. Telegram does not provide getUpdates while a webhook is configured for that bot. Do not remove a working webhook just to perform a test; use another bot or inspect the existing handler instead. An outbound notification alone does not require a webhook.
Send a server-side test message
The following PHP example uses cURL and environment variables. It sends plain text so that untrusted input cannot accidentally become formatting markup.
<?php
function notifyTelegram(string $message): bool {
$token = getenv('TELEGRAM_BOT_TOKEN');
$chatId = getenv('TELEGRAM_CHAT_ID');
if (!$token || !$chatId) {
error_log('Telegram configuration is missing');
return false;
}
$ch = curl_init('https://api.telegram.org/bot' . $token . '/sendMessage');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'chat_id' => $chatId,
'text' => $message,
]),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 10,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = is_string($body) ? json_decode($body, true) : null;
return $status >= 200 && $status < 300
&& is_array($result) && !empty($result['ok']);
}
Call notifyTelegram('Test notification') from a controlled server-side test. This is a connectivity example, not a complete form handler. The request URL contains the bot token, so make sure HTTP debugging, exception reporting, and proxy logs do not expose it. See the official Bot API reference for method parameters and responses.
Make delivery resilient
Save the submission before starting a notification job. Include a stable internal reference such as βNew request #1842β and, where appropriate, a link to a protected dashboard. A queue can record the job state, attempts, and last error while leaving the visitor-facing request responsive.
Treat ambiguous failures carefully. A connection timeout does not prove the message was never delivered: the remote service may have accepted it before the response was lost. A blind retry can create duplicates. Record an uncertain outcome and use the internal request number to support reconciliation. Respect any rate-limit guidance returned by the API and alert an operator when delivery stays unhealthy.
A successful Telegram response confirms an API operation; it is not your source of truth for the original submission. Check your own database or CRM for that.
Protect the form and the chat
Validate fields and lengths on the server. Add appropriate CSRF protection to authenticated workflows, rate limits, and spam controls. Limit request sizes. Do not accept the target chat from the public form. Give the bot only the access it needs and restrict membership of the receiving group.
Send the minimum useful information. An identifier and a link to an access-controlled record are often safer than forwarding the complete form. Avoid passwords, payment credentials, and other secrets in notifications. Decide how long chat history should be accessible and who is responsible for reviewing access.
If the bot also receives messages
Incoming messages require a separate handler. For a webhook, use an HTTPS endpoint and validate the secret header when configured using Telegram's webhook secret token. Reject malformed input, limit payload size, and enqueue longer work. Store update identifiers to prevent a repeated update from triggering the same business action twice.
For polling, manage the update offset and make sure only the intended consumer handles the bot. A bot cannot initiate an arbitrary private chat with a visitor simply because the site collected a name or phone number; the person must start the bot interaction through a supported Telegram flow.
Launch checklist
- Confirm the bot token is stored only on the server and is absent from logs.
- Verify the destination ID and send a test message to the intended chat.
- Save submissions before creating notification jobs.
- Test a network outage and verify that the submission is still available.
- Handle uncertain delivery outcomes without an uncontrolled retry loop.
- Review chat membership, data minimization, monitoring, and the escalation contact.
- If receiving updates, verify webhook authentication and duplicate handling.
Start with one form and a test bot. Once failure handling and access controls are in place, switch the server configuration to the production destination.
Russian-language source: https://morlix.ru/blog/kak-podklyuchit-telegram-bot-api-k-saytu
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.