چگونه با PHP یک ربات تلگرام بسازیم؟

چگونه با PHP یک ربات تلگرام بسازیم؟
با شنیدن واژه‌ی ربات همه‌ی ما ناخوداگاه به یاد ربات‌های فیزیکی که توسط انسان ساخته می‌شود، می‌افتیم. اما کلمه‌ی ربات تنها به هوش مصنوعی محدود نمی‌شود. ربات می‌تواند یک ابزار کوچک در یک نرم‌افزار پیام‌رسان باشد یا نرم‌افزار مستقلی که خدمات خاصی را به کاربر ارائه می‌دهد.
خرید شارژ ایرانسل
خرید شارژ ایرانسل، همراه اول، رایتل | خرید بسته های اینترنت ایرانسل | etore.ir
ردیاب
ردیاب آهنربایی پیام بهترین وسیله برای ردیابی وسیله نقلیه 09121394944
ردیاب
ردیاب آهنربایی پیام بهترین وسیله برای ردیابی وسیله نقلیه 09121394944
خودتان را اینجا معرفی کنید

تلگرام یک API جامع و کاربردی برای برنامه نویسان دارد که توسعه نرم افزارهای مفید را امکان‌پذیر می‌سازد.

بات‌های تلگرام یکی از محبوب‌ترین ربات هایی هستند که در حال حاضر شناخته شده است. این افزونه‌ها قابلیت نصب و توسعه‌ی آسانی دارند و همین باعث شده تا طرفداران زیادی داشته باشند. در این مطلب می‌خواهیم یک ربات ساده کرنومتر را برای تلگرام طراحی کنیم. برای پیاده‌سازی این بات ساده از پی اچ پی استفاده شده است.

از BotFather  برای ایجاد ربات مورد نظر خود استفاده کنید

اولین قدم برای ایجاد ربات این است که یک حساب کاربری برای بات خود ایجاد کنید. برای این کار از BotFather استفاده خواهیم کرد. این ربات را به لیست خود در تلگرام اضافه کرده و دستور /newbot را وارد نمایید.



بعد از اینکه ربات خود را ثبت کردید، BotFather  یک توکن ( token) به شما نمایش خواهد داد که باید از آن نگه داری کنید.  با انتخاب گزینه‌ی /help تمامی دستورات لازم برای توسعه‌ی بات به شما نشان داده می‌شود. 

با یک آنالیزگر ارتباط برقرار کنید

هیچ آنالیزگری در API بات های تلگرام وجود ندارد. بنابراین برای اطلاع از تعداد کاربرانی که از ربات استفاده می‌کنند و نحوه‌ی عملکردشان، مجبوریم سراغ راه‌حل های ثانویه برویم.
Botan ابزار رایگانی است که برای انالیز ربات‌های تلگرام توسعه داده شده است. با استفاده از این ابزار می‌توانید کاربران خود را دسته بندی کنید، اطلاعات‌شان را ببینید و نحوه‌ی عملکردشان را مشاهده نمایید.



برای استفاده از این آنالیزگر ابتدا باید نام ربات را در آن ثبت کرده و توکن خود را بگیرید.

 از وب هوک (Webhook)  برای دریافت پیام‌های کاربران استفاده کنید

با استفاده از دو تکنیک webhooks و long polling می‌توانید پیام های کاربران خود را در تلگرام دریافت کنید.



در روش long polling یا همان getUpdates هربار درخواستی را به تلگرام ارسال می‌کنید و آخرین پیام‌هایی را که کاربران به ربات فرستاده‌اند، دریافت می‌کنید.  ولی در روش وب هوک هر زمان کاربر پیامی به ربات تلگرام شما ارسال کند، بلافاصله این پیام به آدرس وب هوک شما ارجاع داده می‌شود. برای استفاده از این API تلگرام باید ssl  داشته باشید. 
ادرس URL زیر را در مرورگر باز کنید.
https://api.telegram.org:443/bot[token]/setwebhook?url=[webhook]

برای تنظیم ssl  کد زیر را در خط فرمان وارد کنید.

openssl req -newkey rsa:2048 -sha256 -nodes -keyout /path/to/certificate.key -x509 -days 365 -out /path/to/certificate.crt -subj "/C=IT/ST=state/L=location/O=description/CN=yourdomain.com" 

مطمین شوید که ssl روی  دامنه‌ی شما فعال شده باشد.

sudo ufw allow 443/tcp 

 

یک درخواست برای متد وب هوک بفرستید.
 


curl 
  -F "url=https://yourdomain.com/path/to/script.php" 
  -F "certificate=/path/to/certificate.key" 
  "https://api.telegram.org/bot[token]/setwebhook"

در مرحله‌ی اخر باید پاسخ زیر را دریافت کنید.
 

{"ok":true,"result":true,"description":"Webhook was set"} 

 

این پیام  یعنی اینکه همه چیز درست است و می‌توانیم به سراغ پیاده‌سازی هسته‌ی ربات خود برویم.

پایگاه داده بسازید

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


CREATE TABLE IF NOT EXISTS `stopwatch` (
  `chat_id` int(10) unsigned NOT NULL,
  `timestamp` int(10) unsigned NOT NULL,
  PRIMARY KEY (`chat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 مرحله‌ی بعد: کلاس کرنومتر را ایجاد کنید

کلاس stopwatch.php را برای کار با پایگاه داده ایجاد می‌کنیم. دو متغیر خصوصی برای آن در نظر می‌گیریم تا آیدی چت کاربر و زمان‌ را به آن نسبت بدهیم.
 


class Stopwatch
{
    /** @var mysqli */
    private $mysqli;
    /** @var int */
    private $stopwatch_id;
    /**
     * Stopwatch constructor
     * @param mysqli $mysqli
     * @param $stopwatch_id
     */
    public function __construct(mysqli $mysqli, $stopwatch_id)
    {
        $this->mysqli = $mysqli;
        $this->stopwatch_id = intval($stopwatch_id);
    }
}

زمانیکه کاربر دکمه‌ی شروع را انتخاب می‌کند، زمان دقیق و آیدی چت در یک ردیف از پایگاه داده ذخیر خواهد شد.

 


public function start()
{
    $timestamp = time();
    $query = "
        INSERT INTO  `stopwatch` (`chat_id`, `timestamp`)
        VALUES ('$this->stopwatch_id', '$timestamp')
        ON DUPLICATE KEY UPDATE timestamp = '$timestamp'       
    ";
    return $this->mysqli->query($query);
}

زمانیکه تایمر متوقف شد، ردیف فوق باید از پایگاه داده حذف شود:

 


/**
 * Delete row with stopwatch id
 * @return bool|mysqli_result
 */
public function stop()
{
$query = "
    DELETE FROM `stopwatch`
    WHERE `chat_id` = $this->stopwatch_id
    ";
    return $this->mysqli->query($query);
}

بدنه‌ی اصلی کلاس مربوط به زمانی است که کاربر زمان کرنومتر را در خواست کند. در اینصورت باید مقدار فعلی زمان از مقدار اولیه آن کسر شود. برای اینکار از تابع gmdate استفاده می‌کنیم.
 


/**
 * Find row with stopwatch id and return difference in seconds from saved Unix time and current time
 * @return string
 */
public function status()
{
    $query = "
        SELECT `timestamp` FROM  `stopwatch`
        WHERE `chat_id` = $this->stopwatch_id        
    ";
    $timestamp = $this->mysqli->query($query)->fetch_row();
    if (!empty($timestamp)) {
        return gmdate("H:i:s", time() - reset($timestamp));
    }
}

از  کتابخانه‌های پی اچ پی کمک بگیرید

پی اچ پی کتابخانه های زیادی برای کار با API تلگرام دارد. اما در حال حاضر فقط کتابخانه‌ی PHP  Telegram Bot API  از هر دو API بوتان و بات تلگرام پشتیبانی می‌کند.  با استفاده از Composer  این کتابخانه را نصب کنید.
 


composer require telegram-bot/api

برنامه‌نویسی وب هوک را شروع کنید

باید یک اسکرپیت برای پردازش پیام و ارسال جواب برای کاربر بنویسیم. برای اینکار فایل index.php را باز می‌کنیم و کلاس کرنومتر را به آن اضافه می‌کنیم. یک کانکشن به mysql باز کرده و آن را اجرا می‌کنیم:
 


require_once 'vendor/autoload.php';
require_once 'stopwatch.php';
 
// connect to database
$mysqli = new mysqli('database_host', 'database_user', 'database_password', 'database_name');
if (!empty($mysqli->connect_errno)) {
    throw new Exception($mysqli->connect_error, $mysqli->connect_errno);
}
 
// create a bot
$bot = new TelegramBotApiClient('bot_token', 'botanio_token');
// run, bot, run!
$bot->run();

 دستورات را تعریف کنید

حالا باید ربات را به گونه‌ای تنظیم کنیم که به دستور /start پاسخ  دهد. این دستور برای شروع تمامی ربات‌های تلگرام استفاده می‌شود.
 


$bot->command('start', function ($message) use ($bot) {
    $answer = 'Howdy! Welcome to the stopwatch. Use bot commands or keyboard to control your time.';
    $bot->sendMessage($message->getChat()->getId(), $answer);
});

در این دستور یک تابع تعریف می‌کنیم که وقتی کاربر دکمه‌ی شروع را فشار می‌دهد، یک پیام خوشامد برای او فرستاده شود. برای شروع کار کرنومتر هم یک دستور /go  برای آن تعریف می‌کنیم:

 


$bot->command('go', function ($message) use ($bot, $mysqli) {
    $stopwatch = new Stopwatch($mysqli, $message->getChat()->getId());
    $stopwatch->start();
    $bot->sendMessage($message->getChat()->getId(), 'Stopwatch started. Go!');
});

برای تعریف دستور /status  نیز همین فرایند را طی می‌کنیم. کافی است متد status() را فراخوانی کرده و نتیجه را دریافت کنیم. اگر این تابع مقدار تهی را بازگرداند، یعنی اینکه کرنومتر شروع  به کار نکرده است.
 


$bot->command('status', function ($message) use ($bot, $mysqli) {
    $stopwatch = new Stopwatch($mysqli, $message->getChat()->getId());
    $answer = $stopwatch->status();
    if (empty($answer)) {
        $answer = 'Timer is not started.';
    }
    $bot->sendMessage($message->getChat()->getId(), $answer);
});

زمانیکه کاربر کرنومتر را متوقف کرد، ما باید زمان اندازه گرفته شده را به او نشان دهیم. این کار توسط تابع stop() انجام خواهد شد.
 


$bot->command('stop', function ($message) use ($bot, $mysqli) {
    $stopwatch = new Stopwatch($mysqli, $message->getChat()->getId());
    $answer = $stopwatch->status();
    if (!empty($answer)) {
        $answer = 'Your time is ' . $answer . PHP_EOL;
    }
    $stopwatch->stop();
    $bot->sendMessage($message->getChat()->getId(), $answer . 'Stopwatch stopped. Enjoy your time!');
});

الان می‌توانید تمام فایل‌های خود را به دایرکتوری وب هوک آپلود کنید و ربات خود را آزمایش نمایید.

یک صفحه کلید برای بات خود بسازید

یک کیبورد برای بات  خود بسازید تا کاربر بتواند دستورالعمل‌های آن را انتخاب کند. ربات ما دو حالت برای انتخاب خواهد داشت. یک حالت برای شروع کار کرنومتر و دیگری برای پایان کار آن. این دو حالت را توسط تابع sendMessage() پیاده‌سازی می‌کنیم.
 


$keyboard = new TelegramBotApiTypesReplyKeyboardMarkup([['/go', '/status']], null, true);
 
$bot->sendMessage($message->getChat()->getId(), $answer, false, null, null, $keyboards);
});

برای اینکه بتوانید ربات خود را به کاربران نشان دهید باید آن را در مخازنی مانند  Storebot.me ذخیره کنید. لینک http://storebot.me/add را در مروگر خود فراخوانی کنید و فرم مربوطه را کامل نمایید. برای ذخیره ربات باید نام، نام کاربری و دسته بندی برای ربات خود انتخاب نمایید.

 

منبع: tutsplus

کارشناس فناوری اطلاعات، مدیر محتوا و وبلاگ نویس حوزه‌ی فناوری

نظرات و سوالات کاربران

ارسال پاسخ alireza
alireza
پنج شنبه ۱۴ بهمن ۱۳۹۵ ۰۱:۱۶
در پاسخ به دیدگاه سوران ارسال شده در چهارشنبه ۲۲ دی ۱۳۹۵ ۰۲:۴۶
با سلام
آیا راهی وجود داره که بشه اطلاعات یک کانال رو گرفت و توی یک صفحه وب نشون داد. مثلاْ من فقط بخوام تعداد اعضای یک کانال بخصوص رو توی سایتم نشون بدم. میشه این کار رو با php و API تلگرام کرد؟
ممنون میشم راهنمایی بفرمایین
شما میتونید از متد getChatMembersCount برای اینکار استفاده کنید
ارسال پاسخ سوران
سوران
چهارشنبه ۲۲ دی ۱۳۹۵ ۰۲:۴۶
با سلام
آیا راهی وجود داره که بشه اطلاعات یک کانال رو گرفت و توی یک صفحه وب نشون داد. مثلاْ من فقط بخوام تعداد اعضای یک کانال بخصوص رو توی سایتم نشون بدم. میشه این کار رو با php و API تلگرام کرد؟
ممنون میشم راهنمایی بفرمایین