서버 장애 알림이나 사용자의 실시간 결제 완료 메시지를 텔레그램으로 보낼 때, API 요청이 멈추거나 메시지가 수신되지 않는 현상을 경험해봤을 것이다. 단순한 HTTP 요청으로 보이지만, 정확한 Bot Token 생성부터 API 엔드포인트 호출, SSL 인증 환경에서 작동하는 Webhook 연동까지 정확한 원인이나 해결책을 모르는 경우가 많다. 이번에는 Telegram Bot API가 정확히 무엇이고 왜 실시간 알림 시스템에 유용한지, 그리고 PHP cURL을 이용해 안정적으로 메시지를 보내고 Webhook 요청을 수신하는 방법까지 완벽하게 정리해서 소개하겠다.
텔레그램 봇(Telegram Bot)은 사용자가 작성한 서버 프로그램과 텔레그램 클라이언트 간의 중계 역할을 수행하는 특별한 계정이다. 슬랙이나 디스코드에 비해 설정 과정이 매우 단순하고, 가입 절차나 별도의 복잡한 OAuth 2.0 인증 과정 없이 봇 토큰(Bot Token) 하나만으로 즉시 메시지를 발송할 수 있다.
텔레그램 봇을 생성하려면 텔레그램 앱에서 @BotFather 검색 후 /newbot 명령어를 입력하면 된다. 생성이 완료되면 123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ 형식의 HTTP API 토큰을 발급받게 된다.
| 구분 | Telegram Bot API | Slack Webhook | Discord Webhook |
|---|---|---|---|
| 인증 방식 | Bot Token (HTTP Header / URL) | Custom Webhook URL | Custom Webhook URL |
| 수신 메시지 처리 | Long Polling 또는 Webhook | Event Subscriptions | Bot Gateway / Webhook |
| SSL/TLS 필수 여부 | Webhook 등록 시 필수 (HTTPS) | 기본 권장 | 기본 권장 |
| 발송 제한(Ratelimit) | 초당 약 30건 (그룹방 1분당 20건) | 초당 1건 내외 | 초당 5건 내외 |
많은 개발자가 file_get_contents() 함수로 API를 호출하다가 네트워크 타임아웃이나 SSL 핸드셰이크 오류를 겪는다. 실무에서는 cURL 옵션을 정교하게 설정하여 예외 상황을 제어해야 한다.
✗ 잘못된 코드(타임아웃 및 SSL 검증 처리 미비)
<?php
$botToken = "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ";
$chatId = "987654321";
$message = "서버 장애 발생!";
// file_get_contents는 네트워크 지연 시 프로세스를 멈추게 만들며, HTTP 상태 코드를 세밀하게 제어할 수 없다.
$url = "https://api.telegram.org/bot{$botToken}/sendMessage?chat_id={$chatId}&text=" . urlencode($message);
$response = file_get_contents($url);
?>✓ 올바른 코드(cURL 타임아웃, POST 방식 및 JSON 응답 검증 적용)
<?php
function sendTelegramMessage(string $botToken, string $chatId, string $text): bool
{
$url = "https://api.telegram.org/bot{$botToken}/sendMessage";
$postData = [
'chat_id' => $chatId,
'text' => $text,
'parse_mode' => 'HTML'
];
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($postData),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_CONNECTTIMEOUT => 3,
CURLOPT_SSL_VERIFYPEER => true
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error || $httpCode !== 200) {
error_log("Telegram API Error [{$httpCode}]: {$error} / Response: {$response}");
return false;
}
$result = json_decode($response, true);
return isset($result['ok']) && $result['ok'] === true;
}
// 실전 사용 예시
$botToken = "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ";
$chatId = "987654321";
$success = sendTelegramMessage($botToken, $chatId, "<b>[경고]</b> DB 연결 실패 발생!");
var_dump($success);
?>결과/출력값
bool(true)
메시지를 보낼 뿐만 아니라 사용자가 텔레그램 봇에게 전송한 메시지를 서버에서 실시간으로 받아 처리하려면 Webhook(웹훅)을 등록해야 한다. 텔레그램은 HTTPS 프로토콜이 적용된 URL만 Webhook으로 허용한다.
✓ 올바른 코드(Webhook 등록 API 및 수신 엔드포인트 구현)
<?php
// 1. Webhook 등록 스크립트 (최초 1회 실행)
$botToken = "123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ";
$webhookUrl = "https://yourdomain.com/telegram_webhook.php";
$secretToken = "MySuperSecretKey1234"; // 보안을 위한 시크릿 헤더
$setWebhookUrl = "https://api.telegram.org/bot{$botToken}/setWebhook?url=" . urlencode($webhookUrl) . "&secret_token=" . urlencode($secretToken);
$response = file_get_contents($setWebhookUrl);
echo $response;
// 2. telegram_webhook.php (텔레그램 서버가 요청을 보내오는 수신 파일)
$headerSecret = $_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN'] ?? '';
if ($headerSecret !== "MySuperSecretKey1234") {
http_response_code(403);
exit("Unauthorized");
}
$content = file_get_contents("php://input");
$update = json_decode($content, true);
if (isset($update['message'])) {
$chatId = $update['message']['chat']['id'];
$userText = $update['message']['text'] ?? '';
if ($userText === '/start') {
sendTelegramMessage($botToken, $chatId, "안녕하세요! 시스템 알림 봇입니다.");
}
}
http_response_code(200); // 텔레그램 서버에 정상 수신 응답
?>결과/출력값
{"ok":true,"result":true,"description":"Webhook was set"}
텔레그램 API 연동 시 실무 개발자들이 가장 자주 겪는 문제는 다음과 같다.
- Chat ID 오인: 사용자 개인 Chat ID와 그룹방 Chat ID는 다르다. 그룹방 Chat ID는 보통 마이너스(-) 기호로 시작하므로 문자열 형태로 안전하게 다뤄야 한다.
- HTTP 200 미반환 문제: Webhook 수신 파일에서 오류가 발생해 HTTP 200 이외의 응답을 반환하면, 텔레그램 서버는 요청이 실패했다고 판단해 동일한 이벤트를 재시도한다. 이로 인해 동일한 답장이 무한 반복되는 현상이 일어난다.
- SSL 인증서 체인 오류: 자가 서명(Self-signed) 인증서를 사용하는 웹서버에서는 Webhook 연동이 안 된다. Let's Encrypt 등 정식 SSL 인증서를 사용해야 한다.
- secret_token 검증 누락: Webhook URL이 외부에 노출될 경우 해커가 가짜 요청을 보낼 수 있다. secret_token 매개변수를 지정하고 HTTP 헤더를 반드시 검증하자.
Telegram Bot API는 비즈니스 알림 모니터링부터 가벼운 CS 자동 응답까지 구현할 수 있는 매우 가볍고 강력한 도구다. 타임아웃 처리와 안전한 Webhook 검증이라는 작은 최적화와 보안 습관이 모여서 장애 없는 견고한 알림 시스템을 만든다는 점을 잊지 말자. 이 글의 cURL 래퍼 함수와 Webhook 검증 예제를 참고해 본인의 프로젝트에 연동해 보면, 실시간 이벤트 대응에 필요한 최상의 모니터링 환경을 얻을 수 있을 것이다.