Нужно чтобы бот вводил данные в файл. В файле пишется

Бот создан для регистрации на мероприятие с выдачей штрих-кода.
Как сделать так чтобы бот вводил данные из переменных в файл, а не <function fio at 0x> Как из функции вписать сообщение пользователя в файл?

Код:

import os
import requests
import telebot
from telebot import types
from telebot.types import

bot = telebot.TeleBot('');


def init_file():  
    if not os.path.exists('users.txt'):
        with open('users.txt', 'w'):
            pass


def add_user(data: str, ifio: str, inumber: str, imail: str, iorg_num: str, iorg: str,) -> bool:
    with open('users.txt', 'r') as f:
        users = f.read().splitlines()  

    with open('users.txt', 'a') as f:
        f.write(f'{data} {ifio} {inumber} {imail} {iorg_num} {iorg}\n')  
    return True

@bot.message_handler(commands=['start'])
def start(message):
    bot.send_message(message.chat.id, 'Добро пожаловать! Зарегистрируйтесь на мероприятие.')
    Vfio = bot.send_message(message.chat.id, "Ваше ФИО: ")
    bot.register_next_step_handler(Vfio, fio)

def fio(message1):
    ifio = message1.text
    Vnumber = bot.send_message(message1.chat.id, "Ваш номер телефона: ")
    bot.register_next_step_handler(Vnumber, number)
    return ifio

def number(message2):
    inumber = message2.text
    Vmail = bot.send_message(message2.chat.id, "Ваша почта: ")
    bot.register_next_step_handler(Vmail, mail)
    return inumber

def mail(message3):
    imail = message3.text
    Vorg = bot.send_message(message4.chat.id, '''Ваша организация: ''')
    bot.register_next_step_handler(Vorg, org_num)
    return imail

def org(message5):
    iorg = message5.text
    return iorg

    result = add_user(data, ifio, inumber, imail, iorg)  
    bot.send_message(message6.chat.id, 'Регистрация прошла успешно!')
    return

bot.polling(none_stop=True, interval=0)

Ответы (1 шт):

Автор решения: Amgarak
  • Проверку на наличие файла можно сделать сразу при старте скрипта.
  • Возвращать ничего через return в функциях fio, number и т.д. не нужно!
  • Если посмотреть docstring метода register_next_step_handler то можно увидеть, что помимо обязательных атрибутов message и callback можно передать произвольные атрибуты args и kwargs.
  • Не страдаем велосипедостраительством, а просто протягиваем через все шаги свой словарь\список, где уже будем запоминать ответы пользователя.
  • Так же посмотрите в сторону машины состояний: вместо протягивания своего атрибута между шагами, можно использовать словарь с ключами user.id где уже под каждым ключом конкретного юзера хранить все его введенные ответы в словаре\списке.
  • Не плохо бы еще добавить валидацию ответов, и повторный запрос "плохих" ответов.

В качестве примера, я организовал проброс словаря между шагами, но вы можете рассмотреть и альтернативный вариант с машиной состояний:

import os
import telebot
from datetime import datetime

bot = telebot.TeleBot("TOKEN")

if not os.path.exists("users.txt"):
    with open("users.txt", "w", encoding="utf-8") as f:
        f.write("Дата | ФИО | Телефон | Почта | Организация\n")


def add_user(data: dict) -> None:
    current_time = datetime.now().strftime("%d.%m.%Y %H:%M")
    record = (
        f"{current_time} | "
        f"{data.get('fio', 'Н/Д')} | "
        f"{data.get('phone', 'Н/Д')} | "
        f"{data.get('email', 'Н/Д')} | "
        f"{data.get('org', 'Н/Д')}\n"
    )

    with open("users.txt", "a", encoding="utf-8") as f:
        f.write(record)


def format_data(data: dict) -> str:
    return (
        f"ФИО: {data['fio']}\n"
        f"Телефон: {data['phone']}\n"
        f"Email: {data['email']}\n"
        f"Организация: {data['org']}"
    )


@bot.message_handler(commands=["start"])
def start(message):
    bot.send_message(
        message.chat.id, "Добро пожаловать! Зарегистрируйтесь на мероприятие."
    )
    bot.send_message(message.chat.id, "Введите ваше ФИО:")
    bot.register_next_step_handler(message, fio, data={})


def fio(message, data):
    data["fio"] = message.text.strip()
    bot.send_message(message.chat.id, "Введите свой номер телефона:")
    bot.register_next_step_handler(message, phone, data=data)


def phone(message, data):
    data["phone"] = message.text.strip()
    bot.send_message(message.chat.id, "Введите свой email:")
    bot.register_next_step_handler(message, email, data=data)


def email(message, data):
    data["email"] = message.text.strip()
    bot.send_message(message.chat.id, "Введите название вашей организации:")
    bot.register_next_step_handler(message, org, data=data)


def org(message, data):
    data["org"] = message.text.strip()
    add_user(data)

    bot.send_message(message.chat.id, "Регистрация прошла успешно!")
    bot.send_message(message.chat.id, f"Ваши данные сохранены:\n{format_data(data)}")


bot.polling(none_stop=True)

Пример с машиной состояний:

user_data = {}  # Keys = user_id, values = {"fio": fio, "phone": phone, и т.д..}

@bot.message_handler(commands=["start"])
def start(message):
    user_id = message.from_user.id
    user_data[user_id] = {}  
    bot.send_message(
        message.chat.id, "Добро пожаловать! Зарегистрируйтесь на мероприятие."
    )
    bot.send_message(message.chat.id, "Введите ваше ФИО:")
    bot.register_next_step_handler(message, fio)

def fio(message):
    user_id = message.from_user.id
    user_data[user_id]["fio"] = message.text.strip()
    bot.send_message(message.chat.id, "Введите свой номер телефона:")
    bot.register_next_step_handler(message, phone)

# И т.д..

введите сюда описание изображения введите сюда описание изображения

→ Ссылка