使用 pyTelegramBotApi 向多个用户发送消息链

问题描述

我必须向多个用户发送消息链。其中一些按钮应该冻结消息发送(一种确认):

>>> bot: 'Hello'
>>> bot: 'My name is %bot name%'
>>> bot: 'How are you?'
<<< button: 'Fine'  # <-- this is button. Any message should not to be sent before the user clicks `Fine` button
>>> bot: 'Can we continue?'  # <-- this message shows only after user clicks `Fine` button
<<< button: 'Yes'  # <-- this is button. Any message should not to be sent before the user clicks `Yes` button
>>> bot: 'That\'s great!'  # <-- this message shows only after user clicks `Yes` button
<<< button: 'Of course'  # <-- this is button. Any message should not to be sent before the user clicks `Of course` button
>>> bot: 'See you next time'  # <-- this message shows only after user clicks `Yes` button

我有很多带有多个按钮的类似管道,我可以做什么功能/类可以做到这一点。

最小工作示例:

import time
from dataclasses import dataclass
from typing import Any,Dict,List

import telebot

token = '%TELEGRAM_BottOKEN%'

bot = telebot.TeleBot(token)


users: List[int] = []


class MessageTypes:
    INFO_MESSAGE = 0
    BASIC_MESSAGE_WITH_BUTTON = 1


@dataclass
class Message:
    text: str
    message_type: int
    params: Dict[str,Any]


@bot.message_handler(commands=['start'])
def _start(message: telebot.types.Message):
    users.append(message.chat.id)


@bot.message_handler(func=lambda x: 'exec' in x.text)
def _send_message(message: telebot.types.Message):
    for i,user in enumerate(users):
        try:
            _send_message_to_user(user)
        except telebot.apihelper.ApiTelegramException as telegramEx:
            print(f'chat_id:{user}\t{telegramEx}')


def _send_message_to_user(user_id: int):
    send_next = True

    @bot.callback_query_handler(func=lambda q: q.data == 'messages')
    def __clear_reply_markup(query: telebot.types.CallbackQuery):
        bot.edit_message_reply_markup(chat_id=query.message.chat.id,message_id=query.message.id,reply_markup=None)
        nonlocal send_next
        send_next = True

    def __send_message(msg):
        if msg.message_type == MessageTypes.INFO_MESSAGE:
            return bot.send_message(user_id,msg.text,parse_mode='HTML')
        elif msg.message_type == MessageTypes.BASIC_MESSAGE_WITH_BUTTON:
            kb = telebot.types.InlineKeyboardMarkup()
            kb.add(telebot.types.InlineKeyboardButton(text=msg.params['buttons'][0]['text'],callback_data='messages'))

            nonlocal send_next
            send_next = False

            return bot.send_message(chat_id=user_id,text=msg.text,parse_mode='HTML',reply_markup=kb)

    def _message_generator():
        while i < len(messages):
            msg = yield
            time.sleep(1.25)

            __send_message(msg)

    messages = [
        Message('Hello',{}),Message('My name is %bot name%',Message('How are you?',1,{'buttons': [{'text': 'Fine'}]}),Message('Can we continue?',{'buttons': [{'text': 'Yes'}]}),Message('That\'s great!',{'buttons': [{'text': 'Of course'}]}),Message('See you next time',]

    i = 0
    mg = _message_generator()
    next(mg)
    while i < len(messages):
        if send_next:
            mg.send(messages[i])
            i += 1
            if i == len(messages):
                mg.close()


bot.polling()

当多个用户附加到机器人时会出现问题。第一个用户获得完整的管道,但第二个 - 没有收到任何消息。

最简单的复制方法

  1. 不要启动机器人
  2. 向机器人发送 /start 命令
  3. 向机器人发送两条 exec 消息
  4. 启动机器人

您将收到两条 HelloMy name is %bot name%How are you? 消息。如果您点击任何按钮 Fine(第一个或第二个),您将在聊天顶部看到 Loading... 消息,但不会收到任何回复

但如果您发送 /start 命令和单个 exec 消息,一切都会正常。

看起来我对生成器的态度是正确的,但不知道如何避免这种行为。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...