0

我正在开发一个带有 FSM 的电报机器人。它应该是用于订购披萨的聊天机器人。对话应该是这样的:

  • 你想要什么样的披萨?大或小?
  • 伟大的
  • 你将如何付款?
  • 用现金
  • 你想要一个大披萨,现金付款吗?
  • 是的
  • 谢谢你的订单

我有这个代码:

僵尸软件

import telebot
import config
import FSM

from telebot import types

bot = telebot.TeleBot(config.TOKEN)
fsm = FSM.TelegramBot()

@bot.message_handler(commands=['start'])
def welcome(message):

    #keyboard
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
    item1 = types.KeyboardButton("Заказать пиццу")
    item2 = types.KeyboardButton("Посмотреть меню")

    markup.add(item1, item2)

    bot.send_message(message.chat.id,
                     "Добро пожаловать, {0.first_name}!\nЯ - <b>{1.first_name}</b> бот, я помогу вам "
                     "сделать заказ.".format(
                         message.from_user, bot.get_me()),
                     parse_mode='html', reply_markup=markup)


@bot.message_handler(content_types=['text'])
@bot.message_handler(func=lambda message: fsm.state == 'asleep')
def order_pizza(message):
    bot.send_message(message.chat.id, 'Какую вы хотите пиццу? Большую или маленькую?')
    fsm.asked_for_payment_method(message.text)




@bot.message_handler(content_types=['text'])
@bot.message_handler(func=lambda message: fsm.state == 'size_selected')
def choose_size(message):
    bot.send_message(message.chat.id, 'Как вы будете платить?')
    fsm.asked_for_payment_method(message.text)

@bot.message_handler(content_types=['text'])
@bot.message_handler(func=lambda message: fsm.state == 'payment_selected')
def choose_size(message):
    bot.send_message(message.chat.id, 'Какой вкус вы хотите?')
    fsm.asked_for_flavour(message.text)
@bot.message_handler(content_types=['text'])
@bot.message_handler(func=lambda message: fsm.state == 'flavour_selected')
def choose_size(message):
    markup = types.InlineKeyboardMarkup(row_width=2)
    item1 = types.InlineKeyboardButton("Да", callback_data='yes')
    item2 = types.InlineKeyboardButton("Нет ", callback_data='no')
    markup.add(item1, item2)

    bot.send_message(message.chat.id, f'Вы хотите {fsm.size} пиццу {fsm.flavour}, оплата - {fsm.pay_method} ?', reply_markup=markup)





@bot.callback_query_handler(func=lambda call: True)
def callback_inline(call):
    try:
        if call.message:
            if call.data == 'yes':
                bot.send_message(call.message.chat.id, 'Спасибо за заказ')
                fsm.confirmed()
                # show alert
                bot.answer_callback_query(callback_query_id=call.id, show_alert=True,
                                          text="Заказ оформлен")
            elif call.data == 'no':
                markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
                item1 = types.KeyboardButton("Заказать пиццу")
                item2 = types.KeyboardButton("Посмотреть меню")

                markup.add(item1, item2)

                bot.send_message(call.message.chat.id, 'Бывает ', reply_markup=markup)
                fsm.confirmed()

            # remove inline buttons
            bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text=f'Вы хотите {fsm.size} пицца {fsm.flavour}, оплата - {fsm.pay_method} ?',
                                  reply_markup=None)



    except Exception as e:
        print(repr(e))


# RUN
bot.polling(none_stop=True)

而这个有限状态机的代码。我用过pytransitions/transitions

FSM.py

from transitions import Machine, State


class telegram_bot_state(object):

    states = ['asleep',
              'size_selected',
              'payment_selected',
              'flavour_selected']

    transitions = [
        {'trigger': 'asked_size', 'source': 'asleep', 'dest': 'size_selected', 'after': 'update_size'},
        {'trigger': 'asked_for_payment_method', 'source': 'size_selected', 'dest': 'payment_selected', 'after': 'update_payment'},
        {'trigger': 'asked_for_flavour', 'source': 'payment_selected', 'dest': 'flavour_selected','after': 'update_flavour'},
        {'trigger': 'confirmed', 'source': 'flavour_selected', 'dest': 'asleep'}, ]

    def __init__(self):
        self.size = ''
        self.pay_method = ''
        self.flavour = ''
        self.machine = Machine(model=self, states=TelegramBot.states, transitions=TelegramBot.transitions, initial='asleep')

    def update_size(self, msg):
        self.size = msg
        print(f'размер задан: {self.size}')


    def update_payment(self, msg):
        self.pay_method = msg
        print(f'способ оплаты задан: {self.pay_method}')


    def update_flavour(self, msg):
        self.flavour = msg
        print(f'Вкус пиццы задан: {self.flavour}')

但问题是它只是贯穿所有内容,而不是等待用户的回答。只需发送所有的questin。

ps如果写错了,我很抱歉这是我的第一个问题。

4

0 回答 0