Всем привет! Спасибо за интерес к предыдущим постам (раз и два), а сегодня продолжаем дополнять нашего бота функционалом. Сохраним ответы из телеграма от пользователей в гугл таблицу.
Полезное отступление
Сначала я бы хотела сделать пол шага назад и показать, в каком виде мы получаем информацию из телеграма, когда мы кликаем по кнопке, отправляем сообщение боту или любое другое действие. Любая активность пользователя возвращается в виде json пакета.
Например, мое сообщение /start отправляет HTTP POST запрос к веб-приложению (веб-приложение это наш скрипт). Скрипт, в свою очередь, с помощью Simple trigger doPost(e) вернет пакет как в снипете ниже
e в doPost(e) означает event. Далее обращаемся к документации и изучаем методы для event. Находим e.postData.contents и используем его для парсинга json-пакета. Функция парсинга у нас уже есть
function doPost(e) < const update = JSON.parse(e.postData.contents); let msgData = <>if (update.hasOwnProperty(‘message’)) < msgData = < id : update.message.message_id, chat_id : update.message.chat.id, user_name : update.message.from.username, text : update.message.text, is_msg : true >; > sendQuestions(msgData.chat_id); >
Помимо свойства message могут быть callback_data, edited_message, forwarded_message и так далее. При этом возвращаемый пакет будет содержать разные ключи и вложенность и, соответственно, в парсинге необходимо предусматривать все кейсы, которые нас интересуют.
Телеграм-Бот через Google-таблицы (без кода)
У нас есть кейс с кнопками, нажатие на какую-либо из них возвращает пакет вида
Очевидно, что пакеты различаются и порядок парсинга тоже изменится. Дополним функцию doPost(e) обработкой нажатия кнопки
function doPost(e) < const update = JSON.parse(e.postData.contents); let msgData = <>if (update.hasOwnProperty(‘message’)) < msgData = < id : update.message.message_id, chat_id : update.message.chat.id, user_name : update.message.from.username, text : update.message.text, date : (update.message.date/86400)+25569.125, is_msg : true >; > else if (update.hasOwnProperty(‘callback_query’)) < msgData = < id : update.callback_query.message.message_id, chat_id : update.callback_query.message.chat.id, user_name : update.callback_query.from.username, first_name : update.callback_query.from.first_name, text : update.callback_query.message.text, data : update.callback_query.data, is_button : true >//sendQuestions(msgData.chat_id); >
Сам объект msgData можно дополнять любыми необходимыми вам значениями. В моем примере, помимо некоторых данных из пакета, я добавила идентификаторы is_msg и is_button.
Надеюсь, что в этой части я привела достаточные вводные как работать с пакетами и парсингом.
План минимум
Функцию doPost(e) я оставлю только для парсинга и вызову в ней в последней строке новую функцию dataHandler(msgData). Обозначим ее пока приблизительно, проверив какое событие (event) вернулось — сообщение или кнопка.
function dataHandler(msgData) < if (msgData.is_msg) < sendQuestions(msgData.chat_id); >else if (msgData.is_button) < saveData(msgData) >>
Если бот получил сообщение, отправляем вопросы, если кнопку, сохраняем ответы. Структура таблицы для сохранения ответов следующая
Функция сохранения ответов saveData(msgData)
function saveData(msgData)
В переменную vals я записываю сохраняемые данные в том порядке, в котором они будут выведены в таблице. На лист usersSheet вставляю новую строку с помощью метода appendRow() и указанием вставляемого массива. Результат выполнения функции приведен на скрине выше во второй строке таблицы.
Далее будем проверять правильность ответов и возвращать пользователю результат. Здесь нам нужно сопоставить сообщение с вопросом из таблицы, затем вопрос из таблицы — с ответами из таблицы Answers и проверить выбранный из 4 вариантов ответ на корректность.
Здесь я бы хотела использовать не текст вопроса, а его ид. Поменяю текст вопроса так, что в начале вопроса будет его ид.
В функции sendQuestions(chat_id) вместо строки send(e[1], chat_id, keyboard) напишу две следующие
const question = e[0]+’/’+questionsArr.length+’: ‘+e[1] send(question, chat_id, keyboard)
Таким образом, в объекте msgData после нажатия кнопки мы можем спарсить ид вопроса и записать его в таблицу с ответами, изменив функцию saveData(msgData)
function saveData(msgData)
В данном случае, из текста сообщения мы сохраняем только первый символ, что соответствует ид вопроса. Как это выглядит в таблице.
*Если дата записана в виде магических чисел, измените формат ячеек в соответствующей колонке.
Теперь добавим интерактивности нашему боту и дадим пользователю понять, верный ли он дал ответ или нет. Пример ниже
После ответа бот показывает правильность ответов в тексте кнопок, а в тексте сообщения выводит ответ пользователя и корректность данного ответа.
Для начала обозначим функцию, которая редактирует уже отправленное сообщение
function editMsg(msg, chat_id, msg_id, keyboard) < const payload = < ‘method’: ‘editMessageText’, ‘chat_id’: String(chat_id), ‘message_id’: String(msg_id), ‘text’: msg, ‘parse_mode’: ‘HTML’ >if (keyboard) payload.reply_markup = JSON.stringify(keyboard) const data =
Функция использует метод editMessageText, обязательными параметрами являются text, chat_id и message_id. Дополнительно мы можем указать другие параметры, в том числе клавиатуру.
*Чтобы не запутаться, храните функции в разных файлах, разделив их по предназначению. Например, функции для отправки данных в телеграм, глобальные переменные и функция парсинга расположены у меня в разных файлах.
Далее создам еще одну функцию editMessage(msgData), в которой нам нужно сравнить ответ пользователя с вариантами ответов из таблицы, и в зависимости от правильности ответа внести соответствующие правки в текст.
Начнем с ответов из таблицы, записав их в переменную answersArr, что мы уже делали в функции отправки вопросов.
function editMessage(msgData)
Воспользуюсь методом массива .filter(), оставив варианты ответа только для текущего вопроса
const answersArr = answersSheet.getDataRange().getValues().filter(e => e[0] == msgData.text[0]);
В данном случае я сравниваю первый элемент массива answersArr с первым символом в строке текста сообщения, то есть сопоставляю ид вопроса из таблицы с ответами с ид вопроса из текста сообщения.
Сохраним в переменную curAnswerArr строку из таблицы с ответами, которая соответствует данному пользователем ответу
const curAnswerArr = answersArr.find(e => e[1] == msgData.data);
Здесь в уже отфильтрованном массиве из 4х вариантов ответов я выбираю один, текст которого равен тексту в кнопке.
Далее отредактирую сам текст сообщения в зависимости от того, правильный был ответ или нет
let newText = new String(); if (curAnswerArr[2]) newText = msgData.text + ‘nn✅WownТвой ответ: ‘+msgData.data; else newText = msgData.text + ‘nn❌NopenТвой ответ: ‘+msgData.data;
Если данный пользователем ответ имеет плашку TRUE, то в текст добавляю галочку, или крестик в обратном случае.
И наконец прописываем строку с вызовом функции editMsg() и передаем новый текст сообщения, ид чата, ид сообщения и null для клавиатуры.
editMsg(newText,msgData.chat_id,msgData.id,null);
Вся функция saveData(msgData) представлена ниже
function editMessage(msgData) < const answersArr = answersSheet.getDataRange().getValues().filter(e =>e[0] == msgData.text[0]); const curAnswerArr = answersArr.find(e => e[1] == msgData.data); let newText = new String(); if (curAnswerArr[2]) newText = msgData.text + ‘nn✅WownТвой ответ: ‘+msgData.data; else newText = msgData.text + ‘nn❌NopenТвой ответ: ‘+msgData.data; editMsg(newText,msgData.chat_id,msgData.id, null); >
На этом этапе деплоим и проверяем, что все работает
Клавиатура под сообщением пропала, т.к. в editMsg вместо клавиатуры мы передали null.
Редактирование клавиатуры оставлю читателю для самостоятельного изучения. Может один из моих старых постов поможет
Источник: temofeev.ru
Как научить бота читать текстовые файлы, строить таблицы и диаграммы
ChatGPT — полезная вещь, но часто работать с ним было неудобно. Он запоминал мало информации, а длина сообщений была ограничена. Кроме того, он писал код и таблицы внутри чата — потом приходилось их копировать куда надо. Теперь этой проблемы нет, потому что в ChatGPT появился новый режим — Code Interpreter. Что это за режим, зачем и как его использовать — рассказываю в статье.
Зачем использовать этот режим
В нем можно загружать боту несколько файлов разных форматов: xlsx, docx, txt, csv и др. Вот, что бот умеет в новом режиме:
- решать сложные математические задачи;
- писать код;
- редактировать файлы;
- анализировать данные;
- создавать диаграммы;
- писать по заданным инструкциям.
Для примера я попросил ChatGPT нарисовать 6 диаграмм с любыми данными и вот, что у него получилось:
В общем, режим крутой и в нем можно сделать много полезного. Но сначала разберемся, как с ним работать.
Как включить режим Code Interpreter
Сейчас режим доступен всем пользователям с платной подпиской. Но при подключении к боту рекомендую выбирать в VPN локацию США или какую-нибудь страну Западной Европы. Потому что в некоторых странах режима до сих пор нет в настройках. Почему так — неизвестно.
Чтобы включить режим code interpreter, в правом нижнем углу кликните на три точки рядом с email и выберите «settings https://www.ixbt.com/live/offtopic/kak-nauchit-bota-chitat-tekstovye-fayly-stroit-tablicy-i-diagrammy.html» target=»_blank»]www.ixbt.com[/mask_link]
10 конструкторов для создания Telegram-ботов
Чат-боты активно внедряются в коммуникации между бизнесом и клиентами. Это удобно всем: менеджеры не тратят время на простые запросы и работают с частными случаями. Клиенты — не ждут ответа поддержки, быстро получают нужную информацию.
Ботов используют в разных сферах: от интернет-магазинов до государственных ведомств. Сейчас набирают обороты чат-боты в Telegram: мессенджер стал самым популярным в России, поэтому все больше компаний используют его для общения с клиентами.