تطبيق روبوت تليجرام باستخدام بايثون وجاوا سكربت مع نشره على AWS

وإطلاق روبوت تيليجرام الجديد على AWS

Page content

هنا ملاحظاتي مع دليل تدريبي خطوة بخطوة حول كيفية تطبيق ونشر على AWS روبوت تيليجرام. لقد أضفت بدءًا سريعًا (الاستجواب الطويل) ومسارًا جاهزًا للإنتاج (الويب هوك)، مع أمثلة في بايثون ونود. جس.

روبوتات تعمل في مجال التكنولوجيا المعلومات

الروبوتات في تيليجرام هي تطبيقات تعمل على خوادمك وتحدث مع المستخدمين عبر تيليجرام. سنتسجيل روبوت، ونكتب برنامجًا صغيرًا، ونربطه بواجهة برمجة تطبيقات تيليجرام (Bot API).

TL;DR

  1. إنشاء روبوت عبر @BotFather → الحصول على الرمز.
  2. بناء تطبيق صغير باستخدام python-telegram-bot أو Telegraf.
  3. البدء بـ الاستجواب الطويل محليًا؛ التبديل إلى الويب هوك للإنتاج.

ما ستحتاجه

  • حساب تيليجرام (جوال أو سطح مكتب)

  • شاشة معدة + محرر كود

  • واحد من:

    • بايثون 3.10+ و pip
    • نود. جس 18+ و npm/pnpm/yarn

إنشاء روبوتك مع BotFather (الحصول على الرمز)

  1. في تيليجرام، ابحث عن @BotFather وابدأ محادثة.
  2. أرسل /newbot واتبع الإرشادات لتسمية روبوتك واختيار اسم مستخدم فريد (يجب أن ينتهي بـ bot)، مثال: example_helper_bot.
  3. BotFather يرد برمز API مثل 123456:ABC-DEF.... عامل هذا ككلمة مرور؛ لا تضيفه إلى Git. يمكنك دائمًا إعادة إنشاءه عبر BotFather إذا تسرب.

نصيحة: يوضح الدليل الرسمي لتيليجرام هذه الخطوات بالضبط وكيفية التحقق من رمزك باستخدام getMe.


اختر مجموعتك

يمكنك استدعاء Bot API HTTP الخام بنفسك، لكن استخدام مكتبة مُحافظة هو أسرع.

  • بايثون: python-telegram-bot (غير متزامن، حديث). ([https://docs.python-telegram-bot.org])
  • نود. جس: telegraf (مُنضج، ودود مع TypeScript). ([https://telegraf.js.org])

Bot API نفسه موثق هنا وهو المصدر الوحيد للحقيقة لطرق مثل getUpdates و setWebhook.


بدء سريع: تشغيل محليًا مع الاستجواب الطويل

الاستجواب الطويل مثالي للتطوير المحلي: يسأل روبوتك تيليجرام باستمرار عن التحديثات الجديدة عبر getUpdates. (في الإنتاج، من المحتمل أن تتحول إلى الويب هوك.)

يدعم تيليجرام طريقة اثنين متقابلة حصرية لاستقبال التحديثات: getUpdates (الاستجواب) أو الويب هوك؛ يتم الاحتفاظ بالتحديثات لمدة تصل إلى 24 ساعة.

خيار أ: بايثون (مع python-telegram-bot)

التركيب والهيكلية

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

الكود: 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("👋 مرحبًا! أرسل لي شيئًا وأنا سأكرره.")

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()  # الاستجواب الطويل

if __name__ == "__main__":
    main()

تشغيله:

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

هذا يستخدم ApplicationBuilder من الوثائق الحالية المستقرة.

خيار ب: نود. جس (مع telegraf)

التركيب والهيكلية

npm init -y
npm i telegraf

الكود: index.js

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

const bot = new Telegraf(process.env.BOT_TOKEN); // تعيين متغير BOT_TOKEN
bot.start((ctx) => ctx.reply('👋 مرحبًا! أرسل لي شيئًا وأنا سأكرره.'));
bot.on('text', (ctx) => ctx.reply(ctx.message.text));

bot.launch();

// إيقاف ناعم
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));

تشغيله:

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

هذا يعكس مثال “البدء” الرسمي لـ Telegraf.


جعله مفيدًا (ال الأوامر والزرار)

إضافة أمر /help

بايثون

from telegram.ext import CommandHandler

async def help_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("/start – ترحيب\n/help – هذا المساعدة")

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

CommandHandler هو الطريقة القياسية لربط الأوامر.

نود (Telegraf)

bot.help((ctx) => ctx.reply('/start – ترحيب\n/help – هذا المساعدة'));

زرار الرد السريع (لوحة مفاتيح مخصصة)

بايثون

from telegram import ReplyKeyboardMarkup

async def start(update: Update, context):
    keyboard = [["Help", "About"]]
    await update.message.reply_text(
        "اختر خيارًا:",
        reply_markup=ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
    )

نود (Telegraf)

const { Markup } = require('telegraf');
bot.start((ctx) => {
  ctx.reply("اختر خيارًا:", Markup.keyboard([["Help", "About"]]).resize());
});

الإنتاج: التبديل إلى الويب هوك

في الإنتاج، يرسل تيليجرام التحديثات إلى نقطة النهاية HTTPS الخاصة بك. يمكنك تعيين هذا باستخدام setWebhook، وتقديم رمز سري لكي تتمكن من التحقق من الطلب عبر رأس X-Telegram-Bot-Api-Secret-Token.

تعيين ويب هوك باستخدام curl:

TOKEN=123456:ABC-DEF...
WEBHOOK_URL="https://your-domain.com/telegram/${TOKEN}"  # تضمين مسار سري
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

نقاط رئيسية من المواصفات:

  • setWebhook يتطلب عنوان URL HTTPS ويدعم secret_token.
  • أثناء تعيين ويب هوك، لا يمكنك استخدام getUpdates.
  • الأرقام المدعومة تشمل 443، 80، 88، 8443.

خيارات خادم الويب هوك

  • نود (Telegraf) الويب هوك المدمج:
bot.launch({
  webhook: {
    domain: "your-domain.com",
    port: 8080,
    // رأس سري اختياري
    secretToken: process.env.WEBHOOK_SECRET
  }
});

Telegraf يعرض خيارات الويب هوك من الدرجة الأولى ويعمل مع Express/Fastify/Cloudflare Workers، إلخ.

  • بايثون (python-telegram-bot) PTB يعمل بشكل جيد مع إطارات ASGI/WSGI (FastAPI، Starlette، Flask). استخدم ApplicationBuilder().token(...).build()، عرض مسار POST يغذي التحديثات JSON الواردة إلى تطبيقك، واتصل بـ bot.set_webhook(...). راجع وثائق ApplicationBuilder للأنماط البناء. ([docs.python-telegram-bot.org][2])

هل تختبر محليًا؟ استخدم نفقًا (مثل ngrok) لعرض https://... إلى تيليجرام، ثم اتصل بـ setWebhook مع العنوان العام.


إعداد أوامر الروبوت (اختياري لكنه ودود للمستخدمين)

يمكنك تعريف قائمة الأوامر الخاصة بالروبوت (ما يراه المستخدمون عند كتابة /) إما:

  • في BotFather عبر /mybots → تعديل الروبوت → تعديل الأوامر، أو
  • بشكل برمجي مع setMyCommands باستخدام مكتبتك أو Bot API الخام.

دليل “من BotFather إلى ‘Hello World’” الرسمي يشير إلى معالجة الأوامر المتقدمة وأمثلة إضافية إذا كنت ترغب في الذهاب أعمق.


اعتبارات النشر

أي خادم قادرة على HTTPS يعمل:

  • جهاز خادم صغير (Ubuntu + systemd)
  • بدون خادم (AWS Lambda/Cloud Functions) مع دمج الويب هوك
  • حاويات على منصات مثل Fly.io/Render/Heroku

تحتوي وثائق Telegraf على أمثلة لـ Lambda، GCF، Express، Fastify، إلخ.


قائمة فحص الأمان والموثوقية

  • احتفظ بالرمز سريًا (متغيرات البيئة، مدير السر). ألغِه في BotFather إذا تسرب.
  • استخدم secret_token مع الويب هوك وتحقق من رأس X-Telegram-Bot-Api-Secret-Token.
  • لا تخلط بين الاستجواب والويب هوك؛ اختر واحدًا في كل مرة.
  • تعامل مع الأخطاء والمحاولات مرة أخرى: سيقوم تيليجرام بمحاولة استجابات الويب هوك غير 2xx. سجل بشكل مناسب.
  • كن حذرًا من أنواع التحديثات (الرسائل، الاستفسارات، الاستعلامات الداخلية، المدفوعات، إلخ) واشترك فقط في ما تحتاجه (allowed_updates).

العمل مباشرة مع واجهة برمجة تطبيقات HTTP (اختياري)

يمكنك استدعاء نقاط النهاية مثل:

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

استخدم GET أو POST مع JSON أو بيانات النموذج حسب المواصفات.


ماذا يجب عليك فعله والقراءة التالية

  • المرجع الرسمي لواجهة برمجة تطبيقات Bot: الطرق، الكائنات، الحدود، التنسيق، المدفوعات، الوضع الداخلي.
  • دليل رسمي “من BotFather إلى ‘Hello World’”: مسيرة أعمق وأمثلة متعددة اللغات.
  • وثائق python-telegram-bot (الثابتة): الأنماط الحديثة غير المتزامنة.
  • وثائق Telegraf: وصفات سريعة، مساعدين لـ الويب هوك، ونماذج TS.

خطوات النشر على AWS للنسخة الخاصة ببايثون

لدينا خياران رئيسيان للنشر على بنية تحتية AWS للروبوت التيليجرام:

  • أ) بدون خادم (API Gateway + Lambda + Secrets Manager) — أرخص وأسهل للتشغيل، مثالي لحركة المرور المعتدلة.
  • ب) مُحصَّن (ECS Fargate + ALB + ACM) — مناسب للإنتاج المستقر وحركة المرور المستمرة والibraries طويلة المدى مثل python-telegram-bot في وضع الويب هوك.

أ) بدون خادم على AWS (API Gateway + Lambda)

استخدم هذا عندما ترغب في عدم وجود خوادم وتكاليف تقريبًا صفرية. الكود أدناه يتعامل مع الويب هوك لـ Telegram مباشرة (لا يوجد حلقة حدث طويلة المدى).

  1. إعداد معالح Lambda بسيط (بايثون)

أنشئ handler.py:

import json, os, urllib.request

BOT_TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
SECRET_HEADER = os.environ.get("WEBHOOK_SECRET", "")  # يجب أن يتطابق مع 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) التحقق من رأس سر Telegram (المحدد عند تكوين الويب هوك)
    if SECRET_HEADER:
        if event.get("headers", {}).get("X-Telegram-Bot-Api-Secret-Token") != SECRET_HEADER:
            return {"statusCode": 401, "body": "secret غير صحيح"}

    # 2) تحليل التحديث
    body = event.get("body") or "{}"
    update = json.loads(body)

    message = update.get("message") or update.get("edited_message")
    if not message:
        # تجاهل التحديثات غير المرتبطة بالرسالة (استفسارات، استفسارات داخلية، إلخ) مؤقتًا
        return {"statusCode": 200, "body": "ok"}

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

    # 3) التوجيه البسيط
    if text.startswith("/start"):
        reply(chat_id, "👋 مرحبًا من AWS Lambda! أرسل أي نص وأنا سأكرره.")
    elif text.startswith("/help"):
        reply(chat_id, "/start – ترحيب\n/help – مساعدة\n(مُنشر على AWS Lambda)")
    elif text:
        reply(chat_id, text)  # كرر

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

هذا يستخدم مكالمات HTTPS الخام إلى Bot API للحفاظ على Lambda نحيفًا ووديًا لبدء البارد. يمكنك توسيع التوجيه لاحقًا.

  1. تعبئة ونشر Lambda
# ترتيب المشروع
# .
# ├─ handler.py
# └─ requirements.txt   # (اتركه فارغًا لهذا المثال البسيط)

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}'

الدور (<LambdaExecutionRole>) يحتاج إلى AWSLambdaBasicExecutionRole لـ CloudWatch Logs.

تفضل تخزين رمزك في AWS Secrets Manager وتحميله عند البدء—هذا المثال يستخدم متغيرات البيئة لبساطته.

  1. إنشاء نقطة نهاية HTTPS (API Gateway)
# HTTP API (ليس REST) لخفض التأخير
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)

# إضافة مسار افتراضي 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  # مثال: https://abc123.execute-api.ap-somewhere.amazonaws.com

تأكد من أن السماحية لـ Lambda تم إضافتها تلقائيًا؛ إذا لم تكن كذلك:

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. توجيه تيليجرام إلى ويب هوكك
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

أرسل /start إلى روبوتك—الرسائل ستتدفق عبر API Gateway → Lambda.

  1. السجلات، المحاولات، والتحديثات
  • راقب السجلات: aws logs tail /aws/lambda/telegram-bot-webhook --follow
  • يعيد تيليجرام المحاولة عندما لا يكون نقطة النهاية 2xx؛ حافظ على الاستجابات سريعة.
  • لطرح كود جديد: إعادة التعبئة + aws lambda update-function-code --function-name telegram-bot-webhook --zip-file fileb://function.zip.

ب) python-telegram-bot المُحصَّن على ECS Fargate + ALB

استخدم هذا عندما ترغب في مرونة python-telegram-bot (PTB) مع تطبيق غير متزامن واتصالات مستمرة. سنقوم بتشغيل PTB خلف موزع حمل HTTPS.

  1. الكود (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

async def start_cmd(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("🚀 مرحبًا من 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))
    # لا نقوم بتشغيل run_polling(); سنقوم بتغذية الويب هوك يدويًا.

@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}  # تجاهل بصمت

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

نقطة دخول uvicorn: 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"]

البناء والدفع:

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 خلف ALB
  • إنشاء مجموعة أمان تسمح بدخول 443 على ALB؛ ECS المهام تسمح 8080 من مجموعة أمان ALB.
  • إنشاء موزع حمل تطبيق (ALB) مع مستمع HTTPS (443) وشهادة ACM لโดمنك.
  • مجموعة الأهداف: HTTP 8080 (نوع الهدف IP)، مسار فحص الصحة / (FastAPI تقدم 404؛ يمكنك إضافة @app.get("/") مسار صحة).

إنشاء تعريف مهمة (Fargate) مع:

  • صورة الحاوية: $ECR:latest
  • خريطة المنفذ: 8080
  • المتغيرات البيئية: TELEGRAM_BOT_TOKEN، WEBHOOK_SECRET
  • دور المهمة: دور أساسي لتسجيل CloudWatch.

إنشاء خدمة ECS:

  • نوع الإطلاق Fargate، عدد المهام المطلوب 1+.
  • ربطها بمجموعة أهداف ALB.

ملاحظة عن الโดمن HTTPS العام لـ ALB (أو استخدام Route 53 لربط اسم DNS الخاص بك).

  1. أخبر تيليجرام عن عنوان 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"]'
  1. التوسع والتشغيل
  • توسعة مهام ECS لأعلى أو لأسفل؛ ALB سيوزع حركة المرور.
  • تدوير الرموز في Secrets Manager، تحديث الخدمة مع مهمة جديدة.
  • استخدام CloudWatch Logs لتسجيل التطبيق وسجلات ALB (S3).

ما يجب أن نختاره؟

  • Lambda + API Gateway: أبسط وأرخص عند حجم منخفض؛ مثالي لروبوتات تقوم ببضع مكالمات في الدقيقة.
  • ECS Fargate + ALB: الأفضل عندما ترغب في تجربة كاملة لـ python-telegram-bot، وسطwares مخصصة، مهام خلفية، وحركة مرور مستمرة.

قائمة مختصرة (كلا الطريقتين)

  • استخدم نقطة نهاية HTTPS + secret_token وتحقق من رأس X-Telegram-Bot-Api-Secret-Token.
  • اختر الويب هوك أو الاستجواب (ليس كلاهما).
  • احفظ التكوين في Secrets Manager، لا في الكود.
  • أضف مراقبة: CloudWatch Logs + مؤشرات (إنذارات 5xx).
  • تتعامل فقط مع أنواع التحديثات التي تحتاجها؛ توسع لاحقًا.

روابط مفيدة