Implementasi Bot Telegram dalam Python dan JavaScript dengan penempatan ke AWS
Dan menempatkan bot Telegram baru ke AWS
Berikut adalah catatan saya dengan tutorial langkah demi langkah tentang cara mengimplementasikan dan mendeploy ke AWS sebuah bot Telegram. Saya telah menambahkan panduan cepat (long polling) dan jalur produksi (webhooks), dengan contoh dalam Python dan Node.js.
Bot Telegram adalah aplikasi yang berjalan di server Anda dan berkomunikasi dengan pengguna melalui Telegram. Kita akan mendaftarkan bot, menulis program kecil, dan menghubungkannya ke Bot API Telegram.
TL;DR
- Buat bot melalui @BotFather → dapatkan token.
- Bangun aplikasi kecil dengan python-telegram-bot atau Telegraf.
- Mulai dengan long polling secara lokal; beralih ke webhooks untuk produksi.
Apa yang Anda butuhkan
-
Akun Telegram (mobile atau desktop)
-
Terminal dasar + editor kode
-
Salah satu dari berikut:
- Python 3.10+ dan
pip
- Node.js 18+ dan
npm
/pnpm
/yarn
- Python 3.10+ dan
Buat bot Anda dengan BotFather (dapatkan token)
- Di Telegram, cari @BotFather dan mulai percakapan.
- Kirim
/newbot
dan ikuti petunjuk untuk menamai bot Anda dan memilih nama pengguna unik (harus diakhiri denganbot
), misalnyaexample_helper_bot
. - BotFather merespons dengan token API seperti
123456:ABC-DEF...
. Anggap ini seperti kata sandi; jangan masukkan ke Git. Anda selalu dapat menghasilkan ulang token ini melalui BotFather jika bocor.
Tips: Tutorial resmi Telegram membahas langkah-langkah ini secara eksak dan cara memverifikasi token Anda dengan
getMe
.
Pilih stack Anda
Anda dapat memanggil Bot API HTTP mentah sendiri, tetapi menggunakan perpustakaan yang dipelihara akan lebih cepat.
- Python:
python-telegram-bot
(asinkron, modern). ([https://docs.python-telegram-bot.org]) - Node.js:
telegraf
(matang, ramah TypeScript). ([https://telegraf.js.org])
Bot API itu sendiri didokumentasikan di sini dan merupakan sumber kebenaran untuk metode seperti getUpdates
dan setWebhook
.
Quick Start: jalankan secara lokal dengan long polling
Long polling sempurna untuk pengembangan lokal: bot Anda secara berkala meminta Telegram untuk pembaruan baru melalui getUpdates
. (Di produksi, Anda kemungkinan besar akan beralih ke webhooks.)
Telegram mendukung dua cara saling eksklusif untuk menerima pembaruan:
getUpdates
(polling) atau webhooks; pembaruan disimpan hingga 24 jam.
Opsi A: Python (dengan python-telegram-bot
)
Instal & scaffold
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install python-telegram-bot
Kode: bot.py
import os
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, ContextTypes, filters
TOKEN = os.environ["TELEGRAM_BOT_TOKEN"] # export TELEGRAM_BOT_TOKEN=123:ABC
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("👋 Halo! Kirimkan sesuatu ke saya dan saya akan mengulangkannya.")
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text(update.message.text)
def main():
app = ApplicationBuilder().token(TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
app.run_polling() # long polling
if __name__ == "__main__":
main()
Jalankan:
export TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
python bot.py
Ini menggunakan ApplicationBuilder
dari dokumen stabil saat ini.
Opsi B: Node.js (dengan telegraf
)
Instal & scaffold
npm init -y
npm i telegraf
Kode: index.js
const { Telegraf } = require('telegraf');
const bot = new Telegraf(process.env.BOT_TOKEN); // set BOT_TOKEN env var
bot.start((ctx) => ctx.reply('👋 Halo! Kirimkan sesuatu ke saya dan saya akan mengulangkannya.'));
bot.on('text', (ctx) => ctx.reply(ctx.message.text));
bot.launch();
// berhenti dengan cara yang lembut
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));
Jalankan:
export BOT_TOKEN=123456:ABC-DEF...
node index.js
Ini meniru contoh “Getting started” resmi Telegraf.
Buat bot yang berguna (perintah & tombol)
Tambahkan perintah /help
Python
from telegram.ext import CommandHandler
async def help_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("/start – sapa\n/help – bantuan")
app.add_handler(CommandHandler("help", help_cmd))
CommandHandler
adalah cara standar untuk mengikat /perintah
.
Node (Telegraf)
bot.help((ctx) => ctx.reply('/start – sapa\n/help – bantuan'));
Tombol respons cepat (keyboard kustom)
Python
from telegram import ReplyKeyboardMarkup
async def start(update: Update, context):
keyboard = [["Bantuan", "Tentang"]]
await update.message.reply_text(
"Pilih opsi:",
reply_markup=ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
)
Node (Telegraf)
const { Markup } = require('telegraf');
bot.start((ctx) => {
ctx.reply("Pilih opsi:", Markup.keyboard([["Bantuan", "Tentang"]]).resize());
});
Produksi: beralih ke webhooks
Di produksi, Telegram mengirimkan pembaruan ke endpoint HTTPS Anda. Anda dapat mengatur ini dengan setWebhook
, secara opsional menyediakan token rahasia sehingga Anda dapat memverifikasi permintaan melalui header X-Telegram-Bot-Api-Secret-Token
.
Atur webhook dengan curl
:
TOKEN=123456:ABC-DEF...
WEBHOOK_URL="https://your-domain.com/telegram/${TOKEN}" # termasuk jalur rahasia
SECRET="my-secret-42"
curl -X POST "https://api.telegram.org/bot${TOKEN}/setWebhook" \
-d url="${WEBHOOK_URL}" \
-d secret_token="${SECRET}" \
-d drop_pending_updates=true
Poin penting dari spesifikasi:
setWebhook
memerlukan URL HTTPS dan mendukungsecret_token
.- Saat webhook diatur, Anda tidak dapat menggunakan
getUpdates
. - Port yang didukung termasuk 443, 80, 88, 8443.
Opsi server webhook
- Node (Telegraf) webhook bawaan:
bot.launch({
webhook: {
domain: "your-domain.com",
port: 8080,
// token rahasia opsional
secretToken: process.env.WEBHOOK_SECRET
}
});
Telegraf menampilkan opsi webhook kelas satu dan terintegrasi dengan Express/Fastify/Cloudflare Workers, dll.
- Python (
python-telegram-bot
) PTB bekerja baik dengan kerangka kerja ASGI/WSGI (FastAPI, Starlette, Flask). GunakanApplicationBuilder().token(...).build()
, ekspos rute POST yang menyediakan JSON pembaruan masuk ke aplikasi Anda, dan panggilbot.set_webhook(...)
. Lihat dokumenApplicationBuilder
untuk pola konstruksi. ([docs.python-telegram-bot.org][2])
Menguji secara lokal? Gunakan tunnel (misalnya,
ngrok
) untuk mengeksposhttps://...
ke Telegram, lalu panggilsetWebhook
dengan URL publik.
Konfigurasi perintah bot (opsional tetapi ramah pengguna)
Anda dapat mendefinisikan daftar perintah bot (apa yang pengguna lihat saat mereka mengetik /
) baik:
- Di BotFather melalui /mybots → Edit Bot → Edit Commands, atau
- Secara programmatic dengan
setMyCommands
menggunakan library Anda atau Bot API mentah.
Panduan resmi Telegram “Dari BotFather ke ‘Hello World’” mengarah ke penanganan perintah yang lebih lanjut dan contoh jika Anda ingin melangkah lebih jauh.
Pertimbangan deployment
Setiap host yang mampu HTTPS bekerja:
- VM kecil (Ubuntu + systemd)
- Serverless (AWS Lambda/Cloud Functions) dengan integrasi webhook
- Container di Fly.io/Render/platform mirip Heroku
Dokumen Telegraf mencakup contoh untuk Lambda, GCF, Express, Fastify, dll.
Daftar pemeriksaan keamanan dan keandalan
- Jaga token tetap rahasia (variabel lingkungan, manajer rahasia). Cabut di BotFather jika bocor.
- Gunakan
secret_token
dengan webhook dan verifikasi headerX-Telegram-Bot-Api-Secret-Token
. - Jangan campurkan polling dan webhook; pilih satu pada satu waktu.
- Tangani kesalahan & retry: Telegram akan mencoba ulang respons webhook non-2xx. Catat dengan tepat.
- Perhatikan jenis pembaruan (pesan, callback, inline query, pembayaran, dll.) dan langgani hanya yang Anda butuhkan (
allowed_updates
).
Bekerja langsung dengan HTTP API (opsional)
Anda dapat memanggil endpoint seperti:
https://api.telegram.org/bot<token>/getMe
https://api.telegram.org/bot<token>/getUpdates
https://api.telegram.org/bot<token>/sendMessage
Gunakan GET atau POST dengan JSON atau form data sesuai spesifikasi.
Apa yang selanjutnya harus Anda lakukan dan baca
- Referensi Bot API resmi: metode, objek, batas, format, pembayaran, mode inline.
- Panduan resmi “Dari BotFather ke ‘Hello World’”: walkthrough yang lebih dalam dan contoh multi-bahasa.
- Dokumen python-telegram-bot (stabil): pola async modern.
- Dokumen Telegraf: resep cepat, helper webhook, dan tipe TS.
Langkah deployment ke AWS untuk versi Python
Kami memiliki dua opsi utama untuk deployment bot Telegram ke infrastruktur AWS:
- A) Serverless (API Gateway + Lambda + Secrets Manager) — termurah/mudah dijalankan, cocok untuk lalu lintas sedang.
- B) Containerized (ECS Fargate + ALB + ACM) — produksi-grade untuk lalu lintas stabil dan library yang berjalan lama seperti
python-telegram-bot
dalam mode webhook.
A) Serverless di AWS (API Gateway + Lambda)
Gunakan ini ketika Anda ingin zero server dan biaya idle mendekati nol. Kode di bawah ini menangani webhook Telegram secara langsung (tidak ada event loop yang berjalan lama).
- Persiapkan handler Lambda minimal (Python)
Buat handler.py
:
import json, os, urllib.request
BOT_TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
SECRET_HEADER = os.environ.get("WEBHOOK_SECRET", "") # harus cocok dengan secret_token Bot API setWebhook
API_BASE = f"https://api.telegram.org/bot{BOT_TOKEN}"
def reply(chat_id: int, text: str):
data = json.dumps({"chat_id": chat_id, "text": text}).encode()
req = urllib.request.Request(f"{API_BASE}/sendMessage", data=data, headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req) as resp:
return resp.read()
def lambda_handler(event, context):
# 1) Verifikasi header rahasia Telegram (dihubungkan saat Anda mengatur webhook)
if SECRET_HEADER:
if event.get("headers", {}).get("X-Telegram-Bot-Api-Secret-Token") != SECRET_HEADER:
return {"statusCode": 401, "body": "secret tidak valid"}
# 2) Parse pembaruan
body = event.get("body") or "{}"
update = json.loads(body)
message = update.get("message") or update.get("edited_message")
if not message:
# abaikan pembaruan non-pesan (callback_query, inline_query, dll.) untuk saat ini
return {"statusCode": 200, "body": "ok"}
chat_id = message["chat"]["id"]
text = (message.get("text") or "").strip()
# 3) Routing sederhana
if text.startswith("/start"):
reply(chat_id, "👋 Halo dari AWS Lambda! Kirimkan teks apa pun dan saya akan mengulangkannya.")
elif text.startswith("/help"):
reply(chat_id, "/start – sapa\n/help – bantuan\n(Di deploy di AWS Lambda)")
elif text:
reply(chat_id, text) # mengulang
return {"statusCode": 200, "body": "ok"}
Ini menggunakan panggilan HTTPS mentah ke Bot API untuk menjaga Lambda tetap ringkas dan ramah cold-start. Anda dapat memperluas routing nanti.
- Paket & deploy Lambda
# Layout proyek
# .
# ├─ handler.py
# └─ requirements.txt # (biarkan kosong untuk contoh minimal ini)
zip -r function.zip handler.py
aws lambda create-function \
--function-name telegram-bot-webhook \
--runtime python3.11 \
--role arn:aws:iam::<ACCOUNT_ID>:role/<LambdaExecutionRole> \
--handler handler.lambda_handler \
--timeout 10 \
--memory-size 256 \
--zip-file fileb://function.zip \
--environment Variables='{TELEGRAM_BOT_TOKEN=<TOKEN_FROM_BOTFATHER>,WEBHOOK_SECRET=my-secret-42}'
Peran IAM (<LambdaExecutionRole>
) memerlukan AWSLambdaBasicExecutionRole
untuk CloudWatch Logs.
Lebih baik menyimpan token Anda di AWS Secrets Manager dan memuatnya saat inisialisasi—contoh ini menggunakan variabel lingkungan untuk kejelasan.
- Buat endpoint HTTPS (API Gateway)
# HTTP API (bukan REST) untuk latensi lebih rendah
API_ID=$(aws apigatewayv2 create-api \
--name telegram-webhook \
--protocol-type HTTP \
--target arn:aws:lambda:<REGION>:<ACCOUNT_ID>:function:telegram-bot-webhook \
--query 'ApiId' --output text)
# Tambahkan rute default POST /webhook
aws apigatewayv2 create-integration \
--api-id $API_ID \
--integration-type AWS_PROXY \
--integration-uri arn:aws:lambda:<REGION>:<ACCOUNT_ID>:function:telegram-bot-webhook \
--payload-format-version 2.0
aws apigatewayv2 create-route \
--api-id $API_ID \
--route-key "POST /webhook" \
--target "integrations/$(
aws apigatewayv2 get-integrations --api-id $API_ID --query 'Items[0].IntegrationId' --output text
)"
aws apigatewayv2 create-deployment --api-id $API_ID
GW_URL=$(aws apigatewayv2 get-apis --query "Items[?ApiId=='$API_ID'].ApiEndpoint" --output text)
echo $GW_URL # contoh, https://abc123.execute-api.ap-somewhere.amazonaws.com
Pastikan izin Lambda ditambahkan secara otomatis; jika tidak:
aws lambda add-permission \
--function-name telegram-bot-webhook \
--statement-id apigw \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:<REGION>:<ACCOUNT_ID>:$API_ID/*/*/webhook"
- Arahkan Telegram ke webhook Anda
TOKEN=<TOKEN_FROM_BOTFATHER>
WEBHOOK_URL="$GW_URL/webhook"
SECRET="my-secret-42"
curl -X POST "https://api.telegram.org/bot${TOKEN}/setWebhook" \
-d url="${WEBHOOK_URL}" \
-d secret_token="${SECRET}" \
-d drop_pending_updates=true
Kirim /start
ke bot Anda—pesan akan mengalir melalui API Gateway → Lambda.
- Log, retry, dan pembaruan
- Pantau log:
aws logs tail /aws/lambda/telegram-bot-webhook --follow
- Telegram akan mencoba ulang ketika endpoint Anda tidak 2xx; pertahankan respons cepat.
- Untuk mengeluarkan kode baru: re-zip +
aws lambda update-function-code --function-name telegram-bot-webhook --zip-file fileb://function.zip
.
B) Containerized python-telegram-bot
di ECS Fargate + ALB
Gunakan ini ketika Anda ingin ergonomika
python-telegram-bot
(PTB) dengan aplikasi async yang tepat dan koneksi yang bertahan lama. Kita akan menjalankan PTB di balik load balancer HTTPS.
- Kode aplikasi (FastAPI + webhook PTB)
app.py
:
import os, asyncio
from fastapi import FastAPI, Request, Header
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, ContextTypes, filters
TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
SECRET = os.environ.get("WEBHOOK_SECRET", "")
app = FastAPI()
tg_app = None # aplikasi PTB
async def start_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("🚀 Halo dari ECS Fargate + PTB!")
async def echo(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text(update.message.text)
@app.on_event("startup")
async def on_startup():
global tg_app
tg_app = ApplicationBuilder().token(TOKEN).build()
tg_app.add_handler(CommandHandler("start", start_cmd))
tg_app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
# Tidak ada run_polling(); kita akan memberi makan webhook secara manual.
@app.post("/telegram/webhook")
async def telegram_webhook(request: Request, x_telegram_bot_api_secret_token: str | None = Header(default=None)):
if SECRET and (x_telegram_bot_api_secret_token != SECRET):
return {"ok": True} # abaikan secara diam-diam
data = await request.json()
update = Update.de_json(data, tg_app.bot)
await tg_app.process_update(update)
return {"ok": True}
uvicorn
entrypoint: uvicorn app:app --host 0.0.0.0 --port 8080
- Dockerfile
FROM python:3.11-slim
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
RUN pip install --no-cache-dir fastapi uvicorn[standard] python-telegram-bot==21.*
COPY app.py .
EXPOSE 8080
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8080"]
Bangun & push:
aws ecr create-repository --repository-name telegram-ptb || true
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REGION=<REGION>
ECR="$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/telegram-ptb"
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin "$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com"
docker build -t telegram-ptb .
docker tag telegram-ptb:latest $ECR:latest
docker push $ECR:latest
- Layanan ECS Fargate di balik ALB
- Buat Security Group yang memungkinkan masuk 443 di ALB; ECS tasks memungkinkan 8080 dari ALB SG.
- Buat Application Load Balancer (ALB) dengan listener HTTPS (443) dan sertifikat ACM untuk domain Anda.
- Grup target: HTTP 8080 (jenis target IP), jalur kesehatan
/
(FastAPI menyajikan 404; Anda dapat menambahkan@app.get("/")
jalur kesehatan).
Buat Task Definition (Fargate) dengan:
- Gambar kontainer:
$ECR:latest
- Pemetaan port: 8080
- Variabel lingkungan:
TELEGRAM_BOT_TOKEN
,WEBHOOK_SECRET
- Peran tugas: peran dasar CloudWatch logging.
Buat ECS Service:
- Jenis peluncuran Fargate, jumlah diinginkan 1+.
- Hubungkan ke grup target ALB.
Catat domain HTTPS publik ALB (atau gunakan Route 53 untuk mengarahkan nama DNS Anda).
- Beri tahu Telegram URL webhook Anda
TOKEN=<TOKEN_FROM_BOTFATHER>
SECRET="my-secret-42"
WEBHOOK_URL="https://your.domain.com/telegram/webhook"
curl -X POST "https://api.telegram.org/bot${TOKEN}/setWebhook" \
-d url="${WEBHOOK_URL}" \
-d secret_token="${SECRET}" \
-d drop_pending_updates=true \
-d allowed_updates='["message","edited_message","callback_query"]'
- Skala & operasikan
- Skala tugas ECS naik/turun; ALB akan menyebar lalu lintas.
- Putar ulang token di Secrets Manager, perbarui layanan dengan lingkungan tugas baru.
- Gunakan CloudWatch Logs untuk log aplikasi dan log akses ALB (S3).
Yang mana yang harus kita pilih?
- Lambda + API Gateway: paling sederhana, termurah di volume rendah; cocok untuk bot yang melakukan beberapa panggilan per menit.
- ECS Fargate + ALB: terbaik ketika Anda ingin pengalaman penuh
python-telegram-bot
, middleware kustom, pekerjaan latar belakang, dan lalu lintas stabil.
Daftar pemeriksaan cepat (kedua pendekatan)
- Gunakan endpoint HTTPS +
secret_token
dan verifikasi headerX-Telegram-Bot-Api-Secret-Token
. - Pilih webhook ATAU polling (tidak keduanya).
- Simpan konfigurasi di Secrets Manager, bukan dalam kode.
- Tambahkan observabilitas: CloudWatch Logs + metrik (alarm 5xx).
- Tangani hanya jenis pembaruan yang Anda butuhkan; perluas nanti.
Tautan berguna
- https://docs.python-telegram-bot.org
- https://telegraf.js.org
- https://core.telegram.org/bots/tutorial
- https://core.telegram.org/bots/api
- AWS CDK Overview, TypeScript dan Python Contoh dan Pertimbangan Kinerja
- Kinerja AWS Lambda: JavaScript vs Python vs Golang
- Lambda Bertingkat dengan AWS SAM dan Python
- AWS SAM + AWS SQS + Python PowerTools
- Python Cheat Sheet
- uv - Paket Python Baru, Manajer Proyek, dan Lingkungan
- Pasang Node.js