В Телеграм есть много разных служебных уведомлений, которые он направляет при наступлении событий при взаимодействии пользователя с ботом, в рамках данной статьи нам будет интересно поработать с теми, которые приходят при начале или при удалении диалога с блокировкой бота.
В любом из указанных событиях приходит объект my_chat_member
в котором есть нужные нам данные пользователя в случае если он подписался или отписался от бота.
Исключение: В случае первого старта бота этот объект не приходит, если пользователь перезапускает ранее удаленного бота, то объект приходит с пометкой old_chat_member->status == "kicked"
{
"chat":{
"id":123456789,
"first_name":"User",
"type":"private"
},
"from":{
"id":123456789,
"is_bot":false,
"first_name":"User",
"language_code":"ru"
},
"date":1685526728,
"old_chat_member":{
"user":{
"id":987654321,
"is_bot":true,
"first_name":"Bot",
"username":"Bot_bot"
},
"status":"kicked",
"until_date":0
},
"new_chat_member":{
"user":{
"id":987654321,
"is_bot":true,
"first_name":"Bot",
"username":"Bot_bot"
},
"status":"member"
}
}
При получении этих уведомлений достаточно проверить свойство объекта my_chat_member->new_chat_member->status
в случае если оно равно "member"
, то это активный пользователь, если же оно равно "kicked"
, то это удаление бота с блокировкой.
Что делать при том или ином варианте, зависит от логики вашего приложения. Например если пользователь удаляет и блокирует бот, то можно в базе данных такому пользователю ставить флаг "неактивен", чтобы не тратить на него ресурсы при рассылке сообщений.
Пример получения таких служебных уведомлений:
// токен бота
$token_bot = "903520000:A___________LnysLjuXLXfuZmIqjpVrg";
// получим данные из телеграм
$data = json_decode(file_get_contents("php://input"), false);
// получим id бота
$bot_id = explode(":", $token_bot)[0];
// проверим это объект начала диалога с ботом или удаление бота
if (isset($data->my_chat_member)) {
// можно дополнительно проверить на id бота
// но это излишнее условие, можно этого не делать - тк от другого бота это не придет
if($data->my_chat_member->new_chat_member->user->id == $bot_id) {
// получим объект пользователя
$user = $data->my_chat_member->from;
// если это начало диалога
if($data->my_chat_member->new_chat_member->status == "member") {
// здесь можно добавить пользователя в базу, или "активизировать"
set("Active: " . json_encode($user));
// ...
}
// если это удаление бота
else if($data->my_chat_member->new_chat_member->status == "kicked") {
// здесь можно удалить пользователя из базу или поставить флаг "неактивности"
set("UnActive: " . json_encode($user));
// ...
}
}
}
/** Вспомогательная функция для записи данных в файл
* @param $data
*/
function set($data) {
// откроем файл на запись, если его нет создадим
$fh = fopen("./data.txt", 'a');
// запишем данные в файл
fwrite($fh, $data . "\n==================================\n");
// закроем файл
fclose($fh);
}
Альтернативный способ проверки
При взаимодействии с пользователем, бот направляет запросы на выполнение каких-либо действий, и в ответ всегда получает объект с информацией об успешности выполнения запроса с дополнительными вспомогательными данными.
// пример ответа на запрос
{
"ok":true,
"result":true
}
// пример ответа на запрос при блокировке бота
{
"ok":false,
"error_code":403,
"description":"Forbidden: bot was blocked by the user"
}
Можно направить безобидный (незаметно для пользователя) запрос на передачу действия бота через метод sendChatAction
например typing
, если пользователь не заблокировал бота, даже если он при этом удалил чат с ботом, в ответ придет положительный ответ.
echo file_get_contents("https://api.telegram.org/bot<TOKENBOT>/sendChatAction?chat_id=<CHATID>&action=typing");
В зависимости от ответа можно сделать пометку в базе данных пользователю: "активный" или "неактивный".
Если у вас есть еще примеры, просьба написать в комментариях - думаю дополнительный опыт будет только плюсом.
Откройте по ссылке или QR бот @iMakeBot, нажмите кнопку Старт/Start.
Следуйте инструкциям бота.