Бот должен отправить сообщение из беседы пользователю, как это сделать?
Нужно написать бота, который собирает информацию о «заказе», отправляет одним сообщением всю информацию в группу с админами, прикрепляя кнопки с вариантами ответа админов (на фото реализация), а админы отправляют путём этих кнопок ответ обратно пользователю.
Как организовать ответ админов пользователю? При нажатии на кнопку, текст с кнопки должен отправиться пользователю через бота.
Попробовала через forward.message, все работает только для меня (так как я являюсь админом беседы). Если приходят данные с другого телеграмм-аккаунта, при нажатии на кнопку в беседе админов мною ответ приходит не другому пользователю, а мне
Добавила фрагмент обработки сообщения, если приходит ссылка. На питоне пишу впервые, так что прошу строго не судить, стараюсь собирать код с помощью разных подсказок форумов и гитхаба :D
Запуталась, прошу помочь :( Спасибо!
То есть бот работает так: пользователь ведет с ботом диалог, собирается информация, которая отправляется ботом в беседу с админами, затем админы нажимают на кнопку и пользователю должен вернуть их ответ. То есть админы делают свайп по экрану, выделяя сообщение для ответа и нажимают кнопку и пользователь, чей ник написан в выделенном сообщении, должен получить ответ
@bot.message_handler(content_types=['text'])
def answer(message):
if 'https://steam' in message.text:
information = 'Тут собирается информация от пользователя'
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
item_1 = types.KeyboardButton('Первая кнопка')
markup.add(item_1)
bot.send_message('id беседы с админами', information, reply_markup=markup)
user_ID = message.from_user.id
if message.caption is not None and "Первая кнопка" in message.caption.lower():
bot.forward_message(user_ID, -1001728991819, message.message.id) # в этой части, мне кажется, что-то не то
elif message.text == 'Скин отправлен, принимай трейд':
bot.send_message(message.from_user.id, 'Скин отправлен, принимай трейд')
Ответы (1 шт):
В общем вот.
from telebot import TeleBot, types
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
# я отсюда беру токен, не обращай внимания
import config
bot = TeleBot(config.BOT_TOKEN)
# начинаем разговор с ботом
# он просит нас отправить имя и мы регистрируем следующий хендлер/функцию
# которая будет реагировать на сообщение юзера
# в неё передаем обьект месседж(также можно передавать колбек) и название функции
# которая и будет это делать (без вызова, только название)
@bot.message_handler(commands=['start'])
def start(message: types.Message):
bot.send_message(message.chat.id, text="Привет, напиши имя")
bot.register_next_step_handler(message, get_name)
# собственно сама функция
# в ней делаем сразу маркап, и в колбек дату передаем такую строку
# type:accept@id:{message.from_user.id}
# всё что здесь написано мы руками обрабатываем в след хендлере, чтобы
# получит информацию о юзере.
# разбиваем строку по смыслу собакой @, а по тип-данные разбиваем двоеточием
# accept чуть ниже обьясню, а в айди кидаем айди юзера
# отправляем в чат по айдишнику (само собой у вас другой айди)
# в текст вписываем то что написал юзер, а в reply_markup собственно маркап
def get_name(message: types.Message):
markup = InlineKeyboardMarkup().add(
InlineKeyboardButton("Принимай трейд", callback_data=f"type:accept@id:{message.from_user.id}"))
bot.send_message(chat_id=-614322222, text=f"{message.text}", reply_markup=markup)
# делаем колбек хендлер, с фильтром в виде лямбда функции
# которая берет наш колбек, вытаскивает из неё data (это по факту строка
# которую мы писали в колбек дате при создании кнопки)
# дальше проверяем её на валидность, по факту чтобы начиналась со строки "type:"
# и этот хендлер будет срабатывать исключительно на нашу кнопку
###
# дальше вызываем anwer_calback_query, чтобы пропал значок часов на кнопке
# после проверяем на тип чата, который в принципе можно
# запихнуть в фильтр хендлера, но в целом неважно
@bot.callback_query_handler(func=lambda call: call.data.startswith("type:"))
def handle_from_admin(call: types.CallbackQuery):
bot.answer_callback_query(callback_query_id=call.id)
if call.message.chat.type == "group":
# вытаскиваем данные а именно, тип ответа, который был нажат
# (мы не можем получить текст с инлайн кнопки, потому делаем так)
# и юзер айди
type_answer = call.data.split("@")[0].split(":")[1]
user_id = call.data.split("@")[1].split(":")[1]
# делаем словарь по типу type_answer - ответ,
# чтобы добавить кнопки создайте новый ключ, и добавьте такой же ключ
# при создании инлайн кнопки
answers = {
"accept": "Принимай трейд",
}
text = answers[type_answer]
# ну и отправляем уже в лс
bot.send_message(chat_id=user_id, text=text)
bot.infinity_polling(skip_pending=True)
Собственно где-то вот так. Единственное я не знаю насколько много данных вы хотите вытащить из юзера, если немного то все их можно запихать в колбек дату, если много то наверное лучше юзать какой-нибудь FSM для телебота. Я не очень люблю телебот, потому советую айограм, в нем есть несколько хороших фич, для работы с колбеками да и вообще с данными.
UPD.
Пример добавления кнопки
def get_name(message: types.Message):
markup = InlineKeyboardMarkup().add(
InlineKeyboardButton("Принимай трейд", callback_data=f"type:accept@id:{message.from_user.id}")).add(
InlineKeyboardButton("У тебя мало кейсов", callback_data=f"type:not_enough_cases@id:{message.from_user.id}"))
bot.send_message(chat_id=-614322222, text=f"{message.text}", reply_markup=markup)
@bot.callback_query_handler(func=lambda call: call.data.startswith("type:"))
def handle_from_admin(call: types.CallbackQuery):
bot.answer_callback_query(callback_query_id=call.id)
if call.message.chat.type == "group":
type_answer = call.data.split("@")[0].split(":")[1]
user_id = call.data.split("@")[1].split(":")[1]
answers = {
"accept": "Принимай трейд",
"not_enough_cases": "Мало кейсов"
}
text = answers[type_answer]
bot.send_message(chat_id=user_id, text=text)