Никита Швецов
CRM-маркетолог
На прошлой неделе Лена Благова рассказала, как возникла идея создать квест на день рождения на основе чат бота и как прошёл сам квест. На меня легла техническая часть реализации.
Ситуация и первые сложности
25 июля, у Вовы и Вани Ильиных, основателей Email Soldiers, день рождения. Мы решили подготовить для них квест и чат-бота, который помогал бы двигаться по квесту.
В обычной ситуации чат-ботами занимается CRM-маркетолог Андрей Благов. Но он был плотно занят на клиентских проектах, а мне интересна тема чат-ботов. К тому же в моём OKR стоит цель на эту тему, поэтому за разработку взялся я. В реализации мне помогала Лена Благова, которая добровольно вызвалась менеджерить этот проект.
Сложности возникли уже на старте: у меня не было опыта создания чат-ботов, а сроки были ограничены — около двух недель. А ведь параллельно нужно было заниматься основными проектами.
Решение и реализация
Мы выбрали Telegram: это основной мессенджер, которым пользуются братья. В качестве платформы для создания чат-бота — Chat2Desk: там у нас уже запущены другие боты, функционал знаком и обкатан.
В боте было 3 ветки: «Ваня», «Вова» и «Неильин». Последняя — для поздравителей и любопытствующих.
Схему бота собрали в Miro:
Упростили логику
Логика бота изначально была сложной: помимо того, что в ней было три цепочки, в цепочках Вани и Вовы были как общие сообщения, так и персональные. Например, задание — общее, а ответы — персональные.
Я решил упростить это через переменные. При старте бота, когда личность участника подтверждена, в его дополнительные поля загружались персональные переменные. Поэтому в большинстве случаев можно было упростить логику и использовать одно сообщение для обоих братьев, персонализируя его через переменные. Например, «Привет, {name}», «Любишь бегать по утрам в {place}?»
Переписали бота с нуля
Я собрал драфт бота, оставалось добавить актуальный контент: текст, фотографии и тайминг. Но были баги: иногда бот не реагировал на сообщения от пользователя, не посылал сообщения, зависал. Связывал это с довольно костыльной реализацией из-за отсутствия опыта.
С одной стороны, к концу реализации первого драфта бота у меня сложилось понимание, как реализовать его проще и стабильнее, а с другой — время до запуска ещё было, поэтому я решил переписать бота заново, учитывая свои ошибки.
Я собрал второй драфт бота и действительно, основные, «непонятные» баги исчезли.
Тестировали и перезапускали бота
Изначально, чтобы протестировать бота, его нужно было проходить полностью начиная с первого этапа. Даже если временно сокращать задержки между этапами, это отнимало дополнительное время и вызывало неудобства.
На тот момент мы с Леной уже понимали, что поломка может произойти в любой момент, поэтому предусмотрели возможность перехода к определённому этапу бота без необходимости проходить его полностью.
Если у пользователя бот сломался, например, на третьем этапе, то он мог перезапустить бота и сразу перейти к этапу 3, а не проходить заново этапы 1 и 2 перед этим. Эту же схему использовали, чтобы самим тестировать этапы.
Реализовано это так: при запуске бота можно выбрать, кто ты — «Вова», «Ваня» или «Неильин». Но ещё можно было ввести кодовое слово и попасть в новое меню. И из него, выбрав, кто ты или за кого хочешь протестировать, можно было перейти к нужному этапу.
Удалили варианты кнопок пройденного этапа
В боте был момент, где братьям нужно было угадать, кто рассказывает историю. Сначала показывалось меню, три кнопки, по ним можно было пойти отгадывать истории.
Когда история отгадана, пользователь возвращался на шаг с тремя кнопками и мог пойти угадывать следующую историю.
Нам было нужно, чтобы после прохождения истории пользователь видел в меню только непройденные истории, а пройденные не отображались.
Решение я снова реализовал через переменные: если участник корректно прошёл историю, то это указывалось в одной из переменных, и в меню больше не было этой истории.
У пользователя пропадали кнопки — решили не вмешиваться
В процессе выяснилось, что у пользователя исчезали кнопки в боте, если оператор ответил ему текстом. По факту они не исчезали, а сворачивались, но это было неочевидно для пользователя.
Одним из возможных решений было добавить обработку сообщений от оператора после каждого сообщения, но у нас оставалось мало времени, поэтому мы решили без веской причины просто не вмешиваться в прохождение бота.
Коллективно правили
Два раза мы с Леной Благовой сталкивались с такой проблемой: кто-то из нас вносил изменения в бота, а они не сохранялись.
Насколько мы поняли, это было связано с тем, что если первый человек внёс и сохранил изменения, а второй человек после этого не обновил страницу, то сохраняется версия второго человека — без изменений.
Нам пришлось повторно всё править и предупреждать друг друга о любых работах с ботом.
Столкнулись с ограничением загружаемого видео
На одном из этапов мы должны были получать видео от бота. Оказалось, что платформа не распознаёт видео в формате «кружочков», которые обычно используются в телеграме.
Мы решили отдельно прописать в тексте бота, что ожидаем обычных файлов видео. Но оказалось, что и здесь есть проблема — ограничения файлов в 20 мб. А видео всегда весило больше.
Поэтому пришлось эту часть упростить и вместо видео запрашивать текст.
Обрабатывали незапланированные сообщения
Я предполагал, что братья будут проходить бота, как задумывалось — когда нужно, отправлять текст, когда нужно — нажимать кнопку и т. д. Но всё оказалось не так просто, а бот не умел реагировать на нештатные ситуации: ждал определённых ответов, тогда как ему писали что-то другое. Тогда он «зависал».
Чтобы избежать этого, добавил обработку некорректных фраз.
Вручную увеличивали задержки на этапе
В Chat2Desk есть одна особенность: если пользователь находится на каком-то блоке более 10 минут, то он автоматически проходит дальше по цепочке. Например, если бот задал вопрос, а пользователь не отвечает больше 10 минут.
Изменить это время глобально нельзя, поэтому я вручную в каждый блок добавил большую задержку. Теперь бот ждал ответа участника практически без ограничений по времени.
И снова увеличивали задержки и перезапускали цепочку
Чтобы централизованно хранить и назначать переменные, основную часть я вынес в начало цепочки. Там определялось время и общие переменные.
Но и это превратилось в проблему: если пользователь уже попал в блок ожидания определённого времени или даты, а мы хотим изменить это время или дату, то мы можем только увеличить время ожидания или перезапустить цепочку.
Делали доступ к боту без ссылки на бота
Когда создание бота близилось к завершению, нам нужно было печатать QR код, который затем размещался на открытках братьев. Изначально мы планировали, что к этому моменту будет известна ссылка на финальную версию бота.
Но при создании нового бота ему автоматически присваивается ссылка, которую нельзя изменить. Я рассматривал вариант о третьей версии бота, поэтому не знал, какая ссылка будет финальной. Могла случиться ситуация, что уже отпечатанный QR-код вёл бы не на ту версию бота.
Поэтому решил пойти другим путём: в QR-код мы зашили ссылку, которая не будет меняться. Идея была в том, чтобы перед финальным запуском бота просто сделать редирект на актуальную версию. Спойлер: всё сработало.
Результат
Чат-бот в итоге работал, братья довольны.