F
F
Frag0S2018-05-15 13:20:56
Bots
Frag0S, 2018-05-15 13:20:56

State machine, what's wrong?

Good afternoon, I'm trying to implement a state machine to track the user's position. When I try to run it, it gives an error name 'STATE_DICT' is not defined, tell me how to fix it

import config
import telebot

bot = telebot.TeleBot(config.token)


@bot.message_handler(commands=['start'])
def start(message):
  key = telebot.types.ReplyKeyboardMarkup(True,False)
  key.row("кнопка1")
  key.row("кнопка2")
  bot.send_message(message.chat.id, "Выберите пункт меню:", reply_markup=key)


@bot.message_handler(func=lambda mess: "кнопка1" == mess.text, content_types=['text'])
def handle_text(message):
  key = telebot.types.ReplyKeyboardMarkup(True, False)
  key.row("кнопка5")
  key.row("назад")
  chat_id = message.chat.id
  STATE_DICT[chat_id] = '1'
  bot.send_message(message.chat.id, "Выбери кнопку", reply_markup=key)

@bot.message_handler(func=lambda mess: "кнопка2" == mess.text, content_types=['text'])
def handle_text(message):
  key = telebot.types.ReplyKeyboardMarkup(True, False)
  key.row("кнопка7")
  key.row("назад")
  bot.send_message(message.chat.id, "Выбери кнопку", reply_markup=key)


@bot.message_handler(unc=lambda mess: "назад" == mess.text, content_types=['text'])
def start_finite_machine(message):
  if STATE_DICT[chat.id] == '1':
    start(message)

if __name__ == '__main__':
  bot.polling(none_stop=True)

I followed the example How to make the output correct when a button is pressed in a telegram bot in Python?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
Ranc58, 2018-05-15
@Frag0S

You did not declare STATE_DICT )
In your case:

import config
import telebot

bot = telebot.TeleBot(config.token)
STATE_DICT = {}

In the second it is not necessary to handle everywhere. For this, you need a state machine - it monitors the state and switches to the desired function itself.
Below is a complete example. Should work (I'm not sure because I wrote it from memory, but the logic is correct)
import config
import telebot
from telebot import types

bot = telebot.TeleBot(config.token)
STATE_DICT = {}


@bot.message_handler(commands=['start'])
def start(message):
    markup = types.ReplyKeyboardMarkup(
        one_time_keyboard=False,
        resize_keyboard=True
    )
    markup.add('Кнопка1')
    markup.add('Кнопка2')
    question = 'Выбери'
    chat_id = message.chat.id
    STATE_DICT[chat_id] = 'START'
    bot.send_message(chat_id, question, reply_markup=markup)


def start_work(message):
    chat_id = message.chat.id
    markup = types.ReplyKeyboardMarkup(
        one_time_keyboard=False,
        resize_keyboard=True
    )
    if message.text == 'Кнопка1':
        STATE_DICT[chat_id] = 'VAR1'
        markup.add('Кнопка3')
        markup.add('Кнопка4')
        bot.send_message(chat_id, 'Вы выбрали ответ 1', reply_markup=markup)
    else:
        STATE_DICT[chat_id] = 'VAR2'
        markup.add('Кнопка5')
        markup.add('Кнопка6')
        bot.send_message(chat_id, 'Вы выбрали ответ 2', reply_markup=markup)


def var1(message):
    chat_id = message.chat.id
    if message.text == 'Кнопка3':
        bot.send_message(chat_id, 'Конец с кнопкой3')
    else:
        STATE_DICT[chat_id] = 'VAR2'
        bot.send_message(chat_id, 'Конец с кнопкой2')


def var2(message):
    chat_id = message.chat.id
    if message.text == 'Кнопка5':
        bot.send_message(chat_id, 'Конец с кнопкой5')
    else:
        STATE_DICT[chat_id] = 'VAR2'
        bot.send_message(chat_id, 'Конец с кнопкой6')


@bot.message_handler(func=lambda message: True)
def start_finite_machine(message):
    states = {
        'START': start_work,
        'VAR1':  var1,
        'VAR2':  var2,
    }
    chat_id = message.chat.id
    states[STATE_DICT[chat_id]](message)


if __name__ == '__main__':
  bot.polling(none_stop=True)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question