代码之家  ›  专栏  ›  技术社区  ›  feeeper

使用PytegrambotAPI向多个用户发送预定义的消息列表

  •  0
  • feeeper  · 技术社区  · 3 年前

    我必须向多个用户发送多条消息。一些消息应该“等待”,直到用户点击该消息下的按钮。看起来应该是这样(从另一个更一般的角度来看) 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()
    
    

    当多个用户连接到bot时,就会出现问题。第一个用户得到了完整的管道,但第二个用户没有得到任何消息。

    最简单的复制方法:

    1. 不要启动机器人
    2. 邮寄 /start 对机器人的命令
    3. 派两个 exec 发送给机器人的消息
    4. 启动机器人

    你会得到两个你好,我叫%bot name%,你好吗?信息。如果你点击任何按钮 Fine (第一或第二)你会看到的 Loading... 消息出现在聊天室的顶部,不会得到任何回应。

    但是如果你送 /开始 命令和单一 执行官 一切都会好起来的。

    0 回复  |  直到 3 年前
        1
  •  0
  •   hawe25    2 年前

    根据Pyapi documentation 关于Telebot部分

    可以使用async和Wait使bot异步工作。

    改变

    import telebot
    

    from telebot.async_telebot import AsyncTeleBot
    import asyncio
    

    并替换所有 def 包含带有 async def 例子:

    async def exec_step_2
    

    然后把所有机器人都包起来。通过如下方式发送消息:

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

    希望它能解决你的问题