چرا سکان آکادمی؟
ساخت ربات telegram - قسمت هشتم - ساخت دکمه ی شیشه ای

ساخت ربات telegram - قسمت هشتم - ساخت دکمه ی شیشه ای

در این قسمت از سری مجموعه های ساخت ربات تلگرام ، سعی داریم نحوه ساخت دکمه شیشه ای و عمکرد آن را آموزش دهیم ، فرض کنید ربات تلگرامی داشته باشید که با کلیک هر کاربر بر روی هر دکمه اطلاعاتی به سرور تلگرام ارسال کند و شما هم قصد داشته باشید که این اطلاعات از دید کاربر پنهان بماند ، به عنوان مثال در قسمت قبل نحوه ساخت منوی کبوردی را آموزش دادیم و کاربر پس از هر بار کلیک بر روی هر دکمه مقدار آن (که هم مقدار بود و هم نام نمایشی دکمه) به سرور تلگرام ارسال می شد ، حال اگر بخواهیم دکمه ای بسازیم که مقدار نمایشی آن با مقدار ارسال به سرور برابر نباشد ، می توانیم از دکمه ای شیشه ای استفاده کنیم ، برای درک بهتر مفهوم کد کامل ربات را قرار داده و به توضیح آن می پردازم :

<?php
require_once("Telegram.php");

define("_TOKEN", "<-BotToken->");
define("_ADMIN", "<-YourChatId->");

$json = file_get_contents('php://input');

$tg = new Telegram($json);

$chatId = $tg->getChatId();
$messageText = $tg->getText();

switch ($messageText) {
  case "/start":
    $tg->setInlineButton();
    break;
  case "1":
    $message = "شما بر روی گزینه سمت چپ کلیک کرده اید و مقدار نمایشی آن One و مقدار ارسالی آن 1 است ،";
    $message .= " این پیام پس از ده ثانیه به طور خودکار پاک می گردد.";
    $tg->sendMessage($message);
    break;
  case "2":
    $message = "شما بر روی گزینه سمت چپ کلیک کرده اید و مقدار نمایشی آن Two و مقدار ارسالی آن 2 است ،";
    $message .= " این پیام پس از ده ثانیه به طور خودکار پاک می گردد.";
    $tg->sendMessage($message);
    break;
  default:
    $message = "دستور ناشناخته است !";
    $tg->sendMessage($message);
    break;
}
<?php


class Telegram {
 
  private static $jsonData;

  public function __construct($json = null) {
    if ($json != null) {
      self::$jsonData = json_decode($json);
    }
  }

  public function getChatId() {
    if (isset(self::$jsonData->callback_query->from->id))
      return self::$jsonData->callback_query->from->id;
    else
      return self::$jsonData->message->chat->id;
  }

  public function getText() {
    if (isset(self::$jsonData->callback_query->data))
      return self::$jsonData->callback_query->data;
    else
      return self::$jsonData->message->text;
  }

  public function sendMessage($message) {
    $message = urlencode($message);
    $url = "https://api.telegram.org/bot" . _TOKEN;
    $url .= "/sendMessage?chat_id=" . $this->getChatId();
    $url .= "&text=" . $message;
    $results = file_get_contents($url);

    sleep(10);

    $results = json_decode($results);
    $messageId = $results->message_id;
    $url = "https://api.telegram.org/bot" . _TOKEN;
    $url .= "/deleteMessage?chat_id=" . $this->getChatId();
    $url .= "&message_id=" . $messageId;
    file_get_contents($url);

  }

  public function setInlineButton() {
    $keyboardArray =
      array(
        array(
          array("text" => "One", "callback_data" => "1"),
          array("text" => "Two", "callback_data" => "2")
        )
      );

    $inlineKeyboard = array(
      "inline_keyboard" => $keyboardArray
    );

    $text = "لطفا یکی از دکمه های زیر را انتخاب کنید :";
    $text = urlencode($text);

    $inlineKeyboard = json_encode($inlineKeyboard);
    $url = "https://api.telegram.org/bot" . _TOKEN;
    $url .= "/sendMessage?chat_id=" . $this->getChatId();
    $url .= "&text=" . $text;
    $url .= "&reply_markup=" . $inlineKeyboard;
    file_get_contents($url);
  }
}

- اولین قطعه کد مربوط به فایل index برنامه ما است ، فایلی که بصورت پیش فرض توسط سرور به عنوان فایل اصلی برنامه اجرا می شود ، تنها نکته آموزشی این فایل ، ساخت شی از کلاس Telegram است که همانطور که در کد مشاهده می کنید بوسیله خروجی جیسون ربات تلگرام سربار گذاری شده است (برای اطلاع بیشتر در زمینه برنامه نویسی php می توانید به آموزش زبان php مراجعه کنید).

- به کلاس Telegram می رویم ، در این کلاس 5 متد نوشته شده است که به ترتیب به توضیح آن می پردازیم.

متد construct__ :

- این متد سازنده کلاس Telegram است ، سازنده وظیفه سربار گذاری یا مقداردهی متغییرها داخل کلاس را به عهده دارد ، در زبان php سازنده را با construct__ معرفی می کنند ، این متد در زبان های دیگر به صورت های مختلف فراخوانی می شود به عنوان مثال در زبان جاوا متد سازنده باید هم نام کلاس باشد.

متد getChatId :

- این متد همانطور که از نامش پیداست ، chat_id کاربری که پیام ارسال کرده را دریافت می کند ، اما با کمی تفاوت ، برای درک بیشترمفهوم ، به قسمتی از کد متد getChatId که در زیر بازنویسی شده است ، توجه کنید :

if (isset(self::$jsonData->callback_query->from->id))
      return self::$jsonData->callback_query->from->id;

- جهت دریافت اطلاعات از طریق دکمه شیشه ای که در ادامه با نحوه ساخت آن آشنا می شوید باید برای اولین قدم مقدار های chat_id و text را بدست بیاوریم ، هنگامی که از callback استفاده میکنید ، آرایش و نام اندیس های برگشتی از سرور تلگرام کمی تغییر می کند ، در این بخش خروجی های ربات ما از دو طریق خارج نیستند یا callback هستند یا خروجی عادی ، پس برای صحت اینکه بدانیم callback است ، یک اندیس از آن را که مطمئن هستیم در صورت پاسخ از طریق callback وجود خواهد داشت را چک میکنیم ، ما در این متد صحت وجود chat_id را مورد بررسی قرار می دهیم ، اگراندیس آرایه فوق تنظیم شده باشد ، مقدار آن را بر میگردانیم در غیر این دریافت chat_id به صورت عادی انجام می گیرد.

متد getText :

- این متد هماهنند متد getChatId عمل میکند و بدلیل اینکه نوع آرایش اطلاعات آرایه callback با حالت عادی متفاوت است ، باید ابتدا مانند متد getChatId صحت وجود آرایه callback بررسی شود ، مانند قطعه کد زیر :

if (isset(self::$jsonData->callback_query->data))
      return self::$jsonData->callback_query->data;

همانطور که ملاحظه میکنید برای دریافت مقدار اطلاعات برگشتی از callback باید مقدار اندیس data را مورد تجزیه و تحلیل قرار دهیم.

متد sendMessage :

- این متد دارای قطعه کد های جالبی است ، اگر از ارسال پیام عادی آن صرف نظر کنیم ، در میانه این متد شما شاهد کد زیر می باشید :

sleep(10);

- دربرنامه نویسی چند نخی یا همان Thread ، این امکان برای برنامه نویسان فراهم است که برنامه را با وقفه اجرا کنند و ما در این آموزش فقط قصد داریم از خاصیت وقفه آن استفاده کنیم ، این متد بدون هیچ شی و کلاسی قابل استفاده است و مفسر php به محض رسیدن به این خط ، برنامه را برای مدت 10 ثانیه (مقدار پارامتر داخل متد به ثانیه است) متوقف می کند و پس از اجرای مجدد قطعه کد زیر با قابلیت حذف پیام اجرا می شود که در زیر آن قطعه کد را نوشته ایم :

$results = json_decode($results);
$messageId = $results->message_id;
$url = "https://api.telegram.org/bot" . _TOKEN;
$url .= "/deleteMessage?chat_id=" . $this->getChatId();
$url .= "&message_id=" . $messageId;
file_get_contents($url);

- برای حذف پیامی که از ربات به کاربر ارسال شده ما نیاز به دو پارامتر می باشیم ، نام های پرامترها همانطور که در بالا مشخص است chat_id و meesage_id است ، مقدار chat_id که در اختیار داریم ، اما برای بدست آوردن مقدار message_id ، یک نگاه کوتاه به جیسون خروجی ارسال پیام ربات می کنیم :

{
  "ok": true,
  "result": {
    "message_id": 37,
    "from": {
      "id": 595663424,
      "is_bot": true,
      "first_name": "Sokan Academy",
      "username": "SokanAcademy_bot"
    },
    "chat": {
      "id": 441660894,
      "first_name": "Mohammad",
      "last_name": "Zarchi",
      "type": "private"
    },
    "date": 1539352475,
    "text": "Hi"
  }
}

- به اندیس message_id خروجی توجه کنید ، همانطور که می دانید برای دستیابی به این اندیس باید از طریق عمل کنیم :

$results = json_decode($results);
$messageId = $results->message_id;

- بعد از بدست آوردن message_id ، کافی است آنرا در متد حذف پیام تلگرام جایگذاری کنید ، برای آشنایی با متد حذف پیام میتوانید به لینک زیر توجه کنید :

https://api.telegram.org/bot<-BotToken->/deleteMessage?chat_id=441660894&message_id=35

با استفاده از این متد (که در قالب لینک نوشته شده) می توانید ، پیامی که message_id آن 35 است و برای کاربری با chat_id ذکر شده که در این جا 441660894 را پاک کند.

متد setInlineButton :

- اصلی ترین متد این بخش از آموزش متد ساخت کلید شیشه ای است ، ابتدا باید برای برنامه معین کنید که چند سطر دکمه در چند ستون می خواهید ، برای معرفی تعداد سطرها و ستون ها می توانید از آرایه کمک بگیرید (آرایه های تو در تو) مانند زیر :

$keyboardArray =
      array(
        array(
          array("text" => "One", "callback_data" => "1"),
          array("text" => "Two", "callback_data" => "2")
        )
      );

- کد بالا دو دکمه را در یک سطر جای داده ، توجه مقدار اندیس callback_data مقداری است که به سرور تلگرام ارسال می شود و همانطور که مشاهده می کنید این مقدار با مقدار text متفاوت است ولی در ایجاد کیبورد که در بخش قبل آموزش دادیم مقدار text هم نام نمایشی و هم مقدار ارسالی به سرور بود (مگر در دکمه های که تلگرام برای درخواست های قانونی ایجاد کرده است) ، اگر بخواهید دو دکمه در دو ردیف ایجاد کنید ، فقط کافیست آرایه ی بالا را بصورت زیر تغییر دهید :

$keyboardArray =
      array(
        array(
          array("text" => "One", "callback_data" => "1"),
          array("text" => "Two", "callback_data" => "2")
        ),
        array(
          array("text" => "Three", "callback_data" => "3"),
          array("text" => "Four", "callback_data" => "4")
        )
      );

توجه : در هنگام تعریف آرایه ها ، به موقعیت اندیس ها و آرایه های تو در تو توجه کامل کنید.

در ادامه کد ما باید آرایه ای داشتیم که دارای یک اندیس با نام inline_keyboard باشد ، مانند زیر :

$inlineKeyboard = array(
    "inline_keyboard" => $keyboardArray
);

که مقدار این اندیس همانطور که ملاحظه می کنید ؛ با مقدار آرایه ی دکمه ها ، برابر شده است ، برای نمایش دکمه ها حتما و حتما باید متنی وجود داشته باشد ، در غیر این صورت تلگرام دکمه ها را نمایش نمی دهد ، این متن به طریق زیر معرفی می شود :

$text = "لطفا یکی از دکمه های زیر را انتخاب کنید :";
$text = urlencode($text);

- حال نوبت به ارسال دکمه ها به کاربر مورد نظر است ، ابتدا باید آرایه ی کلی دکمه ها که نام آن inlineKeyboard$ است را به جیسون تبدیل کنیم ؛ برای این منظور از تابع json_encode مانند زیر استفاده می کنیم :

$inlineKeyboard = json_encode($inlineKeyboard);

- متد ارسال دکمه ، همان متد ارسال پیام است ، تنها تفاوت ارسال متد ارسال دکمه با ارسال پیام در تعداد پارامتر هایش است ، به کد زیر که دوباره بازنویسی میکنم توجه کنید :

$url = "https://api.telegram.org/bot" . _TOKEN;
$url .= "/sendMessage?chat_id=" . $this->getChatId();
$url .= "&text=" . $text;
$url .= "&reply_markup=" . $inlineKeyboard;
file_get_contents($url);

- با توجه به کد بالا ، reply_markup تنها پارامتر اضافی است که ایجاد کننده دکمه شیشه ای است و مقدار آن برابر شده با تبدیل شده آرایه کیبوردها به جیسون ، هم اکنون این کد بر روی ربات SokanAcadmy_bot@ در حال اجراست ، در قسمت نهم به آموزش کامل ثبت نام کاربر بصورت مرحله به مرحله ، با قابلیت ذخیره اطلاعات در پایگاه داده می پردازیم.

پایان قسمت هشتم.

موفق باشید.