Pull to refresh

Боты в телеграм: опыт, откровения, советы по разработке

Reading time10 min
Views26K
Давайте сразу по делу. Содержание статьи:
  • С чего мы начали писать ботов в Telegram. Первый опыт.
  • Создание nodejs библиотеки bot-brother для быстрого написания ботов.
  • Разбираем код свеженаписанного бота DeloreanBot
  • Общечеловеческие рекомендации по созданию популярного бота
  • Философские рассуждения о монетизации ботов


Поехали.

С чего мы начали делать ботов. Matchmaker, Weatherman, Zodiac.


Внимание! Следующий абзац может содержать спойлеры. Будьте осторожны.

Все три бота получились годными и болтаются сейчас в топе storebot.me. Weatherman уже несколько месяцев стабильно держится на первом месте рейтинга.

Теперь краткая история создания.

Разработчиков хлебом не корми – дай только накодить какую-нибудь прикольную бестолковую фигню. Поэтому нам было невероятно сложно игнорировать новость о запуске ботов в Telegram.
Перво-наперво нужно было придумать идею для первого бота. Ресерч начали со столпов интернета – порно и котиков.
Оказалось, что в арабских странах порно-сайты заблокированы, а порно в телеграме доступно. Этот факт помножил привлекательность порно-ботов для разработчиков на бесконечность и ниша быстро заполнилась.
А на котиков у Сережи (Сережа – это вообще говоря разработчик, я тут тока статьи пишу) аллергия.

Где-то на стыке порно и котиков возникла идея сделать дейтинг-бота. Недолго думая, мы создали Matchmaker_bot – аналог Tinder в Telegram (telegram.me/matchmaker_bot).
Идея бота проста и поэтому прекрасна – вы загружаете фото, а затем смотрите фото других людей. Если вы понравились некоторому пользователю, а он понравился вам, бот позволит вам обменяться контактами и вы сможете жить долго и счастливо пока смерть не разлучит вас поболтать в телеграме.

Не могу не поделиться. При первом запуске бота в коде был баг, который засчитывал дизлайк за лайк. Из-за этого бага я залайкала добрый десяток брутальных иранцев, которые тут же радостно принялись со мной чатиться.
Каждый раз, когда я видела уведомление в телеграм о том, что мне пришло фото, я зажмуривалась и бежала к Сереже, чтобы тот удалил фотку – все ждала непристойностей. Но вежливые иранцы ни разу не прислали ничего непотребного – только картинки с цветам и котиками. Такие вот романтичные товарищи.

За первые двое суток жизни бот собрал 800 уникальных пользователей, получил 200 человек суточной аудитории и до сих пор аудитория растет.
На момент написания статьи мы имеем 900 уникальных посетителей в сутки.

Мы не специалисты по SEO-оптимизации сайтов и, честно скажу, не представляем, как сделать веб-сайт, который бы за два дня привлек аналогичную аудиторию без каких-либо специальных усилий.

Поэтому результат нас воодушевил и Сережа решил быстренько наваять еще пару ботов. Так свет увидели Weatherman и Zodiac – боты, которые умеют давать прогноз погоды или гороскоп, а также отправлять вам ежедневно прогнозы на сегодня или завтра в указанное вами время (telegram.me/weatherman_bot и telegram.me/zodiac_bot).

Сережа заморочился и сделал локализацию для ботов на 5 языках, а для погодного бота аж взял платное погодное API.
Мультиязычность, точность прогноза и понятный интерфейс внезапно сделали погодного бота очень популярным.
Сейчас он находится в топе storebot.me, периодически попадая на место самого крутого бота в Telegram, имеет более 2000 оценок пользователей, средняя оценка 5 звезд. Отзывы полны любви и обожания.


Создание nodejs библиотеки bot-brother для быстрой разработки ботов


Первый бот писался бессистемно, на голом энтузиазме. Но настоящий разработчик понимает – если вам предстоит делать примерно один и тот же продукт много раз, начинает попахивать фреймворком. Готовых библиотек или фреймворков мы не нашли, поэтому Сережа написал свою либу.

Telegram Bot API позволяет с помощью http-запросов получать или отправлять текстовые команды для диалога с пользователем.
Вы можете добавлять в запросы специальную разметку и переменные, чтобы, например, показывать пользователю несложную клавиатуру.


На деле разработчик думает в терминах несколько более сложных абстракций.

1. Вы разделяете текстовые сообщения от пользователя на два типа – ввод команды и ответ на запрос бота.

Например, имеет место диалог:
User: Бот, покажи мне прогноз погоды!
Bot: Ок, для какого города?
User: Иркутск
Bot: Холодно в Иркутске…

Первая фраза диалога – это инициализация диалога пользователем, ввод команды. А третья фраза – это уже ответ на конкретный вопрос бота.

2. Вся работа с ботом – это хождения по некоторому конечному автомату.

Вот хочется иметь средства для удобного перемещения между состояниями (командами), уметь делать дочерние и родительские состояния, возвращаться в состояние по новой и т.д. и т.п. Проще говоря – хочется иметь удобный инструмент для маршрутизации между командами.

3. Вам хочется иметь инструмент для удобной работы с разными языками.

Хочется иметь отдельно логику, отдельно конфиги для разных языков. В идеале конфиги языков должны быть простые, чтобы можно было отдавать файлы локализации на аутсорс для перевода.

4. Вам хочется организовать сессии.

То есть иметь некоторый набор данных, которые привязаны к уникальному пользователю бота.

5. Хочется разбить обработку команды на несколько стадий – middlewares.

Все любят принципы express.js :)

Все эти идеи воплотились в библиотеке bot-brother. Мы постарались написать для нее подробную документацию, с которой можно ознакомиться в репозитории.

Бот за день. Использование bot-brother на примере бота для уведомлений DeloreanBot.


Если кто-то хочет пропустить лирику, потрогать работающего бота можно в Telegram, а его исходники посмотреть на гитхабе.

Для остальных опишем особенности реализации.
Функциональность изготавливаемого бота – пользователь вводит в бот напоминания и время, бот в нужное время присылает уведомление.
Например, пользователь пишет «Погулять с собакой через час», бот через час присылает напоминалку. (Давайте сразу договоримся, что мы не претендуем на оригинальность идеи). Делаем бот на русском и английском языках.

Написание такого бота от и до, отладка и локализация интерфейса на английский у нас занимает один день.

Нам нужно:
  • Уметь отрабатывать команды пользователя;
  • Организовать локализацию;
  • Уметь удобным способом определять часовой пояс пользователя;
  • Хранить пользовательские данные;
  • Уметь отслеживать время, когда нужно отправить сообщение;
  • Уметь парсить фразы, содержащие дату и время.

1. Обработка команд пользователя

Это в общем базовая функциональность bot-brother. Нет смысла дублировать здесь документацию библиотеки. Приведу небольшой фрагмент кода для общего понимания. Регистрация команды и реакции на ее ответ обычно выглядит вот так:

// Регистрируем команду settings_locale
bot.command('settings_locale')
    .invoke(function (ctx) {
        // Наш ответ на вызов команды – просим пользователя выбрать язык
	return ctx.sendMessage('Выберите язык');
    })
    .answer(function (ctx) {
        // Обработчик ответа пользователя на наш вопрос.
	ctx.session.locale = ctx.answer;
	ctx.setLocale(ctx.answer);
	return ctx.sendMessage('answer.success').then(function () {
            // Когда человек выбрал язык, сразу возвращаемся к прошлой команде.
	    return ctx.goBack();
	});
    })
    // Не будем заставлять пользователя вбивать текст, предложим варианты ответа с помощью клавиатуры.
    .keyboard([[
            {'Русский': 'ru'},
	    {'English': 'en'},
         ],
         // Добавляем кнопку «назад» для передумавших.
         [{‘Назад‘: function (ctx) { ctx.goBack(); }]
    ]);


2. Организация локализации

Раз уж мы просим у человека указать язык интерфейса, неплохо бы при работе с ботом показывать ему тексты на правильном языке.

Все фразы будем хранить в виде “ключ-локализованное значение” в yaml-файлах. Этот формат удобен, если вы хотите отдавать файлы на редактирование сторонним переводчикам. Пример файла с английским переводом можно посмотреть здесь.

Кодом превращаем эти файлы в json нужного формата и передаем боту.

Код по превращению yaml-файлов в json научного интереса не представляет, но если что лежит тут.
// Фрагмент кода по созданию бота
var bot = bb({
        key: config.bot.key,
        redis: config.redis
    })
    // Задаем боту наборы фраз на разных языках.
    .texts(texts.ru, {locale: 'ru'})
    .texts(texts.en, {locale: 'en'})
    .texts(texts.default);


После этого в коде везде вместо текстовых фраз будем указывать соответствующие ключи локализации.

Все куски кода с выводом текстовых сообщений немного изменятся.
Этот фрагмент кода
.invoke(function (ctx) {
    // Наш ответ на вызов команды – просим пользователя выбрать язык
    return ctx.sendMessage('Выберите язык');
})

трансформируется в
.invoke(function (ctx) {
    // Наш ответ на вызов команды – просим пользователя выбрать язык
    return ctx.sendMessage('settings.locale');
})


3. Определение часового пояса пользователя.

Если вы подойдете и попросите рядового гражданина назвать свой часовой пояс, он может вас не понять. Зато почти все человеческие особи более или менее уверены в названии города, в котором они находятся. Воспользуемся этим фактом.

Для определения часового пояса, таким образом, нужно или напрямую запросить локацию пользователя, или попросить пользователя напечатать название своего города. Практика показывает, что этот подход хорош и никого не отпугивает.

Название города переводим координаты с помощью Яндекс http-геокодера (внимание, нужно получить ключ).

Координаты скармливаем timezoner, который вернет нам часовой пояс пользователя.

Есть нюансы – оба сервиса имеют ограничения на количество запросов в сутки. Поэтому:
а) кешируем запросы к геокодеру для одинаковых городов;
б) когда человек вводит точную локацию, все равно прогоняем ее через геокодер, получаем город пользователя и работаем дальше с координатами центра города – таким образом для всех пользователей из Москвы можно будет сделать один запрос в timezoner.

Код модуля для определения часового пояса см. здесь.

4. Хранение пользовательских данных

Ранее мы отметили, что bot-brother умеет долгое время хранить данные, привязанные к конкретному пользователю. Эта функциональность реализована через Redis.

В более сложных ботах в Redis мы храним только небольшое количество пользовательских сессионных данных, а основную массу все же приходится размещать в полноценной базе данных (например в MongoDB).

Но для этого бота решили обойтись только Redis-ом.
Чтение пользовательских данных из хранилища происходит перед обработкой очередной команды, а запись назад в хранилище после цикла обработки очередной команды.

5. Отслеживание момента, в который нужно отправить нотификацию.

В других наших ботах требуется отправлять сообщения пользователям в определенное время суток. Для этого на сервере крутится процесс, которые проверяет время, проверяет записи в базе и регулярно отправляет оповещения.

Но для этого бота нашлось более прикольное решение. В Redis можно добавлять ключи с заданным временем жизни. Когда ключ протухает, Redis отправляет нам соответствующее событие. Вот собственно и все.
Как только нам нужно добавить уведомление, мы записываем в Redis ключ с нужным временем жизни, а дальше просто слушаем события и отправляем по ним уведомления пользователям.
Код.

6. Поиск времени или даты в фразе

Есть чудесная библиотека chrono-node, которая умеет искать время в английских фразах.
По аналогии дописываем код для русского языка.

Мы теперь более или менее представляем:
  • Как создается бот;
  • Как задается локализация;
  • Как регистрируются команды и их обработчики;
  • Как декларируются клавиатуры с вариантами ответов;
  • Как организовать хранение пользовательских данных;
  • Как организовать определение часового пояса пользователя;
  • Как вычленить дату и время из текста.

Дальше остается просто аккуратно запрограммировать все нужные команды для бота и отладить. Полную версию смотрим все в том же репозитории.

2 дня. Полет предсказуемый.

Мы опубликовали DeLorean в storebot два дня назад. Статистика:
  • 38 оценок, средняя оценка 4 звезды;
  • Вышли в тройку Best New Bots, попали в тематическую рассылку storebot;
  • 1500 уникальных пользователей.

Общечеловеческие рекомендации по созданию популярного бота


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

Почему важно иметь высокое место в рейтинге?
  • Чем выше бот, тем больше веротяность, что на него кто-то случайно наткнется.
  • Если бот поднимается наверх, он может попасть в рассылки storebot-а (Best New Bots, Top Chart Bots). Рассылки соответственно привлекут вам приличное количество новых пользователей.

Конечно же телеграм никогда не опубликует магические алгоритмы, по которым вычисляется рейтинг ботов. Тем не менее, у нас на эту тему есть гипотеза, которая кажется довольно правдоподобной.

Итак, рейтинг вашего бота больше всего зависит от недавних оценок в storebot. Если вашему боту за недавнее время поставили много положительных оценок (5 звездочек), то он с большой вероятностью поползет вверх в рейтингах.
Количество уников в боте и интенсивность его использования, похоже, никак не влияют на позицию в рейтинге. Иначе мы никак не можем объяснить, как наш Zodiac_bot умудряется обгонять в рейтингах, например, суперпопулярный бот Яндекс.Картинок :/

Исходя из этой мысли заключаем, что единственный способ продвинуть бота в сторе – не расстраивать целевую аудиторию бота и сделать пользователей максимально счастливыми.

Сейчас боты – это молодая и странная ниша. Ключевой особенностью подавляющего большинства ботов является непонятный интерфейс.
У автора статьи сформировалось субъективное ощущение, что боты пишут разработчики для разработчиков. И почему-то мало кто пишет ботов для людей.
Если вы делаете бота для разработчиков, то едва ли у вас получится поднять его высоко в рейтинге. Просто потому что непрограммисты будут путаться в интерфейсе и ставить низкие оценки. Ваш кэп.

В связи с этим несколько очевидных рекомендаций, как сделать удобного бота для пользователей-непрограммистов.

Клавиатуры вместо команд

Да, я знаю, что команды – это очень круто. Команды в консоли, команды в мессенджере – это ли не счастье?
Но, как ни удивительно, большая часть населения земного шара не любит вбивать команды.
Отсюда рекомендация №1: чтобы совершенно любой пользователь не впадал в ступор при работе с вашим ботом (даже ваша бабушка), всегда, практически на любом этапе работы с ботом, показывайте пользователю клавиатуру с возможными вариантами действий. Команды оставьте для гиков, пусть радуются.

Не надо спрашивать у людей сложные вещи

Эту мысль я уже в принципе раскрыла в разделе про определение часового пояса. Чем меньше пользователю надо подумать и кликнуть при работе с вашим ботом, тем больше шансов, что он не отвалится.

Не стесняйтесь использовать emoji

Особенность ботов – маленькое количество выразительных средств для создания привлекательных интерфейсов. Поэтому если у нас есть возможность делать кнопку с иконкой и текстом, ее нужно использовать.
Я допускаю, что многим не нравится искажения литературного письма вульгарными картинками, но emoji правда часто делают текстовый интерфейс более дружелюбным. Отличная иллюстрация – прогноз погоды.


Полюбите негативные отзывы

Много негативных отзывов – не самая страшная ситуация для продукта. Самая страшная реакция – никто не пользуется и ничего не пишет. Вот тут правда непонятно что делать.
А когда у вас есть негативные отзывы, вы можете:
а) доделать бота
б) исправить баги (если это багрепорты)
в) написать автору негативной оценки и пообщаться про бота

Мы активно практикуем все три подхода. Сережа много раз писал пользователям, оставившим какой-то непонятный фидбек с низким рейтингом, сообща они находили баг, чинили, и почти всегда пользователь возвращался, чтобы поставить более высокую оценку боту (что как мы знаем способствует его дистрибуции).

Лирическое отступление – самые прикольные отзывы оставляют пользователи дейтинг-бота.

А ведь Mehregan прав, а как же душа?..

Философские рассуждения о монетизации ботов


Теоретически мы понимаем, что если у нас есть аудитория 2000 человек в день, на ней хоть что-то можно заработать. Но практически совсем не понимаем, как.
Сейчас наша головная боль – растущие потребности погодного бота. Его аудитория растет, запросы в погодное апи растут и наши затраты на его поддержание тоже. Когда рост прекратится – непонятно.

Мы придумали три теоретических подхода к монетизации бота:
  1. Сделать кнопку для пожертвований. Плюс подхода – ненавязчивость. Минусы – скорее всего доход будет близкий к нулю.
  2. Платная подписка. Даем пользоваться ботом бесплатно, например, месяц, потом просим купить ключ к боту за доллар. Плюсы – точно не выйдем в минус. Минус – можем растерять всех пользователей.
  3. Размещение рекламы в боте. Плюсы – шансы заработать кажется есть. Минусы – можем сильно испортить карму.

Мы пробуем развить подход номер три, который про рекламу. Сережа написал платформу для размещения рекламы в ботах adbot.io. Почитать доку и посмотреть платформу можно на сайте платформы — adbot.io. Она совсем новая, пока в ней только наши боты и совсем нет рекламодателей. Это все пока чистой воды эксперимент, так что зовем всех неравнодушных поучаствовать. Нам очень хочется найти арбитражника, который согласится разместить в наших ботах рекламу (на первых порах можно даже бесплатно), чтобы просто понять, жизнеспособна ли рекламная биржа для ботов.

Если хоть какой-то из этих подходов позволит сделать ботов прибыльными (или хотя бы не убыточными), то видимо ниша небезнадежна. А если не позволит, видимо так и умрут ботики как красивый концепт.
Tags:
Hubs:
Total votes 26: ↑19 and ↓7+12
Comments19

Articles