ربات تلگرام

نصب MadelineProto روی هاست cPanel از Composer تا اجرای دائمی

برای نصب MadelineProto روی هاست cPanel به PHP 8.3 یا بالاتر، افزونه gmp و چند افزونه دیگر و راهی برای روشن نگه داشتن پروسس ربات نیاز دارید. فایل session را هم باید بیرون از public_html بگذارید، چون هر کسی آن را داشته باشد به اکانت یا ربات شما دسترسی دارد.

نوشته تیم فنی پیکوهاستبه روزرسانی: ۲۳ شهریور ۱۴۰۵۱۴ دقیقه مطالعه

MadelineProto کتابخانه ای PHP است که مستقیم با MTProto، پروتکل اپ های رسمی تلگرام، کار می کند. با آن می توانید یک اکانت کاربری را از کد کنترل کنید یا رباتی بنویسید که بدون عبور از Bot API به سرورهای تلگرام وصل شود. نصب MadelineProto روی هاست cPanel با Composer کار سختی نیست. ربات معمولا بعد از نصب زمین می خورد: session جایی مانده که از مرورگر دانلود می شود، یا پروسس بعد از مدتی بسته شده و چیزی دوباره راهش نینداخته است.

MadelineProto چیست و چه زمانی به آن نیاز دارید

MadelineProto را وقتی لازم دارید که Bot API جواب کارتان را نمی دهد، مثلا ربات باید فایل بزرگ تر از ۵۰ مگابایت آپلود کند یا کار باید با اکانت کاربری انجام شود. این کتابخانه کارهای اپ های رسمی تلگرام را از کد PHP ممکن می کند و دو حالت ورود دارد: با شماره تلفن به عنوان کاربر، یا با توکن ربات. در حالت ربات هم درخواست ها از api.telegram.org عبور نمی کنند و سقف های مخصوص Bot API، مثل آپلود ۵۰ مگابایتی، اعمال نمی شوند.

برای رباتی که فقط به دستور و دکمه جواب می دهد و فایل بزرگ جابه جا نمی کند، Bot API ساده تر است و روی هاست معمولی هم اجرا می شود. مراحلش در راه اندازی وبهوک برای ربات Bot API آمده است. سقف فایل، ریسک مسدود شدن اکانت و هاست لازم هر روش را هم در تفاوت های MadelineProto و Bot API کنار هم گذاشته ایم.

پیش نیازهای نصب MadelineProto روی هاست

MadelineProto به PHP 8.3 یا بالاتر و افزونه های mbstring، xml، json، fileinfo، gmp، openssl، iconv و gd نیاز دارد. جزئیات در صفحه نیازمندی های مستندات آمده است:

موردالزامی یا پیشنهادیکجا بررسی کنید
PHP 8.3 یا بالاتر (8.4 پیشنهاد شده)الزامیبخش انتخاب نسخه PHP در cPanel و دستور php -v
افزونه های mbstring، xml، json، fileinfo، gmp، openssl، iconv و gdالزامیبخش افزونه های PHP در cPanel و دستور php -m
افزونه های ffi و uvپیشنهادی، برای کارایی بهترهمان بخش افزونه ها
سیستم عامل لینوکس یا یونیکسپشتیبانی رسمی؛ ویندوز پیشنهاد نمی شودcPanel فقط روی لینوکس نصب می شود

بررسی نسخه PHP در cPanel و ترمینال

نسخه PHP هر دامنه را در cPanel از MultiPHP Manager عوض می کنید. روی سرورهای CloudLinux این کار معمولا در بخش Select PHP Version انجام می شود و افزونه ها هم همان جا فعال می شوند. PHP خط فرمان ممکن است نسخه دیگری باشد، پس اگر به ترمینال دسترسی دارید، آن را جدا چک کنید:

php -v
php -m | grep -Ei 'mbstring|xml|json|fileinfo|gmp|openssl|iconv|gd|ffi'

برای دیدن تنظیمات PHP وب، فایل موقتی با محتوای <?php phpinfo(); بسازید و در مرورگر باز کنید. بعد از خواندن نتیجه پاکش کنید، چون این صفحه اطلاعات سرور را به هر بازدیدکننده ای نشان می دهد.

بخش Terminal در cPanel فقط وقتی دیده می شود که حساب دسترسی shell داشته باشد و میزبان این قابلیت را فعال کرده باشد. اگر آن را نمی بینید، از پشتیبانی هاست بخواهید فعالش کند یا دسترسی SSH بدهد.

نصب با Composer، فایل phar یا madeline.php

برای رباتی که کاربر واقعی دارد، Composer را انتخاب کنید و اگر پروژه تان Composer ندارد، فایل phar را. صفحه نصب روش سومی هم دارد، madeline.php، که فقط برای آزمایش است.

نصب با Composer

Composer باید نسخه ۲ یا بالاتر باشد. در ترمینال پوشه ای بیرون از public_html بسازید و کتابخانه را آنجا نصب کنید:

mkdir -p ~/madeline-bot
cd ~/madeline-bot
composer require "danog/madelineproto:^8"

قید ^8 هر نسخه 8.x را قبول می کند، ولی نسخه اصلی بعدی را بدون اطلاع شما نصب نمی کند. در کد هم فقط vendor/autoload.php را با require_once بارگذاری می کنید.

اگر ترمینال دستور composer را نمی شناسد، یا از پشتیبانی بخواهید آن را در دسترس بگذارد، یا Composer را روی کامپیوتر خودتان با همان نسخه PHP هاست اجرا کنید و پوشه vendor را همراه composer.json و composer.lock آپلود کنید. پوشه vendor هزاران فایل کوچک دارد و آپلود یک zip و extract کردنش در File Manager سریع تر تمام می شود؛ مراحلش را در آموزش تصویری آپلود سورس در cPanel ببینید.

فایل phar

فایل madeline81.phar را از بخش Releases مخزن MadelineProto در گیت هاب دانلود کنید، کنار اسکریپت آپلود کنید و آن را include کنید:

<?php
require_once __DIR__ . '/madeline81.phar';

این فایل با پروژه ای که از قبل با Composer نصب شده سازگار نیست. اگر پروژه تان composer.json دارد، کتابخانه را با همان Composer اضافه کنید.

madeline.php برای آزمایش

روش سوم چند خط کد است که فایل madeline.php را دانلود و include می کند:

<?php
if (!file_exists('madeline.php')) {
    copy('https://phar.madelineproto.xyz/madeline.php', 'madeline.php');
}
require_once 'madeline.php';

مستندات صریحا نوشته این روش را هیچ وقت در production به کار نبرید. madeline.php نسخه های آلفا و بتا را با به روزرسانی خودکار می گیرد و تغییرات ناسازگار ممکن است بدون اطلاع شما وارد ربات شوند. برای امتحان کردن کتابخانه روی هاست مشکلی ندارد.

ساختار پوشه ها و جای فایل session

فایل session را بیرون از public_html بگذارید. MadelineProto در اولین ورود، اطلاعات ورود را در مسیری که به آن داده اید، مثلا session/bot.madeline، ذخیره می کند و هر کسی به این session دسترسی پیدا کند، بدون کد تأیید و رمز دوم وارد اکانت یا ربات شما می شود.

روی هاست cPanel ساختاری مثل این جواب می دهد:

/home/USERNAME/
├── madeline-bot/          # outside public_html, not reachable from the web
│   ├── vendor/
│   ├── composer.json
│   ├── bot.php            # event handler code
│   └── session/           # bot.madeline is created here
└── public_html/
    └── bot-x7k2q/
        └── index.php      # the only web entry point

فایل index.php داخل public_html فقط کد اصلی را صدا می زند:

<?php
require '/home/USERNAME/madeline-bot/bot.php';

پوشه session باید برای کاربر هاست قابل نوشتن باشد. اگر PHP روی هاست با کاربر خود حساب اجرا می شود، مجوز 700 کافی است و 777 را هیچ وقت برای این پوشه نگذارید. اسم پوشه ورودی وب را هم چیزی انتخاب کنید که حدس زدنش سخت باشد.

اولین ورود با api_id و کد تأیید

گرفتن api_id و api_hash

برای ورود با اکانت کاربری، api_id و api_hash لازم دارید. با اکانت تلگرام خود در my.telegram.org وارد شوید، بخش API development tools را باز کنید و فرم را پر کنید. تلگرام در حال حاضر به هر شماره فقط یک api_id می دهد. در ورود خودکار MadelineProto وارد کردن این دو مقدار اجباری نیست، ولی بهتر است api_id خودتان را بگیرید، چون api_idهایی که در کدهای متن باز منتشر شده اند محدود شده اند و ورود با آن ها به خطای API_ID_PUBLISHED_FLOOD می رسد.

تلگرام اکانت هایی را که با کلاینت های غیررسمی API وارد می شوند خودکار زیر نظر می گیرد و استفاده از API برای flooding، اسپم یا دستکاری آمار عضو و بازدید کانال به مسدود شدن دائمی می رسد. مستندات MadelineProto می گوید اکانت ممکن است بدون هیچ تخلفی هم مسدود شود و پیشنهاد می کند هنگام اولین ورود یا قبل از آن به [email protected] ایمیل بزنید، شماره را بنویسید و توضیح دهید یوزربات چه کاری انجام می دهد.

کد event handler

فایل bot.php را در پوشه madeline-bot بسازید. نمونه زیر از روی مثال مستندات نوشته شده و به دستور /ping جواب می دهد:

<?php declare(strict_types=1);

require_once __DIR__ . '/vendor/autoload.php';

use danog\MadelineProto\EventHandler\Filter\FilterCommand;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\EventHandler\Plugin\RestartPlugin;
use danog\MadelineProto\EventHandler\SimpleFilter\Incoming;
use danog\MadelineProto\Settings;
use danog\MadelineProto\Settings\AppInfo;
use danog\MadelineProto\SimpleEventHandler;

class MyEventHandler extends SimpleEventHandler
{
    // Errors are reported to this account
    public const ADMIN = "@your_username";

    public function getReportPeers()
    {
        return [self::ADMIN];
    }

    public static function getPlugins(): array
    {
        return [RestartPlugin::class];
    }

    #[FilterCommand('ping')]
    public function pingCommand(Incoming&Message $message): void
    {
        $message->reply('pong');
    }
}

$settings = new Settings;
// api_hash is a secret: keep this file outside public_html and out of public git repos
$settings->setAppInfo(
    (new AppInfo)
        ->setApiId(1234567)
        ->setApiHash('YOUR_API_HASH')
);

MyEventHandler::startAndLoop(__DIR__ . '/session/bot.madeline', $settings);

متدهایی که attributeهایی مثل #[Handler] یا #[FilterCommand] دارند، با رسیدن آپدیت مناسب اجرا می شوند. RestartPlugin دستور /restart را برای ادمین فعال می کند تا بعد از تغییر کد، ربات را از داخل تلگرام دوباره راه بیندازید. api_hash را مثل رمز عبور حساب کنید. اگر کد را در گیت نگه می دارید، مقدار واقعی را در فایلی بیرون از مخزن بگذارید و فقط آن فایل را include کنید.

ورود از ترمینال یا مرورگر

اگر session هنوز وارد نشده باشد، startAndLoop ورود را شروع می کند. در CLI سؤال ها در ترمینال پرسیده می شوند و در مرورگر صفحه ورود باز می شود. اول انتخاب می کنید که به عنوان کاربر وارد شوید یا ربات. برای کاربر، شماره تلفن، کدی که تلگرام در اپ می فرستد و اگر تأیید دومرحله ای فعال است، رمز دوم را وارد می کنید. برای ربات، توکن BotFather کافی است.

روی هاست اشتراکی از ترمینال وارد شوید. در این حالت صفحه ورود هیچ وقت روی اینترنت باز نمی ماند که کس دیگری زودتر از شما پرش کند:

cd ~/madeline-bot
php bot.php

بعد از ورود، اسکریپت منتظر آپدیت می ماند. از اکانت دیگری /ping بفرستید و اگر pong برگشت، نصب درست انجام شده است. اسکریپت را با Ctrl+C ببندید؛ session ذخیره شده و دفعه بعد ورود دوباره لازم نیست.

اجرای دائمی MadelineProto روی هاست cPanel

روی هاست cPanel ربات MadelineProto را از طریق آدرس وب اجرا کنید و یک کرون جاب بگذارید که هر چند دقیقه همان آدرس را صدا بزند. ربات فقط تا وقتی جواب می دهد که پروسس PHP آن زنده است و اجرای دائمی از خط فرمان روی هاست اشتراکی دوام نمی آورد.

اجرا از طریق وب و self-restart

وقتی event handler را با باز کردن آدرسش در مرورگر اجرا می کنید، MadelineProto خودش سازوکار self-restart را فعال می کند تا ربات روی وب هاست هایی که زمان اجرا را محدود کرده اند هم روشن بماند. این رفتار در مستندات مدیریت آپدیت ها توضیح داده شده است. قفل گذاری هم خودکار است و اگر آدرس را چند بار باز کنید، باز هم فقط یک نسخه از ربات اجرا می شود.

self-restart ممکن است با ری استارت فیزیکی سرور یا ری استارت وب سرور و php-fpm از کار بیفتد. مستندات برای این حالت اجرا از CLI یا کرون جابی را پیشنهاد می کند که آدرس ربات را مرتب صدا بزند. اگر کدی دارید که باید موقع خاموش شدن اجرا شود، به جای register_shutdown_function از Shutdown::addCallback خود MadelineProto استفاده کنید.

کرون جاب برای برگرداندن ربات

در بخش Cron Jobs در cPanel یک کرون جاب جدید بسازید. در فیلد Minute مقدار */5 و در بقیه فیلدهای زمان * بگذارید تا هر ۵ دقیقه اجرا شود، و در فیلد Command این را بنویسید:

curl -s -o /dev/null --max-time 30 https://example.com/bot-x7k2q/ >/dev/null 2>&1

وقتی ربات روشن است، قفل MadelineProto جلوی ساخته شدن نسخه دوم را می گیرد. اگر ربات خاموش شده باشد، همین درخواست دوباره راهش می اندازد. >/dev/null 2>&1 در انتهای دستور هم نمی گذارد بعد از هر اجرا ایمیل خروجی برایتان بیاید. تصویر مراحل این کار در آموزش تنظیم کرون جاب در cPanel آمده است.

اجرای CLI و محدودیت هایش روی هاست اشتراکی

برای اجرا از خط فرمان، مستندات دستور screen php bot.php را پیشنهاد می کند. برای اینکه /restart یا $this->restart() در CLI کار کند، اسکریپت باید داخل یک حلقه bash اجرا شود تا بعد از هر خروج دوباره شروع شود. راه دیگر Docker با restart: always است:

while :; do php bot.php; done

روی هاست اشتراکی این روش محدودیت دارد. طبق مستندات cPanel، بعد از خروج از پنل، نشست های Terminal پس از مدت کوتاهی بسته می شوند و دستورهای در حال اجرا هم با بسته شدن نشست تمام می شوند. screen هم ممکن است روی هاست نصب نباشد. اجرای CLI دائمی را برای سرور مجازی نگه دارید.

مصرف رم و ذخیره داده ها در MySQL

MadelineProto به طور پیش فرض داده های داخلی اش را در رم و فایل session نگه می دارد. روی سرورهای CloudLinux هر حساب سقف رم مشخصی دارد و رباتی که در چت های زیادی فعال است ممکن است به این سقف برسد. برای کم کردن مصرف رم، مستندات ذخیره این داده ها در MySQL، Postgres یا Redis را پیشنهاد می کند. در cPanel یک دیتابیس MySQL و یک کاربر بسازید و آن را به تنظیمات bot.php اضافه کنید:

use danog\MadelineProto\Settings\Database\Mysql;

// Same rule as api_hash: do not commit the real password
$settings->setDb(
    (new Mysql)
        ->setUri('tcp://localhost')
        ->setDatabase('cpaneluser_madeline')
        ->setUsername('cpaneluser_bot')
        ->setPassword('DB_PASSWORD')
);

MariaDB 10.2 یا MySQL 5.6 به بالا لازم است و جدول ها خودکار ساخته می شوند. دو نکته دیگر هم روی اجرای ربات و مصرف منابع اثر دارد:

  • داخل event handler از توابع مسدودکننده مثل file_get_contents، curl_exec، PDO و mysqli_query استفاده نکنید. MadelineProto کد را بررسی می کند و اگر این توابع را ببیند، ربات را اجرا نمی کند. به جایشان از کتابخانه های amphp مثل amphp/http-client، amphp/mysql و amphp/file استفاده کنید.
  • پروسس MadelineProto worker را kill نکنید. طبق سؤالات رایج مستندات، این پروسس در پس زمینه منتظر درخواست می ماند و در حالت بی کاری مصرف CPU آن نزدیک صفر است. اگر آن را ببندید، شروع MadelineProto در هر درخواست بیش از ۳۰ ثانیه طول می کشد.

موقع انتخاب پلن هاست به سقف رم و تعداد پروسس هم زمان هم نگاه کنید، چون ربات و پروسس worker هر کدام یک پروسس جدا هستند.

خطاهای رایج نصب MadelineProto و راه حل

خطا یا نشانهعلتراه حل
Composer می گوید نسخه PHP با نیازمندی بسته سازگار نیستPHP خط فرمان قدیمی تر از 8.3 استنسخه CLI را با php -v چک کنید و مسیر PHP جدیدتر را از پشتیبانی بپرسید
خطا درباره افزونه ناموجود، مثلا gmpافزونه در نسخه PHP انتخاب شده فعال نیستافزونه را در بخش نسخه PHP در cPanel فعال کنید و وب و CLI را جدا چک کنید
Allowed memory size of ... bytes exhaustedرم در دسترس PHP تمام شدهذخیره داده ها در MySQL را فعال کنید یا منابع هاست را افزایش دهید
بعد از کد تأیید، رمز خواسته می شوداکانت تأیید دومرحله ای داردرمز دوم را وارد کنید؛ در ورود دستی از complete2faLogin استفاده کنید
FLOOD_WAIT_Xدرخواست ها بیشتر از حد مجاز بودهX ثانیه صبر کنید و بین درخواست ها فاصله بگذارید
This peer is not present in the internal peer databaseاکانت یا ربات این چت را هنوز ندیده استیوزرنیم را با getInfo resolve کنید یا با لینک دعوت عضو شوید تا چت به دیتابیس داخلی اضافه شود
Fiber stack allocate failedسقف vm.max_map_count کرنل پر شدهمقدار را با دسترسی root روی 262144 بگذارید؛ روی هاست اشتراکی شدنی نیست
event handler اجرا نمی شود و به توابع ممنوع اشاره می کنداستفاده از file_get_contents، PDO یا توابع مشابهکتابخانه های async خانواده amphp را جایگزین کنید
ربات بعد از ری استارت سرور جواب نمی دهدself-restart وب از کار افتادهکرون جاب فراخوانی آدرس ربات را اضافه کنید
API_ID_PUBLISHED_FLOODاستفاده از api_id منتشرشده در کدهای متن بازapi_id خودتان را از my.telegram.org بگیرید

امنیت session و فایل های ربات

اگر پوشه session به هر دلیلی داخل public_html مانده، دسترسی وب به آن را ببندید. داخل همان پوشه یک فایل .htaccess با این محتوا بسازید:

Require all denied

بعد آدرس پوشه را در مرورگر باز کنید. باید خطای 403 بگیرید و اگر فایل ها هنوز باز می شوند، پوشه را به بیرون از public_html منتقل کنید.

این موارد را هم رعایت کنید:

  • api_hash، توکن ربات و رمز دیتابیس را در مخزن گیت عمومی قرار ندهید.
  • فایل های تست مثل phpinfo را بعد از استفاده پاک کنید.
  • اگر احتمال می دهید session اکانت کاربری لو رفته، از تنظیمات تلگرام در بخش Devices آن نشست را ببندید و دوباره وارد شوید.

چه وقت هاست میدلاین یا سرور مجازی بگیرید

هاست اشتراکی معمولی برای MadelineProto وقتی کم می آورد که PHP 8.3 یا افزونه gmp ندارد، سقف رم و پروسسش برای یک پروسس همیشه روشن کافی نیست، یا اجرای طولانی را متوقف می کند.

اگر یک یا دو ربات دارید و اجرای وب با کرون جاب برایتان کافی است، پلن های هاست میدلاین پیکوهاست را ببینید. این هاست با کانفیگ مخصوص ربات های میدلاین، cPanel، CloudLinux، وب سرور LiteSpeed، امکان انتخاب نسخه PHP و دیتابیس MySQL و PostgreSQL ارائه می شود. افزونه های GMP، BCMath و FFI روی آن فعال است و Max Execution Time بالاتر تنظیم شده تا اسکریپت های طولانی وسط کار قطع نشوند. سرورهایش در آمستردام هلند و دیتاسنتر هتزنر آلمان هستند و لوکیشن آلمان صفحه جدای هاست میدلاین آلمان را دارد. قبل از خرید، تعداد پروسس و کانکشن هم زمان هر پلن را در جدول ببینید. اگر بعدا منابع کم آمد، ارتقا با ارسال تیکت انجام می شود.

اگر به Docker، دسترسی root برای تنظیم vm.max_map_count، چند اکانت هم زمان یا اجرای CLI دائمی نیاز دارید، سرور مجازی مناسب تر است. VPS هلند با مجازی سازی KVM پیکوهاست هارد NVMe و رم DDR4 دارد. بقیه گزینه ها، از هاست ربات Bot API تا سرور مجازی، در مقایسه گزینه های میزبانی ربات تلگرام بررسی شده اند.