Вконтакте умеет напоминать о днях рождениях push-уведомлениями, но это не всегда удобно, функционал приложений календарей намного обширней.
Собственно сразу результат: Ссылка на сервис
Дальше больше :)
Инструкция
Все работает довольно просто. Авторизуете приложение, даете ему доступ к друзьям. Сервис абсолютно безопасен, все исходные коды открыты, да и сам API не позволит сделать что-то плохое.
После выгрузки, полученный ics файл (это формат iCalendar) можно загрузить в любой календарь. P.S. Проверял пока только с Гугл календарем, но должно заработать везде.
Справка по импорту в google calendar: ссылка
Важно! Импортируйте в новый календарь, иначе, если что не так, придется потратить немало времени на чистку )
Техническая часть
Задача: Сделать так, что бы в календаре (например, google) можно было быстро добавить дни рождения друзей из vk. Было бы круто, увидеть список и выбрать записи для выгрузки.
Мысли: Логично, что сервис должен получиться легким, доступным всем, без установки, так же будет круто, если не потребуется ничего, кроме стандартного хостинга. Хм… JavaScript! У VK есть отличный SDK
Реализация: Круто, API есть, нужно подобрать модули, которые облегчат разработку. Гугл, StackOwerflow и GitHub мне в помощь. Вот что я нашел:
- Расширение Bootstrap-table
- Библиотека для создания ics
- Работа с датами Moment JS
Для приличного внешнего вида подключаю Bootstrap, так же без него не заработает плагин для работы с таблицей.
Для начала:
- Создаем приложение тут
- Тип выбираем веб-приложение.
- Для удобной локальной отладки в базовый домен добавляем localhost
- Запоминаем ID приложения
- Подключаем js API. Вот тут описано как
- Реализуем задуманный функционал
Логика работы и код:
- При загрузке проверяем, не авторизованы, ли мы уже
$(document).ready(function () { VK.Auth.getLoginStatus(function (r) { if (r.session) { console.log("Already auth"); uiLogin(); } else { console.log("Not auth"); } }); });
- Для авторизации вызываем соответствующий метод
VK.Auth.login( function (r) { if (r.session) { uiLogin(); } }, VK.access.FRIENDS );
- Получить информацию о пользователе
VK.Api.call( "users.get", {fields : "first_name,second_name"}, function (r) { if (r.response) { $("#userInfo").text(" Пользователь: " + r.response[0].first_name + " " + r.response[0].last_name); } } );
- Обращаемся к API вк, для получения списка друзей (метод «friends.get«). Запросим нужные нам поля
VK.Api.call( "friends.get", { order: "name", fields: "bdate,nickname,city,domain" }, function (r) { ... } );
Тут есть один момент. Города возвращаются как id, а не названия. Не порядок. В вк есть вспомогательный метод, для получения данных о городе по id («database.getCitiesById«), он отлично нам подходит, на вход нужно передать список id. Тянуть все города для страны — не корректно.
// Эта функция поможет вывести массив, только с существующими значениями // По сути так я добился от массива поведения похожего на java Set function fToStr() { var str = ""; for (i = 0; i < this.length; i++) { if (this[i] === undefined) continue; str += this[i]; if (i + 1 < this.length) str += ","; } return str; } Array.prototype.toStr = fToStr; // После получения ответа от вк, пробежимся по него и соберем все города var cityIds = []; filterResp.forEach(function (e) { cityIds[e.city] = e.city; }); // Для получения строчки 1,5,9 воспользуемся нашей функцией cityIds.toStr();
- Дальше подготовим данные для вывода таблицы. Здесь интерес представляет формат даты, приходящий от вк. Я написал такой код. Для людей, скрывших свой год, будем ставить 1900
// now Date from vk response var dt = e.bdate.split("."); var date; if (dt.length == 2) { // DD.MM date = new Date("1900", dt[1] - 1, dt[0]); } else { // DD.MM.YYYY date = new Date(dt[2], dt[1] - 1, dt[0]); }
- Инициализируем таблицу. Здесь все по документации плагина bootstrap-table.
- Таблица отрисована. Теперь ждем от пользователя, пока он выберет все нужные строки для экспорта.
- По нажатию кнопки экспорт, собираем все отмеченные строчки, создаем ивенты для календаря и экспортируем
var cal = ics("ru-RU"); c = 0; birtdayList.forEach(function (e) { if ($("input#"+e.uid).prop("checked")) { cal.addEvent( "ДР " + e.first_name + " " + e.last_name, e.link, e.city, e.birthday, e.birthday); c++; } }); alert("Будет выгруженно " + c + " дней рождений"); cal.download("vk-birtdays");
- Что бы создать ежегодно повторяющиеся мероприятия, я внес изменения в библиотеку. Измененная мной версия тут. Так же пригодилась спецификация формата iCalendar (ics)
Ссылка на проект в GitHub: sboychenko/vk-birthday-exporter