How can I detect whether a user deletes the Telegram Bot chat?
Asked Answered
D

6

17

Is it possible to check, via an API, whether somebody has deleted the Bot Chat in Telegram?

My test : Currently if a user deletes a chat, new messages will not stop sending to user.

Drying answered 8/2, 2016 at 6:32 Comment(0)
R
20

Nope. Only by getting error while sending user something.

Even calling sendChatAction method does not return error if user blocked the chat:

$ curl https://api.telegram.org/bot***/sendChatAction -d 'chat_id=7975895' -d "action=typing"
{"ok":true,"result":true}
$ curl https://api.telegram.org/bot***/sendMessage -d 'chat_id=81083738' -d "text=ololo"
{"ok":false,"error_code":403,"description":"[Error]: Bot was blocked by the user"}
Radbun answered 8/2, 2016 at 8:30 Comment(5)
Thank you, Any idea about my test?Drying
You may continue sending messages, with the hope of user will unblock your bot.Radbun
It seems that after delete a chat it takes a few minutes to propagate it to all serversDrying
I can state that sendChatAction is perfect for this and correctly returns if the user blocked the bot and even if he deleted the account. Check my answer in this question post.Mesh
I noticed that such exception happened if user Stop Bot, but if only delete there is no any exceptionsRyun
M
14

Someone in other answers suggested to use getChat method.

Do not use it for two reasons:

  • even if they can return some special errors, they can change at anytime. Instead, any send method should safe! (This is the answer I got contacting the official support months ago)
  • from my usage I know that getChat results can be cached for a lot of weeks and you won’t have a safe result. i.e. I was able to get regular results of groups using getChat even after a month they kicked the bot from the group.

So what can you do? You can use send methods and I would suggest you to use sendChatAction so you won’t bother users.

You can handle exceptions and check the code of the error returned (403 is the error for this case). Furthermore at the moment I write this answer if the user blocked the bot the returned string contains the word “blocked”, while if he deleted the account the string contains the word “deactivated”.

For example for my bot I developed a function that is automatically runned on intervals, it has a for loop and try to sendChatAction to every users. I check the code of the error (403 is for this) and I check the text of the error. If it contains “blocked” I just mark the user as blocked in the database because I want to keep preferences, otherwise if it contains “deactivated“ I delete the user from the database. I did this to have stats about how many users my bot has and how many of them didn’t block the bot. If you want to do something like this also remember to add a sleep in the for loop because you can use only 30 sendChatAction per second before of hitting limits.

Mesh answered 4/10, 2017 at 4:33 Comment(2)
For me sendChatAction return exception for blocked bot only, for deleted bot it returns true for all actions. It may mean the API was changed from this time.Cleasta
Can you post full "deactivated" error? I wish I could separate deleted users, but there is none information on the internet of how deleted user error look.Graybeard
N
6

This Resolved by new telegram update:

March 9, 2021 Bot API 5.1

Added two new update types

Added updates about member status changes in chats, represented by the class ChatMemberUpdated and the fields my_chat_member and chat_member in the Update class. The bot must be an administrator in the chat to receive chat_member updates about other chat members. By default, only my_chat_member updates about the bot itself are received.

Change log link : https://core.telegram.org/bots/api#march-9-2021

Neckwear answered 19/3, 2021 at 1:7 Comment(0)
C
1

You can get getChat method (https://core.telegram.org/bots/api#getchat). If user stop and block bot, this method return 403 status

Cry answered 3/10, 2017 at 22:0 Comment(1)
This is not correct. You will still receive the chat data.Nightwalker
S
1

I am using telegraf. Whenever I block my bot, I receive the following update:

{
  "update_id": 298643739,
  "my_chat_member": {
    "chat": {
      "id": 402824801,
      "first_name": "foo",
      "last_name": "bar",
      "username": "xyz",
      "type": "private"
    },
    "from": {
      "id": 402824801,
      "is_bot": false,
      "first_name": "foo",
      "last_name": "bar",
      "username": "xyz",
      "language_code": "en"
    },
    "date": 1694342565,
    "old_chat_member": {
      "user": {
        "id": 6344939925,
        "is_bot": true,
        "first_name": "bot",
        "username": "bot_bot"
      },
      "status": "member"
    },
    "new_chat_member": {
      "user": {
        "id": 6344939925,
        "is_bot": true,
        "first_name": "bot",
        "username": "bot_bot"
      },
      "status": "kicked",
      "until_date": 0
    }
  }
}

I didn't understand which message filter should I sue, so I wrote a middleware to act on bot being blocked:

import { deunionize } from 'telegraf';
import { userRepository } from '../repositories/user';
import { CustomContext } from '../types/Context';
import { logger } from '../utils/logger';

/**
 * Tracks bot being blocked
 */
export const blockMiddleware = async (ctx: CustomContext, next: any) => {
  try {
    if (!ctx.user) return next();
    const update = deunionize(ctx.update);
    if (!update.my_chat_member) return next();
    const isKicked = update.my_chat_member.new_chat_member.status === 'kicked';
    const isThisBot = update.my_chat_member.new_chat_member.user.id === ctx.botInfo.id;

    if (isKicked && isThisBot) {
      await userRepository.updateOne(ctx.user.telegram_id, { blocked: true });
    }

    return next();
  } catch (error) {
    logger.error(`Block middleware failed for ${JSON.stringify(ctx.from)} ${error?.message || error.stack}`);
  }
};

Synergetic answered 15/9, 2023 at 12:35 Comment(0)
I
0

As of today Mar 2024, telegram will return such object if you trigger their sendChatAction endpoint, for users who have you blocked. So, @ihoru's answer is no longer valid.

$ curl https://api.telegram.org/bot***/sendChatAction -d 'chat_id=7975895' -d "action=typing"
{'ok': False, 'error_code': 403, 'description': 'Forbidden: bot was blocked by the user'}
Imperfective answered 9/3 at 19:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.