【问题标题】:Send predefined list of messages to multiple users using pyTelegramBotApi使用 pyTelegramBotApi 向多个用户发送预定义的消息列表
【发布时间】:2021-05-02 07:42:56
【问题描述】:

我必须向多个用户发送多条消息。一些消息应该“等待”,直到用户单击该消息下的按钮。它应该看起来像这样(来自另一个更一般的question):

>>> 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
from config import Config

import telebot

bot = telebot.TeleBot(Config().get_str('test_bot_token'))


users: List[int] = []


@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):
    @bot.callback_query_handler(func=lambda x: 'step_1' in x.data)
    def exec_step_2(query: telebot.types.CallbackQuery):
        bot.edit_message_reply_markup(chat_id=user_id,
                                      message_id=query.message.id,
                                      reply_markup=None)
        step_kb = telebot.types.InlineKeyboardMarkup()
        step_kb.add(telebot.types.InlineKeyboardButton('Yes', callback_data='step_2'))
        bot.send_message(chat_id=user_id,
                         text='Can we continue?',
                         reply_markup=step_kb)
        time.sleep(1.25)

    @bot.callback_query_handler(func=lambda x: 'step_2' in x.data)
    def exec_step_2(query: telebot.types.CallbackQuery):
        bot.edit_message_reply_markup(chat_id=user_id,
                                      message_id=query.message.id,
                                      reply_markup=None)
        step_kb = telebot.types.InlineKeyboardMarkup()
        step_kb.add(telebot.types.InlineKeyboardButton('Of course', callback_data='step_3'))
        bot.send_message(chat_id=user_id,
                         text='That\'s great!',
                         reply_markup=step_kb)
        time.sleep(1.25)

    @bot.callback_query_handler(func=lambda x: 'step_3' in x.data)
    def exec_step_2(query: telebot.types.CallbackQuery):
        bot.edit_message_reply_markup(chat_id=user_id,
                                      message_id=query.message.id,
                                      reply_markup=None)
        bot.send_message(chat_id=user_id,
                         text='See you next time')
        time.sleep(1.25)

    bot.send_message(chat_id=user_id, text='Hello')
    time.sleep(1.25)

    bot.send_message(chat_id=user_id, text='My name is %bot name%')
    time.sleep(1.25)

    kb = telebot.types.InlineKeyboardMarkup()
    kb.add(telebot.types.InlineKeyboardButton(text='Fine', callback_data='step_1'))
    bot.send_message(chat_id=user_id, text='How are you?', reply_markup=kb)


bot.polling()

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

最简单的复制方法:

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

你会得到两个你好,我的名字是%bot name%,你好吗?消息。如果您单击任何按钮 Fine(第一个或第二个),您将在聊天顶部看到 Loading... 消息,并且不会得到任何响应。

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

【问题讨论】:

    标签: python python-multithreading py-telegram-bot-api


    【解决方案1】:

    根据 pyTelegramBotAPI documentation 在 AsyncTeleBot 部分

    您可以使用 async 和 await 使机器人异步工作。

    改变

    import telebot
    

    from telebot.async_telebot import AsyncTeleBot
    import asyncio
    

    并将所有 def 包含的进程代码替换为 async def 示例:

    async def exec_step_2
    

    然后像这样用 await 包装所有 bot.send_message:

    await bot.send_message(chat_id=user_id,text='See you next time')
    

    希望它能解决你的问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-13
      • 2019-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多