سلام. توی این مقاله می خوایم یک آموزش ساخت ربات تلگرام با php رو با جزئیات کامل داشته باشیم. نحوه ی ارسال متن، فایل، عکس و …، نحوه ی دریافت اطلاعاتی ارسالی از سمت کاربر، نحوه ی عبور از تحریم ها برای هاست های ایرانی و … در این مقاله به تفصیل آموزش داده خواهد شد.
پیش نیاز آموزش ساخت ربات تلگرام با php در این مقاله آشنا بودن با زبان php و برخی تگ های html است.
فهرست آموزش ساخت ربات تلگرام با php
- ساخت ربات تلگرام
- ارسال پیام متنی به ربات
- استفاده از پراکسی رایگان برای هاست های ایرانی
- ارسال پیام مالتی مدیا به ربات
- استایل دهی پیام (ضخیم کردن متن، لینک دار کردن و …)
- کیبرد دکمه ای و شیشه ای
- آپدیت و حذف پیام های قبلی
- دریافت پیام ارسالی از طرف کاربر
- وب هوک ها
ساخت ربات تلگرام
برای ساخت ربات تلگرام باید از رباتی با نام کاربری botFather استفاده کنیم. این نام کاربری را در تلگرام خود جستجو کنید تا ربات پیدا شود. سپس برای ایجاد ربات جدید، دستور newbot/ را به ربات ارسال می کنیم. با ارسال این دستور ربات از ما می خواهد که یک نام برای ربات خود انتخاب کنیم. این نام می تواند هر نام دلخواهی باشد و می توانید هم به فارسی و هم انگلیسی آن را بنویسید. این نام همان عنوان ربات است. پس از ارسال نام، ربات از ما می خواهد که یک نام کاربری یکتا برای ربات خود انتخاب کنیم. این نام باید به انگلیسی بوده، هیچ فاصله ای نداشته باشد و حتماً به کلمه ی bot ختم شود. در صورتی که نام انتخابی شما قبلاً توسط شخص دیگری انتخاب شده باشد، ربات یک پیام خطا ارسال می کند و شما دوباره بایستی یک نام جدید برای ربات خود انتخاب و ارسال کنید.
در صورتی که نام انتخابی شما یکتا و بدون خطا باشد، یک پیام تبریک که حاوی یک کد توکن برای ربات است را دریافت می کنید. در برنامه نویسی خود برای ارسال پیام به ربات و دریافت پیام از ربات به این کد توکن نیاز داریم.
مطلب مرتبط = هاست ربات تلگرام | معرفی و بررسی بهترین هاست ها
ارسال پیام متنی به ربات
به طور کلی برای ارسال انواع پیام ها به ربات از لیست متد هایی که در این لینک آمده است استفاده می کنیم:
https://core.telegram.org/bots/api#available-methods
در این صفحه، سایت تلگرام تمام متد های ارسال اطلاعات به ربات و همچنین پارامتر های هر کدام را توضیح داده است. در این بخش بعضی از این متد ها که مربوط به ارسال پیام های متنی و مالتی مدیا توضیح داده خواهد شد.
برای ارسال هر نوع پیامی به ربات از api زیر استفاده می کنیم:
https://api.telegram.org/bot<token>/METHOD_NAME
پارامتر ها را هم با متد GET و هم با متد POST می توانیم به این API ارسال کنیم. به جای <token> همان کد توکنی که در بخش قبل دریافت کردیم را قرار می دهیم و به جای METHOD_NAME متد مورد نظر برای ارسال داده و پارامتر های آن قرار می گیرد. از آنجایی که از متد get نیز می توان استفاده کرد، به سادگی می توانیم پیام های ساده را از طریق مرورگر نیز برای ربات ارسال کنیم. در ادامه یک پیام متنی را ابتدا از طریق خود مرورگر و سپس از طریق برنامه نویسی در یک فایل php به ربات ارسال می کنیم.
متد sendMessage
از این متد برای ارسال پیام متنی به ربات استفاده می شود. هر یک از متد ها یک سری پارامتر دارند. از این پارامتر ها برای مشخص کردن اطلاعات ارسالی و همچنین تنظیمات مربوطه استفاده می شود. همانطور که در جدول مشخصات پارامتر ها می بینید، نام هر پارامتر، نوع پارامتر، اختیاری یا اجباری بودن آن و توضیحات تکمیلی مشخص شده است. در اینجا متد sendMessage دو پارامتر اجباری chat_id و text دارد.
پارامتر chat_id یک پارامتر اجباری برای تمام متد های ارسال اطلاعات است و برای این است که ربات بداند که پیام را باید به چه کسی ارسال کند. در واقع chat_id شناسه ی گیرنده ی پیام است. هر کاربری در تلگرام یک شناسه ی عددی دارد. این شناسه را به دو شکل می توانیم پیدا کنیم. یکی وقتی که کاربر پیامی برای ربات ارسال می کند (که در بخش دریافت اطلاعات توضیح داده می شود) و یکی با استفاده از ربات @userinfobot. هر کاربری با استفاده از این ربات می تواند شناسه ی تلگرامی خود را پیدا کند.
ربات @userinfobot را در تلگرام خود جستجو کرده و پیدا کنید. پس از start یک پیام حاوی اطلاعات کاربری برای شما ارسال می شود. مقدار Id همان شناسه ی کاربری شماست. این شناسه را در جایی ذخیره کنید تا در متد های ارسال پیام، برای ارسال پیام های تستی به تلگرام خود از آن استفاده کنید.
پارامتر بعدی از متد sendMessage، پارامتر text است. که همان پیام متنی ای است که می خواهیم به ربات ارسال کنیم. حالا برای تست یک متن ساده مثل “سلام” را یکبار با استفاده از مروگر و یکبار با استفاده از برنامه نویسی برای ربات خود ارسال می کنیم.
خب، طبق توضیح داده شده، مقادیر را در لینک زیر جایگذاری می کنیم:
https://api.telegram.org/bot<token>/METHOD_NAME
https://api.telegram.org/bot1112247097:AAGa4iaP8HPVd6oBvmpKiPrKoY2dp1gg7mE/sendMessage
حالا پارامتر های خود را به لینک بالا اضافه کرده و آن را در مرورگر خود اجرا می کنیم:
در صورتی که مشکلی در ارسال اطلاعات وجود نداشته باشد، پیام به کاربر ارسال شده و خروجی زیر در مروگر چاپ می شود:
{"ok":true,"result":{"message_id":2,"from":{"id":1112247097,"is_bot":true,"first_name":"test","username":"backendbazbot"},"chat":{"id":275488860,"first_name":"zohreh","last_name":"Ahmadi","username":"zohreh_ahmadi70","type":"private"},"date":1602309973,"text":"\u0633\u0644\u0627\u0645"}}
که در آن اطلاعات کاربر، اطلاعات ربات و اطلاعات متن ارسالی مشخص شده است.
ارور های احتمالی:
{"ok":false,"error_code":400,"description":"Bad Request: chat_id is empty"}
ددر صورتی که پارامتر chat_id وارد نشده و یا خالی باشد با این ارور مواجه خواهید شد.
{"ok":false,"error_code":400,"description":"Bad Request: message text is empty"}
در صورتی که پارامتر text وار نشده و یا خالی باشد با این ارور مواجه خواهید شد.
{"ok":false,"error_code":400,"description":"Bad Request: chat not found"}
این ارور به این معناست که یا chat_id اشتباه وارد شده است و یا اینکه chat_id صحیح است اما آن کاربر در ربات وارد نشده و start نکرده است.
برای ارسال این پیام از طریق فایل php، کافیست یک فایل php در هاست یا لوکال هاست خود ایجاد کرده و کد زیر را در آن بنویسید:
<?php
$result = file_get_contents("https://api.telegram.org/bot1112247097:AAGa4iaP8HPVd6oBvmpKiPrKoY2dp1gg7mE/sendMessage?chat_id=275488860&text=سلام");
echo $result;
تابع file_get_contents لینکی که به عنوان ورودی دریافت کرده است را با متد get اجرا کرده و نتیجه را در خروجی برمیگرداند. برای ارسال پیام های ساده می توان بدون هیچ مشکلی از این تابع استفاده کرد اما برای ارسال پیام های پیچیده تر یا استفاده از پراکسی هنگام ارسال داده در هاست های ایرانی باید از روش کاربردی تری مثل curl استفاده کرد. همچنین با استفاده از curl می توانیم پارامتر های خود را با استفاده از متد post که متد امن تری است ارسال کنیم.
اگر همین پیام را بخواهیم با استفاده از curl ارسال کنیم، کد آن را به این شکل می نویسیم:
<?php
$handle = curl_init("https://api.telegram.org/bot1112247097:AAGa4iaP8HPVd6oBvmpKiPrKoY2dp1gg7mE/sendMessage");
$parameters = [
"chat_id" => 275488860,
"text" => "سلام"
];
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters));
curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
$result = curl_exec($handle);
echo $result;
استفاده از پراکسی رایگان برای هاست های ایرانی
در صورتی که از هاست خارجی استفاده می کنید، می توانید از این بخش گذشته و بخش بعدی آموزش را مطالعه کنید.
هاست های ایرانی چون به اینترنت ایران متصل هستند، نمی توانند بدون پراکسی به سرور های تلگرام دسترسی داشته باشند. پس بایستی از یک پراکسی در تابع curl برای ارسال اطلاعات استفاده کنیم. در این بخش می خواهیم طریقه ی ساخت یک پراکسی رایگان از طریق ساخت یک اسکریپت در گوگل را آموزش ببینیم. در این روش به جای ارتباط مستقیم با تلگرام، ابتدا پیام خود را به یک اسکریپت گوگل ارسال کرده و سپس از آنجا آن را به تلگرام ارسال می کنیم. نیازی به یادگیری نحوه ی کد نویسی این بخش ندارید و فقط کافیست آن را دقیقاً طبق آموزش ایجاد کرده و در تابع curl خود وارد کنید.
برای ساخت این پراکسی ابتدا وارد آدرس زیر شوید:
https://script.google.com/home/my
سپس از سایدبار سمت چپ گزینه ی new project را انتخاب کنید.
در صفحه ای که باز می شود کد زیر را کپی و آن را با یک نام دلخواه ذخیره کنید.
کد اسکریپت گوگل (به زبان جاوا اسکریپت).
function doGet(e) {
if(typeof e !== 'undefined'){
return requestHandler(e);
}
}
function doPost(e) {
if(typeof e !== 'undefined'){
return requestHandler(e);
}
}
function requestHandler(e){
var res = handleRequest(e);
return ContentService.createTextOutput(res);
}
function handleRequest(e) {
if(typeof e.parameter.bot_token === 'undefined'){
return 'Error! Bot token not provided';
} else if(typeof e.parameter.method === 'undefined') {
return 'Error! Method name not provided';
}
var bot_token = e.parameter.bot_token;
var tg_method = e.parameter.method;
var data = {
"method": "post",
"muteHttpExceptions": true,
"contentType": "application/json",
}
if(typeof e.parameter.args !== 'undefined'){
var args = e.parameter.args;
data.payload = args;
}
//return e.parameter.args;
var res = UrlFetchApp.fetch('https://api.telegram.org/bot' + bot_token + '/' + tg_method, data);
Logger.log(res.getContentText());
return res.getContentText();
}
سپس از تب publish گزینه ی deploy as web app را انتخاب کنید.
در پاپ آپِ باز شده برای منوی کشویی Who has access to the app گزینه ی آخر یعنی Anyone, even anonymous را انتخاب کرده و دکمه ی deploy را بزنید.
سپس گزینه ی review permission را بزنید و با انتخاب gmail خود به این اسکریپت اجازه ی دسترسی بدهید. و گزینه ی Allow را کلیک کنید.سپس لینک اسکریپت برای شما ایجاد می شود. لینک ایجاد شده را در جایی ذخیره کنید تا در بخش بعد به عنوان پراکسی در تابع curl جایگذاری کنیم.
برای استفاده از این پراکسی، باید آن را در تابع curl به این شکل تغییر دهیم:
<?php
$parameters = [
"chat_id" => 275488860,
"text" => "سلام"
];
$args = array(
'bot_token' => "1112247097:AAGa4iaP8HPVd6oBvmpKiPrKoY2dp1gg7mE",
'method' => "sendMessage",
'args' => json_encode($parameters)
);
$handle = curl_init("https://script.google.com/macros/s/AKfycbxIFY5Sig0peecmH_hay-XveOkqtl6Gq9srDikTIWQ8n5ZDhivJ/exec");
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, $args);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($handle, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($handle);
echo $result;
خط 8 – کد توکن ربات نوشته می شود.
خط 9 – متد ارسال پیام
خط 13 – لینک پراکسی که با اسکریپت گوگل ساختیم
ارسال پیام مالتی مدیا به ربات
برای ارسال پیام های مالتی مدیا از متد های زیر استفاده می کنیم:
برای مشاهده ی لیست جزئیات پارامتر های هر متد روی نام آن کلیک کنید.
- sendPhoto: ارسال عکس
- sendAudio: ارسال صوت
- sendDocument: ارسال فایل
- sendVideo: ارسال ویدیوی
- sendAnimation: ارسال انیمیشن
- sendVoice: ارسال صدا
مانند متد ارسال پیام، این متد های نیز هر کدام دو پارامتر اجباری دارند. یکی chat_id، و دیگری خود آن مدیا؛ که برای sendPhoto نام پارامتر photo است، برای sendAudio نام آن audio است و ….این مدیا را می توانیم از سه طریق ارسال کنیم. اول از طریق لینک مدیا که همان لینک مستقیم آدرسی است که فایل مدیا در آن آپلود کرده اید. دوم با استفاده از ارسال فایل از طریق متد POST و سوم با استفاده از آی دی فایلی که در سرور تلگرام ذخیره شده باشد. روش سوم که نحوه ی به دست آوردن این id است در بخش دریافت اطلاعات توضیح داده خواهد شد. ولی دو روش اول در مثال هایی در زیر نمایش داده خواهد شد.
1- ارسال فایل ها با لینک مستقیم
کد ارسال یک عکس می تواند به شکل زیر باشد. ابتدا کد ارسال کلی curl را در یک تابع جداگانه می نویسیم تا در مثال های بعدی برای مختصر نویسی از تابع آن استفاده کنیم:
<?php
function sendToTelegram($method, $parameters=[]) {
$handle = curl_init("https://api.telegram.org/bot1112247097:AAGa4iaP8HPVd6oBvmpKiPrKoY2dp1gg7mE/$method");
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters));
curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
$result = curl_exec($handle);
return $result;
}
$parameters = [
"chat_id" => 275488860,
"photo" => "https://backendbaz.ir/wp-content/uploads/2020/06/mainlogo-3.png"
];
sendToTelegram('sendPhoto', $parameters);
از این پس در مثال های بعدی از تابع sendToTelegram($method, $parameters); برای ارسال اطلاعات به تلگرام استفاده می کنیم.
2- ارسال از طریق متد post
برای ارسال فایل به این روش، اندکی تنظیمات curl را تغییر می دهیم. در این روش، از هدر Content-Type: multipart/form-data استفاده شده و پارامتر ها نیز پیش از ارسال دیگر تبدیل به json نمی شوند.
یکی از پارامتر های اختیاری مدیا، پارامتر caption است که برای ارسال متن برای کپشن آن مدیا استفاده می شود. در مثال زیر یک فایل صوتی را به همراه کپشن با استفاده از متد post به ربات خود ارسال می کنیم:
<?php
function sendFileToTelegram($method, $parameters=[]) {
$handle = curl_init("https://api.telegram.org/bot1112247097:AAGa4iaP8HPVd6oBvmpKiPrKoY2dp1gg7mE/$method");
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, $parameters);
curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data"));
$result = curl_exec($handle);
echo $result;
}
$parameters = [
"chat_id" => 275488860,
"audio" => new \CurlFile($_SERVER['DOCUMENT_ROOT'].'/filename.mp3', 'audio/mpeg', 'filename.mp3'),
"caption" => 'این زیر نویس آهنگ است'
];
sendFileToTelegram('sendAudio', $parameters);
3- ارسال فایل با استفاده از آی دی فایل (file_id)
آی دی فایل ها با استفاده از آپلود فایل در ربات تلگرام به دست می آید که در بخش دریافت اطلاعات آن را بررسی می کنیم.
استایل دهی پیام (ضخیم کردن متن، لینک دار کردن و …)
برای استایل دهی به متن یا کپشن پیام ها ابتدا پارامتر parse_mode را برابر با HTML قرار می دهیم. سپس می توانیم از تگ های html زیر برای استایل دهی به متن استفاده کنیم:
<b>bold</b>, <strong>bold</strong>
<i>italic</i>, <em>italic</em>
<u>underline</u>, <ins>underline</ins>
<s>strikethrough</s>, <strike>strikethrough</strike>, <del>strikethrough</del>
<b>bold <i>italic bold <s>italic bold strikethrough</s> <u>underline italic bold</u></i> bold</b>
<a href="http://www.example.com/">inline URL</a>
<a href="tg://user?id=123456789">inline mention of a user</a>
<code>inline fixed-width code</code>
<pre>pre-formatted fixed-width code block</pre>
در مثال زیر یک متن را به ربات ارسال می کنیم که در آن کلمه ی بکند باز به آدرس https://backendbaz.ir لینک شده است:
<?php
$parameters = [
"chat_id" => 275488860,
"text" => "برای مشاهده ی ادامه مطلب به سایت <a href="https://backendbaz.ir">بکند باز</a> مراجعه کنید."
];
sendToTelegram('sendMessage', $parameters);
کیبورد دکمه ای و شیشه ای
برای افزودن کیبورد به متن، باید پارامتر reply_markup را مقدار دهی کنیم. این پارامتر می تواند چهار مقدار داشته باشد که در اینجا با دو تای آن کار داریم؛ InlineKeyboardMarkup برای کیبورد شیشه ای و ReplyKeyboardMarkup برای کیبورد دکمه ای. که هر کدام از اینها، خود یک آرایه با پارامتر های مربوط به خود هستند. با دو مثال طرز کد نویسی این دو کیبورد را توضیح می دهیم:
1- کیبورد دکمه ای
پارامتر keyboard ، به صورت سه آرایه ی تو در تو نوشته می شود. آرایه ی اول ردیف ها و آرایه ی دوم ستون های کیبورد را مشخص می کند و آرایه ی سوم مربوط به مشخصات هر دکمه است. هر دکمه یک متن و سه پارامتر اختیاری دیگر دارد. اگر برای هر دکمه فقط بخواهیم پارامتر متن آن را بنویسیم، می توان از آرایه ی سوم صرف نظر کرد. پارامتر one_time_keyboard مشخص می کند که پس از اینکه کاربر یک دکمه را انتخاب کرد کیبورد پنهان شود یا خیر. اگر مقدار آن برابر با true باشد، کیبورد در صفحه باقی خواهد ماند. پارامتر resize_keyboard سایز کیبورد را با توجه به تعداد ردیف ها مشخص می کند. اگر این پارامتر false باشد، صرف نظر از تعداد ردیف ها، همیشه ارتفاع کیبورد، مانند کیبورد تایپ معمولی خواهد بود. برای زیبایی و کارایی بهتر، این پارامتر را true قرار می دهیم.
در مثال زیر، کیبورد ما دو ردیف و سه ستون دارد.
<?php
$parameters = [
"chat_id" => 275488860,
"text" => "نظر شما در مورد این آموزش :",
"reply_markup" => array(
"keyboard" => array(
array("خیلی بد", "ضعیف", "متوسط"),
array("خوب", "خیلی خوب", "عالی"),
),
"one_time_keyboard" => false,
"resize_keyboard" => true,
)
];
sendToTelegram('sendMessage', $parameters);
2- کیبورد شیشه ای
این آرایه فقط یک پارامتر inline_keyboard دارد که مشابه قبل، مقدار آن شامل سه آرایه ی تو در تو است. از آنجایی که در دکمه های شیشه ای، علاوه بر متن دکمه معمولاً یک لینک یا یک داده ی اضافی می خواهیم با آن ارسال کنیم، آرایه ی سوم حذف نمی شود. در این مثال یک کیبورد شیشه ای با دو ردیف داریم. ردیف اول دو ستون و ردیف دوم یک ستون دارد:
<?php
$parameters = [
"chat_id" => 275488860,
"text" => "یکی از گزینه های زیر را انتخاب کنید:",
"reply_markup" => array(
"inline_keyboard" => array(
array(
array("text" => "ورود به سایت", "url" => "https://backendbaz.ir"),
array("text" => "لایک", "callback_data" => "like_12"),
),
array(
array("text" => "افزودن به لیست", "callback_data" => "add_to_list"),
)
)
)
];
sendToTelegram('sendMessage', $parameters);
با استفاده از پارامتر url، می توانیم دکمه ی شیشه ای را به یک وبسایت لینک کنیم. و پارامتر callback_data برای ارسال اطلاعاتی در مورد آن دکمه به سرور استفاده می شود. پس از اینکه کاربر دکمه را فشار داد، تلگرام مدت زمانی مهلت می دهد تا در سمت سرور این callback_query را دریافت و عملیات لازم را انجام دهیم و پس از آن، این اطلاعات منقضی می شود. callback_query در بخش دریافت اطلاعات توضیح داده خواهد شد.
آپدیت و حذف پیام های قبلی
همانطور که در ابتدای آموزش گفتیم، هر گاه که پیامی به ربات ارسال می شود، یک پاسخ نیز در سمت سرور دریافت خواهیم کرد که مشخصات آن پیام ارسال شده را در قالب json برمیگرداند. این پاسخ مربوط به ارسال یک پیام ساده “سلام” است.
{"ok":true,"result":{"message_id":2,"from":{"id":1112247097,"is_bot":true,"first_name":"test","username":"backendbazbot"},"chat":{"id":275488860,"first_name":"zohreh","last_name":"Ahmadi","username":"zohreh_ahmadi70","type":"private"},"date":1602309973,"text":"\u0633\u0644\u0627\u0645"}}
اولین پارامتر آرایه ی result که message_id نام دارد، شناسه ی پیام ارسال شده است که برای آپدیت و ویرایش و یا برای حذف یک پیام از این شناسه برای ارجاع به آن پیام استفاده می کنیم. برای ویرایش یک پیام متنی، به شکل زیر می توانیم کد نویسی کنیم:
<?php
$parameters = [
"message_id" => 2,
"text" => "سلام دوستان"
];
sendToTelegram('editMessageText', $parameters);
انواع دیگر متد های ویرایش را می توانید در این لینک مشاهده کنید:
https://core.telegram.org/bots/api#updating-messages
برای حذف یک پیام کافیست chat_id یا شناسه ی کاربر، و message_id یا شناسه ی پیام را به متد deleteMessage ارسال کنیم:
<?php
$parameters = [
"chat_id" => 275488860,
"message_id" => 2
];
sendToTelegram('deleteMessage', $parameters);
البته حذف پیام ها شرایطی دارد:
- باید کمتر از 48 ساعت از ارسال آن گذشته باشد
- ربات ها در گروه ها، سوپر گروه ها فقط می توانند پیام هایی که از سمت ربات ارسال شده است را حذف کنند. اما اگر ربات، مدیر یک گروه یا سوپر گروه باشد، همه ی پیام ها را می تواند حذف کند.
دریافت پیام ارسالی از طرف کاربر
در این بخش از آموزش ساخت ربات تلگرام با php به سراغ برنامه نویسی برای دریافت و تحلیل پیام ها می رویم. برای دریافت پیام هایی که کاربر به ربات ارسال می کند، یک راه استفاده از متد getUpdates است که البته فقط برای موارد تست از آن استفاده می شود و عملاً در برنامه نویسی یک ربات ساده نیز نمی توان از آن بهره ی خوبی بود و به جای آن باید از وب هوک ها که در بخش بعد توضیح می دهیم استفاده کرد.
متد getUpdates پیام هایی که کاربران ارسال می کنند را تا 24 ساعت در خود نگه می دارد. این متد هیچ پارامتر اجباری ای ندارد و فقط چند پارامتر اختیاری برای محدود کردن نمایش تعداد پیام ها استفاده می شود.
<?php
sendToTelegram('getUpdates');
خروجی این تابع یک json است که حاوی اطلاعات پیام های ارسالی شامل ارسال کننده، نوع پیام، متن پیام و … است.
{"ok":true,"result":[{"update_id":358413271, "message":{"message_id":11,"from":{"id":275488860,"is_bot":false,"first_name":"zohreh","last_name":"Ahmadi","username":"zohreh_ahmadi70","language_code":"en"},"chat":{"id":275488860,"first_name":"zohreh","last_name":"Ahmadi","username":"zohreh_ahmadi70","type":"private"},"date":1602402800,"text":"salam"}},{"update_id":358413272, "message":{"message_id":12,"from":{"id":275488860,"is_bot":false,"first_name":"zohreh","last_name":"Ahmadi","username":"zohreh_ahmadi70","language_code":"en"},"chat":{"id":275488860,"first_name":"zohreh","last_name":"Ahmadi","username":"zohreh_ahmadi70","type":"private"},"date":1602402815,"photo":[{"file_id":"AgACAgQAAxkBAAMMX4K5_ma_vlHXg227K6vdpMyn83MAAiW2MRsCBBlQlJJumUkwxQWZmuMiXQADAQADAgADbQADibYGAAEbBA","file_unique_id":"AQADmZrjIl0AA4m2BgAB","file_size":1668,"width":59,"height":59}]}},{"update_id":358413273, "message":{"message_id":13,"from":{"id":275488860,"is_bot":false,"first_name":"zohreh","last_name":"Ahmadi","username":"zohreh_ahmadi70","language_code":"en"},"chat":{"id":275488860,"first_name":"zohreh","last_name":"Ahmadi","username":"zohreh_ahmadi70","type":"private"},"date":1602402834,"voice":{"duration":6,"mime_type":"audio/ogg","file_id":"AwACAgQAAxkBAAMNX4K6Ep_UkQS9CAEZL3dK_tActaQAAi0KAAICBBlQ4bvjIEH2Y5YbBA","file_unique_id":"AgADLQoAAgIEGVA","file_size":53613}}}]}
اگر این json را با استفاده از تابع json_decode به آرایه تبدیل کنیم، خروجی زیر را خواهیم داشت:
(object) array(
'ok' => true,
'result' =>
array (
0 =>
(object) array(
'update_id' => 358413271,
'message' =>
(object) array(
'message_id' => 11,
'from' =>
(object) array(
'id' => 275488860,
'is_bot' => false,
'first_name' => 'zohreh',
'last_name' => 'Ahmadi',
'username' => 'zohreh_ahmadi70',
'language_code' => 'en',
),
'chat' =>
(object) array(
'id' => 275488860,
'first_name' => 'zohreh',
'last_name' => 'Ahmadi',
'username' => 'zohreh_ahmadi70',
'type' => 'private',
),
'date' => 1602402800,
'text' => 'salam',
),
),
1 =>
(object) array(
'update_id' => 358413272,
'message' =>
(object) array(
'message_id' => 12,
'from' =>
(object) array(
'id' => 275488860,
'is_bot' => false,
'first_name' => 'zohreh',
'last_name' => 'Ahmadi',
'username' => 'zohreh_ahmadi70',
'language_code' => 'en',
),
'chat' =>
(object) array(
'id' => 275488860,
'first_name' => 'zohreh',
'last_name' => 'Ahmadi',
'username' => 'zohreh_ahmadi70',
'type' => 'private',
),
'date' => 1602402815,
'photo' =>
array (
0 =>
(object) array(
'file_id' => 'AgACAgQAAxkBAAMMX4K5_ma_vlHXg227K6vdpMyn83MAAiW2MRsCBBlQlJJumUkwxQWZmuMiXQADAQADAgADbQADibYGAAEbBA',
'file_unique_id' => 'AQADmZrjIl0AA4m2BgAB',
'file_size' => 1668,
'width' => 59,
'height' => 59,
),
),
),
),
2 =>
(object) array(
'update_id' => 358413273,
'message' =>
(object) array(
'message_id' => 13,
'from' =>
(object) array(
'id' => 275488860,
'is_bot' => false,
'first_name' => 'zohreh',
'last_name' => 'Ahmadi',
'username' => 'zohreh_ahmadi70',
'language_code' => 'en',
),
'chat' =>
(object) array(
'id' => 275488860,
'first_name' => 'zohreh',
'last_name' => 'Ahmadi',
'username' => 'zohreh_ahmadi70',
'type' => 'private',
),
'date' => 1602402834,
'voice' =>
(object) array(
'duration' => 6,
'mime_type' => 'audio/ogg',
'file_id' => 'AwACAgQAAxkBAAMNX4K6Ep_UkQS9CAEZL3dK_tActaQAAi0KAAICBBlQ4bvjIEH2Y5YbBA',
'file_unique_id' => 'AgADLQoAAgIEGVA',
'file_size' => 53613,
),
),
),
),
)
همانطور که می بینید، پیام اول یک متن “salam”، پیام دوم یک تصویر و پیام سوم یک صدا است. پارامتر های photo و voice یک پارامتری به نام file_id دارند، که همان شناسه ی فایل است که در بخش ارسال فایل به آن اشاره شد. با استفاده از این شناسه فایل ها را در سرور تلگرام ذخیره کرد و هنگام نیاز با استفاده از file_id آن، آنرا برای کاربر ارسال کرد.
در صورتی که رباتی دارید که با فایل های حجیم سرو کار دارد مثلاً ربات آهنگ یاب یا دانلود فیلم یا … می توانید یکبار فایل های آهنگ یا فیلم را به تلگرام ارسال کرده و فایل آیدی آن را به جای آدرس فایل هنگام ارسال به کاربر استفاده کنید. این کار هم توسط تلگرام توصیه شده است، هم سرعت کار رباتتان را بسیار بالا می برد و هم بسیار در حجم مصرفی هاست خود صرفه جویی کرده و هزینه هایتان را کم می کند.
<?php
$parameters = [
"chat_id" => 275488860,
"voice" => "AwACAgQAAxkBAAMNX4K6Ep_UkQS9CAEZL3dK_tActaQAAi0KAAICBBlQ4bvjIEH2Y5YbBA"
];
sendToTelegram('sendAudio', $parameters);
همانطور که گفتیم استفاده از getUpdates روش مناسبی برای دریافت اطلاعات کاربر در یک ربات نیست. چرا که فقط هنگامی می توانیم پیام ها را دریافت کنیم که خودمان این متد را فراخوانی کنیم. در حالیکه باید بلافاصله هنگام ارسال پیام توسط کاربر، آن پیام خوانده شده و تحلیل شود. برای اینکار از وب هوک ها استفاده می کنیم:
وب هوک ها
وب هوک یک فایل php است که در هاست خود می سازیم و آن را به ربات معرفی می کنیم تا هر زمانی که کاربر پیامی ارسال کرد، آن را مستقیماً به این فایل بفرستد.
نکته: برای استفاده از وب هوک ها، دامنه ی ما حتماً باید ssl معتبر داشته باشد.
فرض کنید فایلی به نام bot.php در ریشه ی اصلی هاست سایت backendbaz ساخته ایم. برای تنظیم این فایل به عنوان وب هوک ربات، از متد setWebhook استفاده می کنیم، و آدرس فایل را به عنوان پارامتر url برای آن ارسال می کنیم:
<?php
$parameters = [
"url" => "https://backendbaz.ir/bot.php"
];
sendToTelegram('setWebhook', $parameters);
در صورتی که پیام زیر در خروجی چاپ شد، یعنی وب هوک با موفقیت تنظیم شده است:
{"ok":true,"result":true,"description":"Webhook was set"}
البته از آنجایی که تنظیم وب هوک فقط یکبار لازم است، می توانیم به جای برنامه نویسی در فایل php مستقیماً یکبار از طریق مرورگر اینکار را انجام دهیم:
https://api.telegram.org/bot<token>/setWebhook?url=https://backendbaz.ir/bot.php
اطلاعات ارسالی توسط کاربر با استفاده از متد POST به فایل bot.php ارسال خواهند شد. پس برای دریافت این اطلاعات می توانیم به شکل زیر کد نویسی کنیم:
<?php
$content = file_get_contents("php://input");
$content = json_decode($content, true);
اطلاعات ورودی را با استفاده از تابع json_decode به آرایه تبدیل می کنیم تا چرخیدن درون آن و بررسی پارامتر های آن ساده تر باشد.
در صورتی که کاربر یک پیام را به ربات ارسال کند چنین چیزی داریم:
(object) array(
'update_id' => 358413271,
'message' =>
(object) array(
'message_id' => 11,
'from' =>
(object) array(
'id' => 275488860,
'is_bot' => false,
'first_name' => 'zohreh',
'last_name' => 'Ahmadi',
'username' => 'zohreh_ahmadi70',
'language_code' => 'en',
),
'chat' =>
(object) array(
'id' => 275488860,
'first_name' => 'zohreh',
'last_name' => 'Ahmadi',
'username' => 'zohreh_ahmadi70',
'type' => 'private',
),
'date' => 1602402800,
'text' => 'salam',
),
),
داده ی ارسالی علاوه بر یک متن مثل بالا می تواند کلیک روی یک دکمه ی شیشه ای باشد، یا ویرایش یک پیام و یا … که لیست این رخداد ها را می توانید در این لینک ببینید:
https://core.telegram.org/bots/api#update
هر رخدادی که از سمت کاربر به ربات ارسال شود، یک پیام مختص به آن به فایل bot.php ارسال می شود که با استفاده از متن پیام ارسالی، نوع پیام، گیرنده ی پیام و … می توان آن را تحلیل کرد و به آن پاسخ داد.
مثلاً فرض کنید می خواهیم برای کسی که دستور /start را ارسال کرده است یعنی کسی که به تازگی وارد ربات شده است یک پیام خوش آمد گویی ارسال کنیم. در این صورت فایل bot.php را به این شکل می نویسیم:
<?php
//تابع ارسال پیام به ربات
function sendToTelegram($method, $parameters=[], $headers = array("Content-Type: application/json")) {
$handle = curl_init("https://api.telegram.org/bot1112247097:AAGa4iaP8HPVd6oBvmpKiPrKoY2dp1gg7mE/$method");
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($parameters));
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($handle);
echo $result;
}
//دریافت اطلاعات پیام ارسالی
$content = file_get_contents("php://input");
$content = json_decode($content, true);
//agar yek payam ersal shode bashad
if(isset($content['message'])) {
$message = $content['message'];
//agar payam ersali, matni bashad
if(isset($message['text'])){
if($message['text'] == '/start') {
//chat_id marbut be ferestendeye payam
$chat_id = $message['from']['id'];
$first_name = $message['from']['first_name'];
$parameters = [
'chat_id' => $chat_id,
'text' => 'کاربر عزیز '. $first_name .'، خوش آمدید'
];
sendToTelegram('sendMessage', $parameters);
}
}
}
آپدیت: استفاده از پراکسی گوگل بر سر راه وب هوک
در هاست های ایرانی در دو حالت ممکن است نتوانید با ربات تلگرام ارتباط برقرار کنید. یک حالت، حالتی است که در بخش قبلی توضیح دادیم: هاست های ایرانی چون به اینترنت ایران متصل هستند، نمی توانند بدون پراکسی به سرور های تلگرام دسترسی داشته باشند. در نتیجه نمی توانند درخواست های ارسال پیام به سرور تلگرام را ارسال کنند. که توضیح دادیم که می توانید برای رفع این مشکل از یک پراکسی رایگان گوگل استفاده کنید.
حالت دوم حالتی است که هاست شما درخواست های آمده از سمت آی پی های تلگرام را مسدود کرده باشد که این اتفاق در همه هاست های ایرانی رخ نمی دهد مگر اینکه آن شرکت هاستینگ این محدودیت را اعمال کرده باشد. در این صورت نیز می توانید از یک پراکسی دیگر استفاده کنید.
دقیقاً مشابه آنچه در بخش قبل توضیح داده شد، یک پراکسی جدید با کد زیر ایجاد کنید و به جای [webhook_url] آدرس وب هوک خود را قرار دهید. که در این مثال برابر است با https://backendbaz.ir/bot.php.
function doGet(e){
var options = {
'method' : 'post',
'contentType': 'application/json',
// Convert the JavaScript object to a JSON string.
'payload' : e.postData.contents,
'muteHttpExceptions' : true
};
var response = UrlFetchApp.fetch('[webhook_url]', options);
Logger.log(response.getContentText());
}
function doPost(e){
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : e.postData.contents,
'muteHttpExceptions' : true
};
var response = UrlFetchApp.fetch('[webhook_url]', options);
Logger.log(response.getContentText());
}
پس از آن از لینک پراکسیِ ایجاد شده برای تنظیم وب هوک استفاده کنید:
https://api.telegram.org/bot<token>/setWebhook?url=[لینک پراکسی]
در این حالت، ربات تلگرام ابتدا پیام را به این پراکسی ارسال می کند و سپس پیام از سمت پراکسی به هاست شما ارسال می شود. در نتیجه از سمت هاست، آی پی گوگل شناسایی می شود نه آی پی تلگرام، و محدودیت به این طریق از بین می رود.
سلام
من یه ربات مدیر به گروه اد کردم با یه ربات معمولی
با ربات معمولی پیامی تو گروه ارسال کردم دیدم ربات مدیر نمی تونه پیام رو دریافت کنه!
ولی ربات مدیر پیام کاربران معمولی رو دریافت میکرد!
دلیلش چیه؟
ممنون
سلام
پیام هایی که از ربات به گروه ارسال میشه به فایل وب هوک ربات دیگر ارسال نمیشه. و ربات ادمین فقط می تونه به پیام هایی که در وب هوکش دریافت می کنه پاسخ بده.
شما می تونید در برنامه نویسی ربات معمولی بنویسید که هر پیامی که به گروه ارسال می کنه یکبار خروجی همون پیام که به صورت json هست رو به وب هوک ربات قبلی هم ارسال کنه. البته باید قبلش تغییراتی در کلیدهای json هم بدید.
اگر برنامه نویسی این بخش رو نمی دونید بفرمایید که کدش رو براتون ارسال کنم.
بله برنامه نویسم
ولی منظورتون رو نفهمیدم.
الان ربات مدیر کلا وقتی ربات معمولی پیامی توی گروه میده ربات مدیر هیچ پیامی دریافت نمیکنه! در این صورت چطوری خروجی بده؟!
ربات مدیر فقط پیام هایی که به وب هوکش ارسال میشه رو دریافت می کنه. و اصلا کاری به ربات مدیر نباید داشته باشید.
در ربات معمولی هر وقت ربات هر پیامی رو به گروه می فرسته، در برگشت یک پاسخ به شکل زیر دریافت می کنه:
و از طرفی پیام هایی که کاربران عادی به گروه می فرستند با فرمت زیر به وب هوک ربات مدیر ارسال میشه:
ربات مدیر هم هر پیامی که با این فرمت به وب هوکش ارسال بشه رو دریافت می کنه.
در نتیجه در کد مربوط به ربات معمولی باید json اول رو به وب هوک ربات مدیر ارسال کنید. با این تفاوت که به جای کلید result کلید message باید قرار بگیره. و بعد به آدرس وب هوک ربات مدیر ارسال بشه. در این صورت ربات مدیر می تونه پیام ارسالی ربات معمولی رو هم دریافت کنه.
$result = json_decode($result, true);
$result['message'] = $result['result'];
$handle = curl_init("https://backendbaz.ir/bot.php"); // وب هوک ربات مدیر
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, json_encode($result));
curl_setopt($handle, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
curl_exec($handle);
گفتید "در نتیجه در کد مربوط به ربات معمولی باید json اول رو به وب هوک ربات مدیر ارسال کنید"
آخه ربات معمولی مدیریتش دست من نیست که بخوام چیزی ازش بگیرم.
برای مثال من یه گروه زدم بعد یه ربات اد میشه تو گروه حالا یکی اد میکنه یا از طریق لینک اد میشه.
بعد مدام پیام میده و مزاحمت ایجاد میکنه
من میخواستم با ربات مدیر پیام هاشو بخونم. راهی پیدا کردم که اگه جوین شد حذفش کنم ولی نمیدونم چطوری با لینک وارد میشه؟!
برای همین گفتم اگه پیامی بده شناسایی بشه و حذف بشه چون ممکنه اون موقع ای که جوین میشه سرور قطع بشه و شناسایی نشه.
پس هر وقت که پیامی ارسال کرد شناسایی بشه.
ممنون
در این صورت باید از ربات تلگرام cli استفاده کنید که نحوه ی کد نویسیش و هاستش کاملاً متفاوته اما پیام های ربات ها رو هم می تونه بخونه. ربات های api چنین قابلیتی در حال حاضر ندارن.
برای دریافت پیام ربات تلگرام به علت فیلتر آیا باید وب هوک را به پروکسی گوگل متصل و اطلاعات را چطوری از پروکسی گوگل به php انتقال دهیم؟
برای دریافت پیام از تلگرام در حالت عادی مشکلی وجود نداره مگر اینکه هاست شما آی پی های تلگرام رو بلاک کرده باشه. در اون صورت هم باید از یه پراکسی گوگل (متفاوت از اینکه در مقاله گفتم)، استفاده کنید که اگر نیاز داشتید بفرمایید کد رو اضافه کنم.
ولی اصلا توصیه نمیشه که هم در دریافت پیام هم در ارسال پیام از پراکسی استفاده کنید، چون سرعت ربات به شدت پایین میاد و دیگه کارایی مناسبی نداره. بهتره از هاستی استفاده کنید که آی پی های تلگرام رو بلاک نکرده باشه. و بهتر از اون این هست که از هاست خارجی استفاده کنید که هم دریافت پیام و هم ارسال پیام رو مستقیم انجام بدید.
سلام وقت بخیر میشه لطفا
پراکسی گوگل (متفاوت از اینکه در مقاله بود ) مربوط به پراکسی دریافت پیام به روش وب هوک
را قرار بدید لطفا
سلام. ممنون. وقت شما هم بخیر
پراکسی درخواستی تون رو به انتهای مقاله اضافه کردم.
سلام خسته نباشید واقعا ممنون بابت پاسخگوییتون
ولی یه خطا میده
(Cannot read properties of undefined (reading 'postData
میشه بگین باید چکارش کنم
خواهش می کنم.
کجا این ارور رو می گیرید؟
عالی بود موفق باشید
یلی ممنون بابت آموزش مفیدتون..
راهکاری مشابه برای واتس اپ سراغ دارید؟
خواهش می کنم
خیر در حال حاضر برای واتس اپ راه حل مشابهی نمی شناسم متأسفانه
دمت گرم، کلی از برنامه هامو با این آموزش به بات تلگرم وصل کردم..
ممنون ازت...
خوشحالم که استفاده کردید 🌸
سلام استاد عزیز،
من چند وقت پیش از آموزشتون استفاده کرده بودم و مجدد کلی مرسی.
یه نگاه به این پست بنداز ببین تو میتونی سر در بیاری؟
میشه اسپویلر پیام ارسال کرد؟ من خیلی تست کردم نشد...
من بلد و ایتالیک و ... رو تست کردم و شد ولی اینو نتونستم.... ممنون میشم کمکم کنی استاد عزیز..
سلام وقتتون بخیر
بله میشه ارسال کرد. با این شیوه تست کنید جواب میده:
https://api.telegram.org/bot[token]/sendMessage?chat_id=[chat_id]&text=<tg-spoiler>spoiler<tg-spoiler>&parse_mode=Html
به جای [token] و [chat_id] هم مقادیر مربوطه رو قرار بدید. اگر ارور خاصی دریافت کردید متنش رو بفرستید.
دمت گرم.
نه با همون روش اسکریپتی میخواستم.
ولی میدونی مشکل چی بود؟ تگ اسپویلر با فارسی مشکل داره.
از بک اسکل R و بکاسلش N استفاده کردم و حل شد. ولی بازم مرسی کلی استاد
سلام استاد من برای دکمه های شیشهای به مشکل خوردم..
{"ok":false,"error_code":400,"description":"Bad Request: inline keyboard button URL 'waze://?ll=35.21497563399694,51.733499134380074&navigate=yes' is invalid: Unsupported URL protocol"}
با این خطا مواجه میشم
ولی لینک معمولی میدم کار میکنه..
ممنون میشم کمکم کنی.
سلام. وقت بخیر
طبق مستندات خود تلگرام توی لینک زیر، فقط می تونید آدرس http:// با tg:// برای پارامتر url قرار بدید.https://core.telegram.org/bots/api#inlinekeyboardbutton
سلام، مرسی استاد عزیز.
ولی چقدددد بدددد :((((
سلامزمانی که کاربر پیامی رو برای ربات ارسال میکنه و در جواب بطور مثال میخواهیم بواسطه یک کد php مقداری را از داخل دیتابیس بخونیم و در جواب برای کاربر ارسال کنیم ، جوابی ارسال نمیشه
یعنی تا زمانی که از کد خاصی استفاده نکردیم ، پیام مثلأ خوش آمد ارسال میشه ، اما زمانی که کاری که نیاز داره و ابتدا باید پردازش انجام بشه رو جواب به کاربر بر نمیگردونه
ممنون میشم راهنمایی بفرمائید.
سلام
1- ممکنه یک اروری در اتصال به دیتابیس شما باشه. 2- ممکنه دیتایی که از دیتابیس دریافت کردید به فرمتی باشه که تلگرام نتونه ارسالش کنه یا متن خیلی طولانی ای باشه که از ظرفیت تلگرام بالا تر باشه یا ...
برای مورد اول باید error_log رو بررسی کنید ببینید php اروری در این رابطه تولید کرده یا نه. ممکنه اون جدول خاص وجود نداشته باشه، اشتباه تایپی باشه یا ...
در مورد مشکل دوم باید نتیجه برگردونده شده از درخواست api به تلگرام رو بررسی کنید. اگر از کد curl توی آموزش استفاده می کنید در واقع باید متغیر $result رو چک کنید. می تونید توی کد نویسیتون بنویسید که بعد از ارسال به تلگرام، یکبار دیگه result رو هم به تلگرام شما ارسال کنه.
مثلاً