Implementering av Telegram-bot i Python och JavaScript med distribution till AWS
Och distribuerar en ny Telegram-bot till AWS
Här är mina anteckningar med en steg-för-steg-guide på hur man implementerar och distribuerar en Telegram-bot till AWS. Jag har lagt till en snabbstart (long polling) och en produktionsklar väg (webhooks), med exempel i Python och Node.js.

Telegram-botar är appar som körs på dina servrar och kommunicerar med användare via Telegram. Vi kommer att registrera en bot, skriva ett litet program och ansluta det till Telegrams Bot API.
TL;DR
- Skapa en bot via @BotFather → få token.
- Bygg en liten app med python-telegram-bot eller Telegraf.
- Börja med long polling lokalt; byt till webhooks för produktion.
Vad du kommer att behöva
-
Ett Telegram-konto (mobil eller desktop)
-
Grundläggande terminal + kodredigerare
-
Ett av följande:
- Python 3.10+ och
pip - Node.js 18+ och
npm/pnpm/yarn
- Python 3.10+ och
Skapa din bot med BotFather (få token)
- I Telegram, söker du efter @BotFather och startar en chatt.
- Skicka
/newbotoch följ anvisningarna för att namnge din bot och välja ett unikt användarnamn (måste sluta medbot), t.ex.example_helper_bot. - BotFather svarar med en API-token som
123456:ABC-DEF.... Behandla detta som ett lösenord; lägg inte det i Git. Du kan alltid regenerera det via BotFather om det läcker ut.
Tips: Telegrams officiella guide går igenom dessa exakta steg och hur du verifierar din token med
getMe.
Välj din stack
Du kan ringa den rena HTTP Bot API själv, men att använda en underhållen bibliotek är snabbare.
- Python:
python-telegram-bot(async, modern). ([https://docs.python-telegram-bot.org]) - Node.js:
telegraf(mogen, TypeScript-vänlig). ([https://telegraf.js.org])
Bot API i sig är dokumenterad här och är källan till sanningen för metoder som getUpdates och setWebhook.
Snabbstart: kör lokalt med long polling
Long polling är perfekt för lokal utveckling: din bot frågar Telegram upprepade gånger efter nya uppdateringar via getUpdates. (I produktion kommer du troligen att byta till webhooks.)
Telegram stöder två ömsesidigt exklusiva sätt att ta emot uppdateringar:
getUpdates(polling) eller webhooks; uppdateringar sparas i upp till 24 timmar.
Alternativ A: Python (med python-telegram-bot)
Installera & skapa mall
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install python-telegram-bot
Kod: 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("👋 Hej! Skicka något till mig och jag kommer att echo det.")
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()
Kör det:
export TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
python bot.py
Det här använder ApplicationBuilder från de aktuella stabila dokumenten.
Alternativ B: Node.js (med telegraf)
Installera & skapa mall
npm init -y
npm i telegraf
Kod: index.js
const { Telegraf } = require('telegraf');
const bot = new Telegraf(process.env.BOT_TOKEN); // sätt BOT_TOKEN miljövariabel
bot.start((ctx) => ctx.reply('👋 Hej! Skicka något till mig och jag kommer att echo det.'));
bot.on('text', (ctx) => ctx.reply(ctx.message.text));
bot.launch();
// smidig stopp
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));
Kör det:
export BOT_TOKEN=123456:ABC-DEF...
node index.js
Det här speglar det officiella Telegraf-exemplet “Getting started”.
Gör det användbart (kommandon & knappar)
Lägg till ett /help-kommando
Python
from telegram.ext import CommandHandler
async def help_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("/start – hälsa\n/help – denna hjälp")
app.add_handler(CommandHandler("help", help_cmd))
CommandHandler är det standard sättet att binda /kommandon.
Node (Telegraf)
bot.help((ctx) => ctx.reply('/start – hälsa\n/help – denna hjälp'));
Snabba svarknappar (anpassat tangentbord)
Python
from telegram import ReplyKeyboardMarkup
async def start(update: Update, context):
keyboard = [["Hjälp", "Om"]]
await update.message.reply_text(
"Välj ett alternativ:",
reply_markup=ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
)
Node (Telegraf)
const { Markup } = require('telegraf');
bot.start((ctx) => {
ctx.reply("Välj ett alternativ:", Markup.keyboard([["Hjälp", "Om"]]).resize());
});
Produktion: byt till webhooks
I produktion skickar Telegram uppdateringar till din HTTPS-ändpunkt. Du kan ställa in detta med setWebhook, valfritt genom att ange en hemlig token så att du kan verifiera begäran via X-Telegram-Bot-Api-Secret-Token-rubriken.
Ställ in en webhook med curl:
TOKEN=123456:ABC-DEF...
WEBHOOK_URL="https://din-domän.com/telegram/${TOKEN}" # inkludera en hemlig sökväg
SECRET="min-hemlighet-42"
curl -X POST "https://api.telegram.org/bot${TOKEN}/setWebhook" \
-d url="${WEBHOOK_URL}" \
-d secret_token="${SECRET}" \
-d drop_pending_updates=true
Viktiga punkter från specifikationen:
setWebhookkräver en HTTPS-URL och stödersecret_token.- Medan en webhook är inställd kan du inte använda
getUpdates. - Stödda portar inkluderar 443, 80, 88, 8443.
Webhook-serveralternativ
- Node (Telegraf) inbyggd webhook:
bot.launch({
webhook: {
domain: "din-domän.com",
port: 8080,
// valfri hemlig rubrik
secretToken: process.env.WEBHOOK_SECRET
}
});
Telegraf exponerar förstaklassiga webhook-alternativ och integrerar med Express/Fastify/Cloudflare Workers etc.
- Python (
python-telegram-bot) PTB fungerar bra med ASGI/WSGI-ramverk (FastAPI, Starlette, Flask). AnvändApplicationBuilder().token(...).build(), exponera en POST-rutt som matar inkommande JSON-uppdateringar i din applikation och ringbot.set_webhook(...). SeApplicationBuilder-dokumentationen för konstruktionsmönster. ([docs.python-telegram-bot.org][2])
Testar du lokalt? Använd en tunnel (t.ex.
ngrok) för att exponerahttps://...för Telegram, sedan ringsetWebhookmed den offentliga URL:en.
Konfigurera botkommandon (valfritt men användarvänligt)
Du kan definiera listan över botkommandon (vad användare ser när de skriver /) antingen:
- I BotFather via /mybots → Redigera bot → Redigera kommandon, eller
- Programmatiskt med
setMyCommandsmed ditt bibliotek eller ren Bot API.
Telegrams officiella guide “From BotFather to Hello World” länkar till mer avancerad hantering av kommandon och exempel om du vill gå djupare.
Distributionsöverväganden
Något HTTPS-kompatibelt värd fungerar:
- En liten VM (Ubuntu + systemd)
- Serverless (AWS Lambda/Cloud Functions) med webhook-integration
- Containrar på Fly.io/Render/Heroku-liknande plattformar
Telegrafs dokumentation innehåller exempel för Lambda, GCF, Express, Fastify etc.
Säkerhets- och pålitlighetschecklista
- Håll token hemlig (miljövariabler, hemlighetshanterare). Återkalla i BotFather om den läcker ut.
- Använd
secret_tokenmed webhooks och verifieraX-Telegram-Bot-Api-Secret-Token-rubriken. - Blanda inte polling och webhooks; välj en åt gången.
- Hantera fel & återförsök: Telegram kommer att återförsöka icke-2xx webhook-svar. Logga lämpligt.
- Var medveten om uppdateringstyper (meddelanden, återkopplingar, inline-förfrågningar, betalningar etc.) och prenumerera endast på vad du behöver (
allowed_updates).
Arbeta direkt med HTTP API:et (valfritt)
Du kan ringa ändpunkter som:
https://api.telegram.org/bot<token>/getMe
https://api.telegram.org/bot<token>/getUpdates
https://api.telegram.org/bot<token>/sendMessage
Använd GET eller POST med JSON eller formdata enligt specifikationen.
Vad du ska göra och läsa näst
- Officiell Bot API-referens: metoder, objekt, gränser, formatering, betalningar, inline-läge.
- Officiell guide “From BotFather to ‘Hello World’”: djupare genomgång och flerspråkiga exempel.
- python-telegram-bot-dokumentation (stabil): moderna async-mönster.
- Telegraf-dokumentation: snabba recept, webhook-hjälpmedel och TS-typer.
AWS-distributionssteg för Python-versionen
Vi har två huvudalternativ för distribution av Telegram-botten till AWS-infrastruktur:
- A) Serverless (API Gateway + Lambda + Secrets Manager) — billigast/enklast att köra, bra för måttlig trafik.
- B) Containeriserad (ECS Fargate + ALB + ACM) — produktionsklass för stabil trafik och långlivade bibliotek som
python-telegram-boti webhook-läge.
A) Serverless på AWS (API Gateway + Lambda)
Använd detta när du vill ha noll servrar och nästan noll kostnad i viloläge. Koden nedan hanterar Telegram-webhooks direkt (ingen långlivad event-loop).
- Förbered en minimal Lambda-handler (Python)
Skapa handler.py:
import json, os, urllib.request
BOT_TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
SECRET_HEADER = os.environ.get("WEBHOOK_SECRET", "") # måste matcha Bot API setWebhook secret_token
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) Verifiera Telegram's hemliga header (inställd när du konfigurerar webhook)
if SECRET_HEADER:
if event.get("headers", {}).get("X-Telegram-Bot-Api-Secret-Token") != SECRET_HEADER:
return {"statusCode": 401, "body": "invalid secret"}
# 2) Parsa uppdatering
body = event.get("body") or "{}"
update = json.loads(body)
message = update.get("message") or update.get("edited_message")
if not message:
# ignorera icke-meddelandeuppdateringar (callback_query, inline_query, etc.) för tillfället
return {"statusCode": 200, "body": "ok"}
chat_id = message["chat"]["id"]
text = (message.get("text") or "").strip()
# 3) Enkel vägledning
if text.startswith("/start"):
reply(chat_id, "👋 Hej från AWS Lambda! Skicka vilken text som helst och jag kommer att echoa den.")
elif text.startswith("/help"):
reply(chat_id, "/start – hälsa\n/help – hjälp\n(Distribuerad på AWS Lambda)")
elif text:
reply(chat_id, text) # echo
return {"statusCode": 200, "body": "ok"}
Detta använder rå HTTPS-anrop till Bot API för att hålla Lambda lätt och kylstart-vänlig. Du kan expandera vägledningen senare.
- Paketera & distribuera Lambda
# Projektlayout
# .
# ├─ handler.py
# └─ requirements.txt # (lämna tomt för detta minimala exempel)
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}'
IAM-roll (<LambdaExecutionRole>) behöver AWSLambdaBasicExecutionRole för CloudWatch Logs.
Föredrar att lagra din token i AWS Secrets Manager och ladda den vid initiering—detta exempel använder miljövariabler för enkelhetens skull.
- Skapa ett HTTPS-ändpunkt (API Gateway)
# HTTP API (inte REST) för lägre latens
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)
# Lägg till en standardväg 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 # t.ex., https://abc123.execute-api.ap-somewhere.amazonaws.com
Se till att Lambda-behörighet läggs till automatiskt; om inte:
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"
- Peka Telegram till din webhook
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
Skicka /start till din bot—meddelanden kommer att flöda genom API Gateway → Lambda.
- Loggar, återförsök och uppdateringar
- Titta på loggar:
aws logs tail /aws/lambda/telegram-bot-webhook --follow - Telegram gör återförsök när din ändpunkt inte är 2xx; håll svaren snabba.
- För att distribuera ny kod: repaketera +
aws lambda update-function-code --function-name telegram-bot-webhook --zip-file fileb://function.zip.
B) Containeriserad python-telegram-bot på ECS Fargate + ALB
Använd detta när du vill ha ergonomin av
python-telegram-bot(PTB) med en ordentlig async-app och permanenta anslutningar. Vi kommer att köra PTB bakom en HTTPS-lastbalanserare.
- App-kod (FastAPI + PTB webhook)
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 # PTB-application
async def start_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("🚀 Hej från 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))
# Ingen run_polling(); vi kommer att mata webhooks manuellt.
@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} # ignorera tyst
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"]
Bygg & skicka:
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
- ECS Fargate-tjänst bakom en ALB
- Skapa en Säkerhetsgrupp som tillåter inkommande 443 på ALB; ECS-uppgifter tillåter 8080 från ALB SG.
- Skapa en Application Load Balancer (ALB) med en HTTPS-lyssnare (443) och ett ACM-certifikat för ditt domännamn.
- Målgrupp: HTTP 8080 (IP-måltyp), hälsokontrollsväg
/(FastAPI serverar 404; du kan lägga till@app.get("/")hälsoruta).
Skapa en Uppgiftsdefinition (Fargate) med:
- Containerbild:
$ECR:latest - Portmappning: 8080
- Miljövariabler:
TELEGRAM_BOT_TOKEN,WEBHOOK_SECRET - Uppgiftroll: grundläggande CloudWatch-loggning.
Skapa en ECS-tjänst:
- Starttyp Fargate, önskat antal 1+.
- Koppla till ALB-målgruppen.
Anteckna den offentliga HTTPS-domänen för ALB (eller använd Route 53 för att peka ditt DNS-namn).
- Berätta för Telegram din webhook-URL
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 och drifta
- Skala ECS-uppgifter upp/ner; ALB kommer att fördela trafik.
- Rotera tokens i Secrets Manager, uppdatera tjänst med ny uppgiftmiljö.
- Använd CloudWatch Logs för apploggning och ALB access logs (S3).
Vilken ska vi välja?
- Lambda + API Gateway: enklast, billigast vid låg volym; bra för botar som gör några anrop per minut.
- ECS Fargate + ALB: bäst när du vill ha hela
python-telegram-bot-upplevelsen, anpassade mellanhänder, bakgrundsjobb och stabil trafik.
Snabbchecklista (båda tillvägagångssätten)
- Använd HTTPS-ändpunkt +
secret_tokenoch verifieraX-Telegram-Bot-Api-Secret-Token-headern. - Välj webhook ELLER polling (inte båda).
- Lagra konfiguration i Secrets Manager, inte i koden.
- Lägg till observabilitet: CloudWatch Logs + mätvärden (5xx-alarm).
- Hantera endast de uppdateringstyperna du behöver; expandera senare.
Användbara länkar
- https://docs.python-telegram-bot.org
- https://telegraf.js.org
- https://core.telegram.org/bots/tutorial
- https://core.telegram.org/bots/api
- AWS CDK Översikt, TypeScript och Python Exempel och Prestanda Överväganden
- AWS lambda prestanda: JavaScript vs Python vs Golang
- Lagerade Lambdas med AWS SAM och Python
- AWS SAM + AWS SQS + Python PowerTools
- Python Cheatsheet
- uv - Ny Python Paket, Projekt och Miljöhanterare
- Installera Node.js