【问题标题】:Trying to delete "left_chat_member" messages with a Telegram Bot尝试使用 Telegram Bot 删除“left_chat_member”消息
【发布时间】:2018-11-27 17:49:00
【问题描述】:

我正在尝试使用 Telegram Bot 执行以下操作:

user.first_name 匹配正则表达式时:

  1. 删除“加入”消息。
  2. 将用户踢出聊天。
  3. 删除“左”消息。

问题是我不知道如何获取“左”消息的message.id,因为:

  1. KickChatMember 方法不返回消息对象,仅返回 truefalse
  2. 包含left_chat_member 的已发送消息将user.from 设置为踢球的成员(在本例中为机器人本身)。
  3. 机器人无法接收自己消息的更新,因此不会收到之前的消息。

所以问题是:

bot 自身发送的包含left_chat_member 的消息是否可以获得message.id?有没有其他方法可以做到这一点?

也许我可以尝试推断message.id,但我不知道这是否可行或推荐。

【问题讨论】:

  • 甚至没有在“启用”中设置“setprivacy”出现该消息(我也是这样)
  • 这可能是一个错误,文档说“所有机器人,无论设置如何,都会收到:所有服务消息。” core.telegram.org/bots/faq#what-messages-will-my-bot-get(但它不起作用)

标签: bots telegram telegram-bot


【解决方案1】:

在 NodeJs 中试试这个代码

let TelegramBot = require('node-telegram-bot-api');
let bot = new TelegramBot(token, {polling: true});
let regex = 'givenUser';  /* Part of the user first name that you wanna kick him out*/

    bot.on('new_chat_members', (data) => newMembers(data));
    bot.on('left_chat_member', (data) => leftMember(data));

    function newMembers(data) {
        let chatId = data.chat.id;
        let msgId = data.message_id;
        let userId = data.new_chat_member.id; 
        let firstName = data.new_chat_member.first_name;
        if (firstName.includes(regex)) {
            bot.deleteMessage(chatId, msgId).catch(e => console.log(e));
            bot.kickChatMember(chatId, userId).catch(e => console.log(e));
        }
}

function leftMember(data) {
    let chatId = data.chat.id;
    let msgId = data.message_id;
    let firstName = data.left_chat_member.first_name;
    if (firstName.includes(regex)) {
        bot.deleteMessage(chatId, msgId).catch(e => console.log(e));
    }
}

【讨论】:

    【解决方案2】:

    与@eyaadh 在https://t.me/BotTalk 的对话中得出的一个可能的近似值是:

    1. new_chat_members 发生时,您有一个message_id(比如说A
    2. 执行kick_chat_member(缺少message_id
    3. 并发送了一条消息(任意),你有一个message_id(比如说B

    (第一步是可选的)

    kick_chat_member产生的消息是B-1,中间有另一条消息进入的可能性很小,如果代码中必须将第2步和第3步放在一起,以尽可能减少之间的时间他们。

    A 消息用于知道最小的 id。换句话说,有问题的 id 在AB 之间(保证)。如果A + 2 等于B,则消息是B-1(或A+1)保证的。否则就无法确定。

    在我看来,left_chat_member 应该将消息发送给生成输出的机器人,这样问题就会得到解决,或者 kick_chat_member 的执行应该返回该信息。


    解决方案

    在管理它的函数中启动new_chat_members 时,可以执行以下操作(将使用三个ID,id1id2id3):

    • id1是加入消息的标识符(new_chat_members自带的那个)。

    • 然后执行kick_chat_member(这会生成ID未知的消息id2)。

    • (如果用户被删除)任何使用sendMessage 发送的消息都会给我们id3

    然后我们从id3 - 1循环到id1 + 1(包括两者):对于这个循环中的每个id,我们发送一个带有sendMessage的“响应消息”(在reply_to_message_id参数中使用循环的id ) 并且我们检查生成的消息是否在其参数reply_to_message.left_chat_member 中包含我们要删除的用户的 id,如果是肯定的,则它是我们要消除的消息(消除,它是 id2),在循环结束时,我们也会消除“响应消息”(每个步骤循环的 id)。

    当 for 循环结束时,我们消除带有 id1id3 的消息。

    通过这种方式,输入和输出(被踢)消息完全确定地被消除,无论其间是否出现其他消息。

    我通过在机器人中的每个动作和在组中写入之间等待 3 秒来测试它(机器人一步一步地进行)。


    Python 示例

    https://github.com/schcriher/welcome-tg-bot/commit/0e4dbaa9cbff5272d682899b1433ff2b3c750a74


    总结:从id3 - 1id1 + 1的所有消息都被回答(回复),并搜索包含left_chat_member的用户ID已被踢。


    更新

    现在机器人在踢出成员时会收到服务消息。分析退出消息是否是bot发出的就足够了,如果是,那就是对bot成员的踢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      • 2016-09-29
      • 2023-01-18
      • 1970-01-01
      • 1970-01-01
      • 2018-12-18
      • 2017-08-07
      相关资源
      最近更新 更多