Implementierung eines Telegram-Bots in Python und JavaScript mit Bereitstellung auf AWS

Und Bereitstellung eines neuen Telegram-Bots auf AWS

Inhaltsverzeichnis

Hier sind meine Notizen mit einer Schritt-für-Schritt-Anleitung zur Implementierung und Bereitstellung eines Telegram-Bots auf AWS.

Ich habe einen schnellen Einstieg (Long Polling) und einen produktionsbereiten Weg (Webhooks) mit Beispielen in Python und Node.js hinzugefügt.

Roboter arbeiten in der IT

Telegram-Bots sind Anwendungen, die auf Ihren Servern laufen und mit Benutzern über Telegram kommunizieren. Wir werden einen Bot registrieren, ein kleines Programm schreiben und ihn mit der Telegram-Bot-API verbinden.

TL;DR

  1. Erstellen Sie einen Bot über @BotFather → erhalten Sie einen Token.
  2. Bauen Sie eine kleine Anwendung mit python-telegram-bot oder Telegraf.
  3. Beginnen Sie mit Long Polling lokal; wechseln Sie für die Produktion zu Webhooks.

Was Sie benötigen

  • Ein Telegram-Konto (mobil oder Desktop)

  • Grundlegendes Terminal + Code-Editor

  • Eines davon:

    • Python 3.10+ und pip
    • Node.js 18+ und npm/pnpm/yarn

Erstellen Sie Ihren Bot mit BotFather (Token erhalten)

  1. In Telegram nach @BotFather suchen und einen Chat starten.
  2. Senden Sie /newbot und folgen Sie den Anweisungen, um Ihren Bot zu benennen und einen eindeutigen Benutzernamen (muss mit bot enden) zu wählen, z. B. example_helper_bot.
  3. BotFather antwortet mit einem API-Token wie 123456:ABC-DEF.... Behandeln Sie dies wie ein Passwort; geben Sie es nicht in Git ein. Sie können es jederzeit über BotFather neu generieren, falls es geleakt wird.

Tipp: Der offizielle Telegram-Leitfaden führt Sie durch diese genauen Schritte und zeigt, wie Sie Ihren Token mit getMe überprüfen.


Wählen Sie Ihren Stack

Sie können die rohe HTTP Bot API selbst aufrufen, aber die Verwendung einer gepflegten Bibliothek ist schneller.

  • Python: python-telegram-bot (asynchron, modern). ([https://docs.python-telegram-bot.org])
  • Node.js: telegraf (ausgereift, TypeScript-freundlich). ([https://telegraf.js.org])

Die Bot-API selbst ist hier dokumentiert und ist die Quelle der Wahrheit für Methoden wie getUpdates und setWebhook.


Schnellstart: lokal mit Long Polling ausführen

Long Polling ist perfekt für die lokale Entwicklung: Ihr Bot fragt Telegram wiederholt nach neuen Updates über getUpdates ab. (In der Produktion werden Sie wahrscheinlich zu Webhooks wechseln.)

Telegram unterstützt zwei sich gegenseitig ausschließende Möglichkeiten, Updates zu erhalten: getUpdates (Polling) oder Webhooks; Updates werden bis zu 24 Stunden gespeichert.

Option A: Python (mit python-telegram-bot)

Installieren & Gerüst erstellen

python -m venv .venv && source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install python-telegram-bot

Code: 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("👋 Hallo! Senden Sie mir etwas und ich werde es zurückgeben.")

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()

Führen Sie es aus:

export TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
python bot.py

Dies verwendet ApplicationBuilder aus den aktuellen stabilen Dokumentationen.

Option B: Node.js (mit telegraf)

Installieren & Gerüst erstellen

npm init -y
npm i telegraf

Code: index.js

const { Telegraf } = require('telegraf');

const bot = new Telegraf(process.env.BOT_TOKEN); // BOT_TOKEN-Umgebungsvariable setzen
bot.start((ctx) => ctx.reply('👋 Hallo! Senden Sie mir etwas und ich werde es zurückgeben.'));
bot.on('text', (ctx) => ctx.reply(ctx.message.text));

bot.launch();

// Anmutiges Beenden
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));

Führen Sie es aus:

export BOT_TOKEN=123456:ABC-DEF...
node index.js

Dies spiegelt das offizielle Telegraf-Beispiel „Getting started“ wider.


Machen Sie es nützlich (Befehle & Schaltflächen)

Fügen Sie einen /help-Befehl hinzu

Python

from telegram.ext import CommandHandler

async def help_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("/start – Begrüßung\n/help – diese Hilfe")

app.add_handler(CommandHandler("help", help_cmd))

CommandHandler ist die Standardmethode, um /commands zu binden.

Node (Telegraf)

bot.help((ctx) => ctx.reply('/start – Begrüßung\n/help – diese Hilfe'));

Schnelle Antwortschaltflächen (benutzerdefinierte Tastatur)

Python

from telegram import ReplyKeyboardMarkup

async def start(update: Update, context):
    keyboard = [["Hilfe", "Über"]]
    await update.message.reply_text(
        "Wählen Sie eine Option:",
        reply_markup=ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
    )

Node (Telegraf)

const { Markup } = require('telegraf');
bot.start((ctx) => {
  ctx.reply("Wählen Sie eine Option:", Markup.keyboard([["Hilfe", "Über"]]).resize());
});

Produktion: Wechsel zu Webhooks

In der Produktion schiebt Telegram Updates an Ihre HTTPS-Endpunkt. Sie können dies mit setWebhook einrichten und optional einen geheimen Token bereitstellen, damit Sie die Anfrage über den Header X-Telegram-Bot-Api-Secret-Token überprüfen können.

Setzen Sie einen Webhook mit curl:

TOKEN=123456:ABC-DEF...
WEBHOOK_URL="https://your-domain.com/telegram/${TOKEN}"  # einen geheimen Pfad einbeziehen
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

Wichtige Punkte aus der Spezifikation:

  • setWebhook erfordert eine HTTPS-URL und unterstützt secret_token.
  • Während ein Webhook gesetzt ist, können Sie nicht getUpdates verwenden.
  • Unterstützte Ports sind 443, 80, 88, 8443.

Webhook-Server-Optionen

  • Node (Telegraf) eingebauter Webhook:
bot.launch({
  webhook: {
    domain: "your-domain.com",
    port: 8080,
    // optionaler geheimer Header
    secretToken: process.env.WEBHOOK_SECRET
  }
});

Telegraf bietet erstklassige Webhook-Optionen und integriert sich in Express/Fastify/Cloudflare Workers usw.

  • Python (python-telegram-bot) PTB funktioniert gut mit ASGI/WSGI-Frameworks (FastAPI, Starlette, Flask). Verwenden Sie ApplicationBuilder().token(...).build(), stellen Sie eine POST-Route bereit, die eingehende JSON-Updates in Ihre Anwendung einspeist, und rufen Sie bot.set_webhook(...) auf. Siehe die ApplicationBuilder-Dokumentation für Konstruktionsmuster. ([docs.python-telegram-bot.org][2])

Testen Sie lokal? Verwenden Sie einen Tunnel (z. B. ngrok), um https://... für Telegram freizugeben, und rufen Sie setWebhook mit der öffentlichen URL auf.


Konfigurieren Sie Bot-Befehle (optional, aber benutzerfreundlich)

Sie können die Liste der Bot-Befehle (was Benutzer sehen, wenn sie / eingeben) entweder:

  • In BotFather über /mybots → Bearbeiten Sie den Bot → Bearbeiten Sie Befehle, oder
  • Programmatisch mit setMyCommands unter Verwendung Ihrer Bibliothek oder der rohen Bot-API.

Der offizielle Leitfaden „From BotFather to Hello World“ von Telegram verlinkt zu fortgeschritteneren Befehlshandhabungen und Beispielen, falls Sie tiefer einsteigen möchten.


Bereitstellungsüberlegungen

Jeder HTTPS-fähige Host funktioniert:

  • Eine kleine VM (Ubuntu + systemd)
  • Serverless (AWS Lambda/Cloud Functions) mit Webhook-Integration
  • Container auf Fly.io/Render/Heroku-ähnlichen Plattformen

Die Telegraf-Dokumentation enthält Beispiele für Lambda, GCF, Express, Fastify usw.


Sicherheits- und Zuverlässigkeits-Checkliste

  • Behalten Sie den Token geheim (Umgebungsvariablen, Geheimnisverwaltung). Widerrufen Sie ihn in BotFather, falls er geleakt wurde.
  • Verwenden Sie secret_token mit Webhooks und überprüfen Sie den Header X-Telegram-Bot-Api-Secret-Token.
  • Mischen Sie nicht Polling und Webhooks; wählen Sie eines zur Zeit.
  • Behandeln Sie Fehler & Wiederholungen: Telegram wird nicht-2xx-Webhook-Antworten erneut versuchen. Loggen Sie entsprechend.
  • Seien Sie sich der Update-Typen (Nachrichten, Rückrufe, Inline-Abfragen, Zahlungen usw.) bewusst und abonnieren Sie nur, was Sie benötigen (allowed_updates).

Arbeiten Sie direkt mit der HTTP-API (optional)

Sie können Endpunkte wie folgt aufrufen:

https://api.telegram.org/bot<token>/getMe
https://api.telegram.org/bot<token>/getUpdates
https://api.telegram.org/bot<token>/sendMessage

Verwenden Sie GET oder POST mit JSON oder Formulardaten gemäß der Spezifikation.


Was Sie als Nächstes tun und lesen sollten

  • Offizielle Bot-API-Referenz: Methoden, Objekte, Limits, Formatierung, Zahlungen, Inline-Modus.
  • Offizieller Leitfaden „From BotFather to ‘Hello World’“: Tiefgehende Anleitung und Beispiele in mehreren Sprachen.
  • python-telegram-bot-Dokumentation (stabil): Moderne asynchrone Muster.
  • Telegraf-Dokumentation: Schnelle Rezepte, Webhook-Helfer und TS-Typen.

AWS-Deploymentschritte für die Python-Version

Wir haben zwei Hauptoptionen für die Bereitstellung des Telegram-Bots auf der AWS-Infrastruktur:

  • A) Serverless (API Gateway + Lambda + Secrets Manager) — günstigste/einfachste Ausführung, ideal für moderaten Verkehr.
  • B) Containerisiert (ECS Fargate + ALB + ACM) — Produktionsreif für stetigen Verkehr und langlaufende Bibliotheken wie python-telegram-bot im Webhook-Modus.

A) Serverless auf AWS (API Gateway + Lambda)

Verwenden Sie dies, wenn Sie keine Server und nahezu keine Leerlaufkosten möchten. Der folgende Code verarbeitet Telegram-Webhooks direkt (kein langlaufender Ereignisloop).

  1. Erstellen Sie einen minimalen Lambda-Handler (Python)

Erstellen Sie handler.py:

import json, os, urllib.request

BOT_TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
SECRET_HEADER = os.environ.get("WEBHOOK_SECRET", "")  # muss mit dem Bot API setWebhook secret_token übereinstimmen

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) Überprüfen Sie den geheimen Header von Telegram (wird bei der Webhook-Konfiguration festgelegt)
    if SECRET_HEADER:
        if event.get("headers", {}).get("X-Telegram-Bot-Api-Secret-Token") != SECRET_HEADER:
            return {"statusCode": 401, "body": "ungültiges Geheimnis"}

    # 2) Aktualisierung parsen
    body = event.get("body") or "{}"
    update = json.loads(body)

    message = update.get("message") or update.get("edited_message")
    if not message:
        # Ignorieren Sie nicht-Nachrichtenaktualisierungen (callback_query, inline_query, usw.) vorerst
        return {"statusCode": 200, "body": "ok"}

    chat_id = message["chat"]["id"]
    text = (message.get("text") or "").strip()

    # 3) Einfache Routing
    if text.startswith("/start"):
        reply(chat_id, "👋 Hallo von AWS Lambda! Senden Sie beliebigen Text und ich werde ihn zurückgeben.")
    elif text.startswith("/help"):
        reply(chat_id, "/start – Begrüßung\n/help – Hilfe\n(Bereitgestellt auf AWS Lambda)")
    elif text:
        reply(chat_id, text)  # Echo

    return {"statusCode": 200, "body": "ok"}

Dies verwendet rohe HTTPS-Aufrufe an die Bot-API, um Lambda schlank und kaltstartfreundlich zu halten. Sie können die Routing-Funktionen später erweitern.

  1. Paketieren und Bereitstellen der Lambda
# Projektlayout
# .
# ├─ handler.py
# └─ requirements.txt   # (leer für dieses minimale Beispiel lassen)

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-Rolle (<LambdaExecutionRole>) benötigt AWSLambdaBasicExecutionRole für CloudWatch-Logs.

Bevorzugen Sie die Speicherung Ihres Tokens im AWS Secrets Manager und Laden Sie es beim Start—dieses Beispiel verwendet Umgebungsvariablen zur Kürze.

  1. Erstellen Sie ein HTTPS-Endpoint (API Gateway)
# HTTP-API (nicht REST) für geringere Latenz
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)

# Fügen Sie eine Standardroute POST /webhook hinzu
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  # z.B., https://abc123.execute-api.ap-somewhere.amazonaws.com

Stellen Sie sicher, dass Lambda-Berechtigung automatisch hinzugefügt wird; wenn nicht:

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"
  1. Richten Sie den Telegram-Webhook ein
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

Senden Sie /start an Ihren Bot—Nachrichten werden durch API Gateway → Lambda weitergeleitet.

  1. Protokolle, Wiederholungen und Updates
  • Protokolle anzeigen: aws logs tail /aws/lambda/telegram-bot-webhook --follow
  • Telegram wiederholt, wenn Ihr Endpunkt nicht 2xx ist; halten Sie die Antworten schnell.
  • Um neuen Code bereitzustellen: neu verpacken + aws lambda update-function-code --function-name telegram-bot-webhook --zip-file fileb://function.zip.

B) Containerisierte python-telegram-bot auf ECS Fargate + ALB

Verwenden Sie dies, wenn Sie die Ergonomie von python-telegram-bot (PTB) mit einer ordnungsgemäßen asynchronen Anwendung und dauerhaften Verbindungen wünschen. Wir werden PTB hinter einem HTTPS-Load Balancer ausführen.

  1. App-Code (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-Anwendung

async def start_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("🚀 Hallo von 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))
    # Kein run_polling(); wir werden Webhooks manuell einspeisen.

@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}  # ignorieren Sie leise

    data = await request.json()
    update = Update.de_json(data, tg_app.bot)
    await tg_app.process_update(update)
    return {"ok": True}

uvicorn Einstiegspunkt: uvicorn app:app --host 0.0.0.0 --port 8080

  1. 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"]

Builden & Pushen:

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
  1. ECS Fargate-Dienst hinter einem ALB
  • Erstellen Sie eine Sicherheitsgruppe, die eingehenden 443 auf dem ALB zulässt; ECS-Aufgaben erlauben 8080 von der ALB-SG.
  • Erstellen Sie einen Application Load Balancer (ALB) mit einem HTTPS-Listener (443) und einem ACM-Zertifikat für Ihre Domain.
  • Zielgruppe: HTTP 8080 (IP-Zieltyp), Health-Check-Pfad / (FastAPI dient 404; Sie können eine @app.get("/") Health-Route hinzufügen).

Erstellen Sie eine Task Definition (Fargate) mit:

  • Container-Image: $ECR:latest
  • Port-Zuordnung: 8080
  • Umgebungsvariablen: TELEGRAM_BOT_TOKEN, WEBHOOK_SECRET
  • Task-Rolle: grundlegende CloudWatch-Protokollierung.

Erstellen Sie einen ECS-Dienst:

  • Starttyp Fargate, gewünschte Anzahl 1+.
  • An die ALB-Zielgruppe anhängen.

Merken Sie sich die öffentliche HTTPS-Domain des ALB (oder verwenden Sie Route 53, um Ihren DNS-Namen zu verweisen).

  1. Teilen Sie Telegram Ihre Webhook-URL mit
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"]'
  1. Skalieren & Betreiben
  • Skalieren Sie ECS-Aufgaben hoch/runter; ALB wird den Verkehr verteilen.
  • Drehen Sie Token in Secrets Manager um, aktualisieren Sie den Dienst mit neuen Task-Umgebungsvariablen.
  • Verwenden Sie CloudWatch-Logs für App-Protokolle und ALB-Zugriffsprotokolle (S3).

Welche sollten wir wählen?

  • Lambda + API Gateway: einfachste, günstigste Lösung bei niedrigem Volumen; ideal für Bots, die nur wenige Aufrufe pro Minute tätigen.
  • ECS Fargate + ALB: ideal, wenn Sie das volle python-telegram-bot-Erlebnis, benutzerdefinierte Middlewares, Hintergrundjobs und stetigen Verkehr wünschen.

Kurze Checkliste (beide Ansätze)

  • Verwenden Sie ein HTTPS-Endpoint + secret_token und überprüfen Sie den X-Telegram-Bot-Api-Secret-Token-Header.
  • Wählen Sie Webhook ODER Polling (nicht beides).
  • Speichern Sie die Konfiguration in Secrets Manager, nicht im Code.
  • Fügen Sie Observabilität hinzu: CloudWatch-Logs + Metriken (5xx-Alarme).
  • Verarbeiten Sie nur die Aktualisierungstypen, die Sie benötigen; erweitern Sie später.