Конечно, каждый из нас любит подарки, но больше всего мы любим сопровождающие их пожелания. И, до недавнего времени, у нас не было возможности приятно удивить человека тёплыми словами, пока в голову не пришла идея: а что, если дать людям возможность обмениваться валентинками (на носу же 14 февраля, всё-таки) не выходя из рамок привычного способа общения — чатов социальной сети?
Слово за слово, и вот оно — готовый бизнес-план по созданию атмосферы праздника Дня всех влюбленных! Сделаем людей счастливыми?

Конечно, в первую очередь необходимо было составить план действий и описать идею. Из-за того, что люди стали более стеснительны, и не всегда готовы доверять кому попало, выбор пал на написание модного и удобного бота для ВК, который имеет знакомый интерфейс, всегда окажется под рукой, а анонимность сообщений будет жестко задана в коде программы.
К сожалению, помимо всех вышеописанных плюсов, у сообществ есть два минуса: низкая пропускная способность (количество сообщений в секунду) и запрет на старт диалога со случайным пользователем (пользователь должен первым и явно выразить своё согласие на поучение сообщений от имени сообщества).
Итак, мы имеем пользователя, готового отправить валентинку своей второй половинке, получателя и посредника в виде чат-бота. Схема взаимодействия проста, бот должен: предложить отправку → узнать получателя → сохранить до 14 февраля → доставить → повторить.
Но этого, конечно, оказалось мало для прожорливго на фантазию ума, и, в целях увеличения активности и вовлечённости аудитории, была продумана схема иного взаимодействия, позволяющего людям знакомится внутри системы, отправляя сообщения случайным людям. Эти «случайные валентинки» можно оценить, и если валентинки двух людей друг другу нравятся, мы даём им возможность пообщаться.
Этот проект создавался чисто на энтузиазме двумя людьми, программистом-недоучкой (мной) и идейным вдохновителем (Степаном sadfun Поповым), не несёт в себе цели чему-то вас научить (хоть и может помочь вам понять суть мироздания), лишь поведать интересную историю создания и проследить путь от идеи до наивной реализации.
Перебрав 3-4 различных библиотеки по запросу «NodeJS VK API», я понял, что нет простых и функциональных библиотек, позволяющих использвать промисы, а также работу через execute. Помните одну из проблем, описанных выше? Да, исполнение запросов к ВКонтакте не напрямую, а пачками по 25 позволяет в разы увеличить пропускную способность.

Сравнительная возможность различных методов запросов к ВКонтакте
Поэтому было принято решение написать что-то своё, надёжное и не очень костыльное решение, основываясь на библиотеке node-fetch.
Дабы не приводить здесь весь код, просто опишу логику работы.
Так как запросы из программы нужно упаковывать в один execute, они собираются в очередь LIFO, а затем отправляются, если:
Запросы из очереди компонуются в код VK Script, который (в этой реализации) выглядит так:
После выполнения кода запросом к ВК, результат каждого запроса (по индексу returnables) возвращается в свой callback, красиво обёрнутый в Promise. Эффективность подхода зашкаливает — чем больше пользователей (и, следовательно, больше запросов к ВКонтакте на отправку), тем меньше задержка ответа. Чтобы удерживать под контролем лимит, в системе отправки есть счётчик, показывающий количество оставшихся запросов на эту секунду, что позволяет быстро обрабатывать всплеск посетителей.
Всего способов получать уведомления о событиях из ВКонтакте есть два: Longpoll-запросы и Callback-сервер. Свой сервер удобен тем, что не требует особых телодвижений для использования, а также позволяет получить пропущенные уведомления (например, при перезагрузке сервера). Такой сервер можно написать в несколько строк, используя нативный класс http.Server.
Всё это создаёт идеальную экосистему для логики программы, которой удобно пользоваться.
Так как пользователь волен делать в чате всё, что угодно, и остановить мы его не в состоянии, нам нужно его ограничить разумными рамками. С этим отлично справляется конечный автомат, задавая каждый возможный переход внутри системы, а использование кнопок (параметр keyboard в messages.send) сделает использование бота простым, как одно касание экрана.
Вот схема взаимодействия пользователя с ботом:

Всё это превращается в набор состояний («Главное меню», «Ввод валентинки» и так далее), переходы между которыми заданы и передаются в кнопках, либо известны изначально и не меняются.

К слову, о кнопках. Их цветовая гамма невариативна (4 цвета на все случаи жизни), но именно кнопки заставляют свести количество ошибок пользователей к минимуму. На их основе можно построить совершенно любую нелинейную систему, именно поэтому они используются повсеместно. И в этом проекте тоже.
Но нужно понимать: если вы целитесь на большой охват аудитории, стоит продумать и иной способ взаимодействия, ведь у кого-то может оказаться старое приложение (VK for iPad, например, не обновлялся очень давно, врать не буду, но кажется, больше года, и поддержки клавиатур там нет). А бывает (да, бывает, я проверял), что люди, не понимая, что на кнопки можно нажимать, просто переписывают их содержимое (и тогда параметр кнопки payload, естественно, не передаётся, и всё может сломаться).
Надо заметить, что не всё бывает так гладко, как это описано на схеме, и иногда встречаются курьёзные случаи. Например, система определения ссылки ВКонтакте некорректно обрабатывала пользователей, короткие ссылки на которых начинались на id, и обрезала это. Удивление людей, встретившихся с этим багом, не описать, ведь они писали валентинку Феде, а получилось, что Олежке.
Итак, если с обычными валентинками всё понятно, есть получатель и отправитель, то как свести двух незнакомых людей? Надо обменять их валентинками, и если людям нравятся валентинки друг друга, то их стоит познакомить! Вот она, формула любви!
Хоть и звучит это пафосно, но работает, и людям становится интереснее работать с ботом — они получат позитивный отклик, если найдётся хоть один человек (о чём, естественно, бот сам позаботится).
Из этого вытекает большой плюс — чем больше людей воспользуются этой возможностью, тем больше шансов познакомится, а следовательно, это, как игра, удерживает человека в чате. Стоит признаться, сессия среднестатистического пользователя составляет ~7 минут, здесь же есть потенциал затянуть человека на 10-15 только ради этой фичи.
Сама рассылка сообщений заставила составила отдельную схему, так как имеется несколько вариантов использования этого бота, пользователь может упустить из виду что-то, а бот ему аккуратно об этом напоминает.

Интересно, как решилась вторая проблема, с невозможностью сообщества первым инициировать диалог с пользователем: теперь эта проблема решается таким сообщением.
Собственно, вот и всё! Если не учитывать некоторые сложности в понимании логики работы VK API, а также с подтверждением аккаунта у одного из провайдеров, всё прошло даже слишком гладко.

Пример чата с ботом
Бот работает и будет радовать людей валентинками, делая их счастливыми. Это сделано, чтобы помочь людям быть добрее друг к другу. Оценить всё это вы можете самолично в сообществе Валентиныч — vk.com/verylovebot, если желаете. Спасибо за внимание!
Слово за слово, и вот оно — готовый бизнес-план по созданию атмосферы праздника Дня всех влюбленных! Сделаем людей счастливыми?

За идеей на луну!
Конечно, в первую очередь необходимо было составить план действий и описать идею. Из-за того, что люди стали более стеснительны, и не всегда готовы доверять кому попало, выбор пал на написание модного и удобного бота для ВК, который имеет знакомый интерфейс, всегда окажется под рукой, а анонимность сообщений будет жестко задана в коде программы.
К сожалению, помимо всех вышеописанных плюсов, у сообществ есть два минуса: низкая пропускная способность (количество сообщений в секунду) и запрет на старт диалога со случайным пользователем (пользователь должен первым и явно выразить своё согласие на поучение сообщений от имени сообщества).
Итак, мы имеем пользователя, готового отправить валентинку своей второй половинке, получателя и посредника в виде чат-бота. Схема взаимодействия проста, бот должен: предложить отправку → узнать получателя → сохранить до 14 февраля → доставить → повторить.
Но этого, конечно, оказалось мало для прожорливго на фантазию ума, и, в целях увеличения активности и вовлечённости аудитории, была продумана схема иного взаимодействия, позволяющего людям знакомится внутри системы, отправляя сообщения случайным людям. Эти «случайные валентинки» можно оценить, и если валентинки двух людей друг другу нравятся, мы даём им возможность пообщаться.
Дисклеймер
Этот проект создавался чисто на энтузиазме двумя людьми, программистом
Учимся говорить с ВК
Перебрав 3-4 различных библиотеки по запросу «NodeJS VK API», я понял, что нет простых и функциональных библиотек, позволяющих использвать промисы, а также работу через execute. Помните одну из проблем, описанных выше? Да, исполнение запросов к ВКонтакте не напрямую, а пачками по 25 позволяет в разы увеличить пропускную способность.

Сравнительная возможность различных методов запросов к ВКонтакте
Поэтому было принято решение написать что-то своё, надёжное и не очень костыльное решение, основываясь на библиотеке node-fetch.
Дабы не приводить здесь весь код, просто опишу логику работы.
Так как запросы из программы нужно упаковывать в один execute, они собираются в очередь LIFO, а затем отправляются, если:
- Вызовов 25 или больше (максимум execute)
- Прошло достаточно времени с прошлой отправки, не меньше 50 миллисекунд, но не больше 150 (чтобы очередь двигалась, несмотря на маленький размер)
Запросы из очереди компонуются в код VK Script, который (в этой реализации) выглядит так:
var returnables = [];
returnables[0] = API.messages.send({"message": "Привет, Хабр!", "peer_id": 1, "random_id": 561427});
returnables[1] = API.users.get({"user_ids": 1, "fields": "sex"});
return returnables;
После выполнения кода запросом к ВК, результат каждого запроса (по индексу returnables) возвращается в свой callback, красиво обёрнутый в Promise. Эффективность подхода зашкаливает — чем больше пользователей (и, следовательно, больше запросов к ВКонтакте на отправку), тем меньше задержка ответа. Чтобы удерживать под контролем лимит, в системе отправки есть счётчик, показывающий количество оставшихся запросов на эту секунду, что позволяет быстро обрабатывать всплеск посетителей.
Учимся слушать ВК
Всего способов получать уведомления о событиях из ВКонтакте есть два: Longpoll-запросы и Callback-сервер. Свой сервер удобен тем, что не требует особых телодвижений для использования, а также позволяет получить пропущенные уведомления (например, при перезагрузке сервера). Такой сервер можно написать в несколько строк, используя нативный класс http.Server.
Всё это создаёт идеальную экосистему для логики программы, которой удобно пользоваться.
Всё когда-нибудь кончается
Так как пользователь волен делать в чате всё, что угодно, и остановить мы его не в состоянии, нам нужно его ограничить разумными рамками. С этим отлично справляется конечный автомат, задавая каждый возможный переход внутри системы, а использование кнопок (параметр keyboard в messages.send) сделает использование бота простым, как одно касание экрана.
Вот схема взаимодействия пользователя с ботом:

Всё это превращается в набор состояний («Главное меню», «Ввод валентинки» и так далее), переходы между которыми заданы и передаются в кнопках, либо известны изначально и не меняются.

К слову, о кнопках. Их цветовая гамма невариативна (4 цвета на все случаи жизни), но именно кнопки заставляют свести количество ошибок пользователей к минимуму. На их основе можно построить совершенно любую нелинейную систему, именно поэтому они используются повсеместно. И в этом проекте тоже.
Но нужно понимать: если вы целитесь на большой охват аудитории, стоит продумать и иной способ взаимодействия, ведь у кого-то может оказаться старое приложение (VK for iPad, например, не обновлялся очень давно, врать не буду, но кажется, больше года, и поддержки клавиатур там нет). А бывает (да, бывает, я проверял), что люди, не понимая, что на кнопки можно нажимать, просто переписывают их содержимое (и тогда параметр кнопки payload, естественно, не передаётся, и всё может сломаться).
Надо заметить, что не всё бывает так гладко, как это описано на схеме, и иногда встречаются курьёзные случаи. Например, система определения ссылки ВКонтакте некорректно обрабатывала пользователей, короткие ссылки на которых начинались на id, и обрезала это. Удивление людей, встретившихся с этим багом, не описать, ведь они писали валентинку Феде, а получилось, что Олежке.
Какой Олежка????
Случайности не случайны
Итак, если с обычными валентинками всё понятно, есть получатель и отправитель, то как свести двух незнакомых людей? Надо обменять их валентинками, и если людям нравятся валентинки друг друга, то их стоит познакомить! Вот она, формула любви!
Хоть и звучит это пафосно, но работает, и людям становится интереснее работать с ботом — они получат позитивный отклик, если найдётся хоть один человек (о чём, естественно, бот сам позаботится).
Из этого вытекает большой плюс — чем больше людей воспользуются этой возможностью, тем больше шансов познакомится, а следовательно, это, как игра, удерживает человека в чате. Стоит признаться, сессия среднестатистического пользователя составляет ~7 минут, здесь же есть потенциал затянуть человека на 10-15 только ради этой фичи.
Сама рассылка сообщений заставила составила отдельную схему, так как имеется несколько вариантов использования этого бота, пользователь может упустить из виду что-то, а бот ему аккуратно об этом напоминает.

Интересно, как решилась вторая проблема, с невозможностью сообщества первым инициировать диалог с пользователем: теперь эта проблема решается таким сообщением.
Но у меня есть условие! Чтобы получатель получил твою валентинку, он тоже должен написать мне. Твоя задача сейчас — уговорить его написать мне что-нибудь. Это сделано, чтобы у тебя не было страха заговорить с ним!В общем, традиционное «Не, баг, а фича!»
Фейерверк в конце
Собственно, вот и всё! Если не учитывать некоторые сложности в понимании логики работы VK API, а также с подтверждением аккаунта у одного из провайдеров, всё прошло даже слишком гладко.

Пример чата с ботом
Бот работает и будет радовать людей валентинками, делая их счастливыми. Это сделано, чтобы помочь людям быть добрее друг к другу. Оценить всё это вы можете самолично в сообществе Валентиныч — vk.com/verylovebot, если желаете. Спасибо за внимание!