В прошлом уроке мы с вами разобрали как работают обработчики сообщений, ну а в этом чтобы немного расслабиться и написать что-то большее чем было до этого, предлагаю написать квест-бот’а который вы сможете настроить под своих друзей, вторую половинку и т.д.
Если в уроке встретится что-то новое, я обязательно объясню как и зачем.
Напомню, что бота под телеграм я пишу на языке программирования Python, с устройством установки и запуска кода, вы можете более познакомиться в ранних статьях( Урок 1 и Урок 2 ).
Использую одного бота, просто каждый раз очищаю код,
Для тех кто, возможно, ещё не знает.
План
Очень жаль, что я не могу посоветоваться с вами насчёт того, сколько будет вопросов/этапов в нашем квесте, в дальнейшем может обратная связь будет мною продумана).
Сделаем к примеру 4 вопроса(потому что в ходе я не придумал пятый, не получалось сделать решение возможным) различного типа и сложности.
Напишем общий тест для, абсолютно, любого человека.
Чат-бот для квеста
Сделаем 4 уровня сложности, как и вопросов.
Считаю, что лучше делать вопросы на которые будущий пользователь сможет ответить без использования интернета, попытаемся заставить пользователя самостоятельно напрячь мозги.
1 вопрос
Сделаем его максимально простым, так скажем первым уровнем сложности.
Я придумал вопрос.
Ну вы, наверное, уже знаете ответ.
2 вопрос
Второй уровень сложности.
Возможно, уже пользователь воспользуется интернетом.
— Конечно же не 100 лет))
3 вопрос
За идею, конечно же, хотелось бы сделать что-нибудь с использованием аудио. К примеру, пусть пользователь угадает название песни или автора песни. Отправим ему отрывок.
Также можем вместо отрывка отправить ему часть текста песни переведённый на английский и обратно на русский, ну может ещё пару раз прогнанный через другие языки.
Возьму наверное мелодию вступления песни Тима Белорусских — Мокрые кроссы >>, в мелодии нет слов и будет, достаточно, сложно узнать, но всё-равно это возможно.
Здесь мы можем столкнуться с проблемами, решим их по ходу написания кода.
4 вопрос
Пусть в данном вопросе пользователь решит задачу:
Чтобы не было лишних вопросов:
2 кроссовка = 10 ;
парень = (20 — 10)/2= 5 ;
2 кулька = (13-5)/2= 4 ;
1 кроссовок + мальчик с 2 кульками в кроссовках * 1 кулёк = 5+(5+4+10)*2=5+19*2=5+38= 43 ;
В этом вопросе мы можем встреться с тем, что если наш телеграм бот будет отправлять картинку как это делаем мы,
1) Это займёт определённое время.
2) Каждая отправленная картинка каждому нашему пользователю займёт место на серверах телеграма.
А если пользователей много, то и места займётся тоже много.
Конечно, очень вряд ли мы займём всё место на серверах, но всё же,
Почему бы сразу не научиться его экономить для дальнейших целей и это будет значительно ускорять отправку картинки.
В кратце о способе: Каждая картинка, которая уже есть на серверах телеграма, которую мы туда отправим, имеет индивидуальный код,
Кейс бот Telegram — Квест
именно по нему мы и будем отправлять картинки в дальнейшем.
Итак, наш план готов, приступим к коду.
Получение индивидуального кода(file_id) с картинки
В прошлой статье я оппубликовал хэндлеры для получения индивидуального кода с различного типа файлов.
Т.к. телеграм хранит на сервере 3 индивидуальных кода к фото, маленького размера, среднего и высокого, то думаю конечно всех устроит высокий размер. Поэтому наш хэндлер к фото возвращает только file_id высокого разрешения.
Запускаем бота с кодом с прошлой статьи и отправляем необходимые файлы.
Источник: dzen.ru
Квест на день рождения с помощью чат-бота. Часть 1: как придумали и организовали
Квест на день рождения с помощью чат-бота в телеграме делали:
- crm-маркетолог Никита Швецов — настройка и тестирование бота;
- офис-менеджер Катя Бутова — идеи, подготовка офлайн-заданий и организация команды;
- редактор Маша Николаева — идеи, проработка логики и тексты;
- дизайнер Серёжа Залипаев — дизайн всего;
- редактор Серёжа Белоножкин — тексты,
- редактор Марина Власова — тексты и залезания на дерево;
- руководитель контент-команды Лена Бычкова — идеи и залезания на дерево;
- аналитик Вика Агейкова — идеи, проработка логики, задания с голосовыми сообщениями, офлайн-задания с тортом и бутылками вина;
- маркетолог Соня Викулова — печать, закупка винишка и запрятывание его в лесу;
- помощник комдира Вика Моисеева — координация расписания близнецов;
- crm-маркетолог Карина Кожаринова — идеи;
- HR-директор Таня Калиниченко — идеи и сбор поздравлений;
- бухгалтер Таня Лоскутова — торт.
А я менеджерила весь процесс.
25 июля у Вовы и Вани Ильиных, основателей Email Soldiers, день рождения, и мы каждый год готовим для них классные подарки. Например, в прошлом году дарили «Монополию Email Soldiers»:
Ещё раньше — картонные копии Вани и Вовы, халаты с надписью «Идеальный».
Хочется радовать ребят и не дарить шаблонные штуки. В 2020 я была поражена крутотой Монополии, позавидовала, что не приложила к ней руку, и решила: в следующий раз я должна принять участие в подготовке подарка. И — следующий раз настал.
От идеи до начала реализации
За месяц до дня Х мы начали обсуждать предполагаемый подарок в девичьем чатике Дискорда. Голосовали за книгу и видеопоздравление, но вдруг возникла идея — а давайте запилим чат-бота!
Вариант небанальный, инновационный — как близнецы и любят. К тому же — можно включить и частицы других подарков: видео и тексты. Чат-бот сразу набрал в два раза больше голосов.
Классный способ совместить приятное с полезным — прокачать достаточно новое для нас направление на весёлой задаче.
Придумали, что это будет квест на день рождения, обсудили общую канву, локации, онлайн- и офлайн-задания. У ребят в жизни много работы, спорта и кутежей — эти темы и решили использовать в квесте.
Этапы квеста в чат-боте
Определились с этапами чат-бота:
- Знакомство с ботом: онлайн-рассказ, что ребят ждёт вечером перед днём квеста.
- Утренняя пробежка: офлайн-этап — поиск подарка в лесу.
- Голосовые сообщения: онлайн-задание с отсылкой к голосовым сообщениям в телеграме, которые так любит Ваня
- Старый офис: поиск подарка в районе самого первого офиса агентства.
- Вопросы: быстрое онлайн-задание, чтобы расслабиться и вспомнить пару смешных историй.
- Бар: ещё один офлайн-этап. Мы не можем без кутежа в день рождения фаундеров, и это место его начала.
- Поздравления: отправка поздравлений от команды в тот же канал непосредственно в день рождения.
Выбор инструмента для создания чат-бота
В качестве инструмента для чат-бота выбрали Chat2Desk. Почему именно этот? По принципу наименьшего сопротивления. Сразу поняли, что настройкой бота будет заниматься менеджер, которому это в новинку (но жутко интересно), а значит, нужен инструмент, который мы уже знаем — тогда сможем получить консультации и помощь внутри команды. На Chat2Desk реализован наш курс для писателей, у нас уже есть аккаунт в этой системе, поэтому выбрали его.
Подробности механики чат-бота
Дальше определились со всеми заданиями, прописали черновые тексты, создали схему-алгоритм.
Важно было расписать всё подробно, чтобы ничего не забыть.
Кусочек схемы-алгоритма в Miro
Дорабатывали схему на ходу: например, когда были готовы тексты, авторы вписали их прямо в карту, и мы с неё переносили всё в бота.
Рабочий процесс создания бота
Менеджмент проекта пал на меня. К задачам подписали ответственных и дедлайны.
Первоначальная таблица задач и ответственных за них сотрудников
Через пару дней количество задач перевалило за 20. Чтобы легче было всё контролировать, я создала доску в Трелло:
Задач оказалось около 25, и это больше, чем мы думали. Повезло, что в команде уже 100+ человек — несложно было найти тех, у кого горят глаза, и распределить задания.
Проблемы и их героические решения
У нас возникли сложности — расскажем, как выкрутились (или не выкрутились):
- Внезапные изменения в расписании. День рождения у ребят в этом году пришёлся на воскресенье. Мы рассчитывали поздравить в пятницу и перейти от последнего шага квеста к кутежу. Но за неделю до этого выяснилось, что у ребят запланирована поездка в Москву в пятницу вечером. Пара часов паники и обдумывания вариантов, и мы решили сдвинуть дату на четверг. Сразу отмечу: сдвигать дедлайн «к себе» — не лучшая затея, ребята. Но у нас не было вариантов.
- Симбиоз офлайна и онлайна в плане подготовкиусложнил процесс сборки проекта в единое целое. Недостаточно было просто придумать алгоритм, текст и настроить бота — нужно добавить много физических шагов. И это усложнилось удалёнкой 95% организаторов. Например, мы решили начать квест, вручив открытки каждому из братьев. Для этого их надо было задизайнить, отдать в полиграфию, забрать напечатанные экземпляры, отдать вручающему, проверить, что QR-код считывается (спойлер: со считыванием у ребят всё равно возникли проблемы). Мы справились во многом благодаря ответственности команды и параноидальным пингам друг друга.
- Симбиоз офлайна и онлайна в ходе прохождения квеста. Вот уехали они выполнять задание в старый офис — а как понять, что у них всё получается? Чтобы соединить онлайн и офлайн и всегда понимать, на каком этапе находятся ребята, в контрольных точках каждого офлайн-задания мы добавили кодовые слова. Парни должны были ввести их в чат-бот для перехода на следующий уровень. Иногда кодовое слово было не совсем очевидно — это добавило динамики в квест.
- Очень загруженный график близнецов усложнил нам выбор времени для заданий. Поэтому мы внесли в календарь ребят встречи, когда должны происходить события квеста.
- Сжатые сроки.Первый мозговой штурм был примерно за месяц до дня рождения, а чатик организаторов удалось собрать за 2 недели до старта квеста. В первую неделю делали всё очень медленно, во вторую — очень быстро. Как справились: — подвинули некоторые внутренние рабочие задачи;
— «несли блюда по готовности»: сначала настроили логику бота, потом вносили чистовой текст, затем — «голосовухи» и фотки, в конце добавили мемы;
— работали ночами и посменно: например, Никита Швецов настраивал бота с 8 до 11 вечера, я с 11 до 2 ночи его тестировала и тоже вносила правки или оставляла комменты, потом в 7-8 утра до начала рабочего дня Никита дополнял схему и тоже тестировал;
— задания в боте были поделены на уровни, и Никита настроил переходы на эти уровни для тестирования, и мы всё финализировали и тестировали по ближайшему уровню до его начала, а дальше, когда он заканчивался, могли перейти к следующему. - Ваня и Вова оказались очень любопытны и, когда получили открытки, приложили усилия, чтобы сломать бота и смутить его своими неправильными ответами. Вместо плановых кодовых слов, например, «Да/Нет» или «Я Вова/Я Ваня», они писали: «А ты кто?» или «А что тебе надо?» В дальнейшем мы учли такое коварное поведение и подстраховались.
- Иногда ребятам нужна была помощь в боте, но, когда что-то пишешь в бот, кнопки подсказок сворачивались. И чтобы увидеть их снова, нужно нажать иконку «Кнопки» в поле ввода:
Источник: vc.ru
Telegram бот для сложных квестов
«В чем же заключается преимущество?» — спросите вы, ну все дело в том, что в нем можно построить логику примерно из следующих выражений:
– Пользователь на шаге N?
– Сообщение содержит изображение и смайлик?
– Текст подходит под регулярное выражению «I am [a-zA-Z]+»?
– Время получения раньше/позже заданного?
– Это было нажатие на клавиатуре/обычное сообщение/inline-кнопка?
Большинство из этих правил могут быть в зависимости друг от друга, но об этом чуть позже.
Для начала, о чем я хочу рассказать:
- Об идее проекта – зачем я это сделал, какие есть аналоги, но почему мне они не нравятся.
- Архитектурных решениях, какие возникли трудности, как были решены.
- Что получилось в итоге и стоило ли оно того, дальнейшее развитие.
Цель проекта
Это было в конце ноября, я понимал что скоро новый год и необходимо дарить подарки.
Идея с Telegram Bot–ом, в качестве карты поиска, казалась крайней простой и в должном исполнении интересной. Единственное что необходимо было сделать – взять и загуглить. Что собственно я и сделал. Основной посыл запроса – платформа для создания квестов, или же просто чат-бот c дополнительной логикой, написанный на python (желательно Django Framework)
Большинство рассмотренных приложений либо имели захордкоженные данные, либо же были своего рода викторинами. Ни то ни другое не подходило.
Интересными вариантами показались: Django Telegram Bot, PermaBot.
На первом репозитории долго задерживаться нет смысла, так как в описании недвусмысленно сказано «Try Permabots: more stable django app for bots.». Потому выбираем второй.
Стоит отметить что данная платформа сделана достаточно качественно, хоть и без соблюдения pep8 (не камень в огород, но это же де-факто стандарт 🙂 ), однако с комментариями, тестами, а главное документацией по REST API.
При наличии всех этих плюсов были обнаружены и существенные недочеты:
- старая версия telegram API (версия 4.2.0 против 9.0.0, последний коммит Июнь 2016)
- полное отсутствие поддержки media (здесь моя идея с изображениями накрылась медным тазом)
- некоторые отсутствующие фичи (отложенная отправка уведомлений с настройками возможного ответа, гибкая настройка клавиатуры чата).
Веб фреймворк – Django, для асинхронных задач – Celery, брокер сообщений –
Redis, база данных – SQLite. В дальнейшем есть возможность переехать на Postgres/MySQL, но пока тащить всю эту махину с собой бессмысленно.
Что стоит отметить, для разработки и запуска проекта нужен внешний https-адрес, на который будут прилетать веб-хуки. Для этого можно использовать туннелирование на публичный домен посредством Ngrok или LocalTunnel.
Я использовал localtunnel локально и на сервере в связке c nginx и let’s encrypt сертификатами.
Архитектура
Bot – содержит общую информацию и token (аналог telegram.Bot в оф. документации)
Quest – модель квеста, все просто: имя, описание, бот. вынесено в отдельную сущность для логического разграничения
Step – возможные состояния переходов. если имеет флаг is_init=True, то будет выбрано в качестве начального при инициализации квеста
Handler – выступает в роли dispatcher-a, имеет логическое выражение, которое может выполняться либо нет, в зависимости от этого переводит пользователя на определенный шаг и отправляет соответствующие ответы (представлены моделью Response)
Condition – содержит возможные правила для какого–то определенного поля.
Update – объект, который прилетает с веб – хуком и содержит всю информацию
CallbackQuery – используется для inline – сообщений, отправлять таковые возможности пока нет (основной упор был на базовую клавиатуру), однако варианты расширения учитывались.
Reponse – хранит информацию о тексте сообщения, клавиатуре, ее поведении (скрыть, удалить, установить по умолчанию, показать дефолтную)
Message – полученный объект сообщения (telegram.Message)
Chat – хранит информацию о чате (telegram.Chat)
Photo – модель хранящая информацию о изображении (telegram.PhotoSize)
Event – отвечает за отправку сообщений в определенный чат, и имеет возможность одновременной установки состояния (шага) пользователя. все дополнительные данные (текст, клавиатура, настройки к ней) берет из заданной модели Reponse
User – модель пользователя унаследовал от contrib.auth.models.AbstractUser c указанием device_uid, step и еще некоторых дополнительных полей
Полную UML диаграмму можно просмотреть в draw.io, файл db-diagram.xml
Как мне кажется, один из любопытных аспектов это то, как происходит решение о выборе того или иного обработчика.
В поле «Mathematics expression» логическое выражение можно задавать двумя способами. Первый – тот что указан в примере, в этом случае условия к данному обработчику будут подставлены в порядке их добавления, во втором варианте – можно указать id условий.
Затем выполняется парсинг. Он проходит два этапа, вначале делается преобразование в булевое отображение, где 1 и 0 – истинность конкретного условия, и затем происходит разбор грамматики с использованием библиотеки pyparsing.
Другая сложность с которой пришлось столкнуться – выбор и указание клавиатуры. Было решено сделать одну по умолчанию и другую предоставлять в ответе. Таким образом появляется возможность задать дефолтную на весь чат, которая может выглядеть примерно так [[«Задать вопрос»], [«Попросить подсказку»]]
Также можно увидеть что telegram api позволяет скрывать текущую клавиатуру при нажатии на кнопку или же удалять ее совсем (в этом случае отправляется дефолтная).
Еще одна вещь связанная с клавиатурой – это попытка узнать что же это было, то ли обычное сообщение написанное пользователем или же нажатие на кнопку. Для чего это нужно?
Предположим, на каком-то шаге мы решили запросить текстовый ответ у пользователя и в то же время там отображается стандартная клавиатура с кнопкой «Поменять задание». Несмотря на то что обработчики (Handlers) содержат опциональные поля Step on success и Step on error, гораздо проще организовать логику ограничив тип действия на который они реагируют. Для этого в модели Chat содержится информация еще и о текущей клавиатуре, по ней определяется нажатие это или другой тип события. Это полезно когда необходимо узнать что творится в каком-то определенном чате.
Помимо этого, из фич, которые показались нужными – это функция redirect message. В каждом обработчике можно указать кому перенаправлять сообщение при вынесении вердикта истинности. Пригождается когда нужно проследить специфические моменты (тот же вопрос администратору) или прохождение некоторых этапов пользователем.
Стоило оно того?
Определенно. Тестирование заняло пару вечеров, после чего я настроил и запустил это на сервере. Квест состоял из 10+ состояний и включал в себя выбор вариантов ответа, рассказ истории (суть была в поиске ключевых слов), выполнение задания по карте местности, отправки фотографии года и еще некоторые.
Пожалуй, реакция человека, для которого я это делал, окупила те вечера перед зачетной неделей, которые я потратил.
Перспективы
На данный момент готов рабочий вариант, который разворачивается в docker-контейнере за пару минут, но для полноценной разработки необходимы тесты, продуманное окружение и еще некоторые настройки. Если кому-то проект покажется интересным, то я с желанием продолжу поддержку/разработку, реализация фронтенда под вопросом, но возможна (на emberJS или vueJS).
Спасибо вам за внимание!
Буду рад услышать вопросы, пожелания, критику
Источник: habr.com