Telegram移动学习机器人未等待就绪条件即批量发送内容求助
Hey there! The core issue here is that your current code runs synchronously—it sends the video and immediately fires off the quiz without pausing to check for user input. You need to add session state management to track where each user is in the workflow (e.g., "sent video, waiting for ready signal").
Here's how to fix this step by step:
1. Add a User State Column to Your MySQL Database
First, update your user table to store the current state of each user's interaction. This keeps state persistent even if your bot restarts:
ALTER TABLE your_users_table ADD COLUMN user_state VARCHAR(20) DEFAULT 'idle'; -- Possible states: 'idle' (ready to start), 'waiting_for_ready' (sent video, waiting for user), 'quiz_completed'
2. Rewrite the handle(msg) Logic to Respect State
Modify your handler to check the user's state before taking action, and update the state as the workflow progresses. Here's how to adapt your existing code:
def handle(msg): chat_id = msg['chat']['id'] content_type = msg.get('content_type') command = msg["text"].strip().lower() if content_type == 'text' else '' # Fetch current user state from MySQL cursor.execute("SELECT user_state FROM your_users_table WHERE chat_id = %s", (chat_id,)) user_state = cursor.fetchone() if not user_state: # If user is new, initialize state to idle cursor.execute("INSERT INTO your_users_table (chat_id, user_state) VALUES (%s, 'idle')", (chat_id,)) db.commit() user_state = 'idle' else: user_state = user_state[0] # Handle different states if content_type == 'text' and chat_id in list1: if command == "hi" and user_state == 'idle': # Send video first video_link = get_fast_video_link_from_db() # Your existing function bot.sendVideo(chat_id, video=video_link) # Update state to waiting for user's ready signal cursor.execute("UPDATE your_users_table SET user_state = 'waiting_for_ready' WHERE chat_id = %s", (chat_id,)) db.commit() bot.sendMessage(chat_id, "Let me know when you're ready to take the quiz!") elif command in ["ready", "im ready", "start quiz"] and user_state == 'waiting_for_ready': # User is ready, send quiz quiz_content = get_quiz_from_db() # Your existing function to fetch quiz bot.sendMessage(chat_id, quiz_content) # Update state to quiz sent cursor.execute("UPDATE your_users_table SET user_state = 'quiz_completed' WHERE chat_id = %s", (chat_id,)) db.commit() elif user_state == 'waiting_for_ready': # User sent something else before confirming ready bot.sendMessage(chat_id, "I'm waiting for you to say 'ready' when you're done with the video!") else: # Default prompt if state is idle or quiz completed bot.sendMessage(chat_id, "Say hi to see your options")
3. Key Notes to Avoid Future Issues
- State Persistence: Using MySQL ensures that if your bot restarts, users won't lose their place in the workflow.
- Flexible Commands: I added multiple possible "ready" commands—you can expand this list based on what makes sense for your users.
- Error Handling: Add try/except blocks around database operations to catch connection issues or query errors.
This approach makes your bot interactive and follows the "video → wait for ready → send quiz" flow you intended.
内容的提问来源于stack exchange,提问作者Rohan Ajmani

