В последнее время всё большую популярность обретают различные интерактивные способы завлечь аудиторию и привлечь к себе больше внимания. Тут и боты для социальных сетей и мессенджеров, и другие решения, придающие «уникальности». Среди них можно выделить и динамические обложки для сообществ, официально поддерживать которые ВКонтакте начали в марте.

Почему я решил написать эту небольшую статью? Хотя ажиотаж вокруг этой темы и спал, всё равно она остаётся довольно популярной, находятся как «клиенты», готовые платить очень большие деньги, так и желающие научиться это делать самому. Я работал с одной «студией», которая берет шестизначные суммы за эту работу, при этом кидая своих разработчиков и мелких клиентов. Так вот, чтобы в этой сфере не было монополии, и все увидели, насколько легко это делается, я и решил написать статью.


На примере моего пустого сообщества-песочницы

Вступление


Я опишу, как сделать динамическую обложку, отображающую текущее время и последнего подписчика. Любой другой функционал делается не сложнее — чуть больше строк кода и доступ к API других сервисов.

Что нам понадобится? Всего лишь подготовленный фон для обложки и access_token для группы с правами доступа к фотографиям. Привожу пример на Java, но сделать это можно и любым другим способом.

Статья рассчитана на более-менее опытных читателей — расписывать, как отправить GET запрос или авторизоваться в ВК через API я не стану.

Приступаем


Для начала реализуем транслирование новых подписчиков на обложку. Логика примерно следующая: получаем запрос от Callback API, берём оттуда id пользователя, по нему берём имя и аватар, накладываем на имеющийся фон и загружаем в ВК. Проще некуда. Поехали.

Обрабатываем запрос от Callback API


Выглядеть этот запрос будет примерно так:

{
  "type": "group_join",
  "object": {
    "user_id": XXXXXXXX,
    "join_type": "join"
  },
  "group_id": XXXXXXXX
}

Парсить JSON, я думаю, все умеют. Отсюда нам нужен только id пользователя, и по нему мы уже получаем имя, фамилию и ссылку на фотографию.

Достаточно сделать такой GET-запрос:

https://api.vk.com/method/users.get?user_ids=XXXXXXXX&fields=photo_max_orig&v=5.65

В ответ мы получим:

{
  "response": [
    {
      "id": XXXXXXXX,
      "first_name": "имя",
      "last_name": "фамилия",
      "photo_max_orig": "https:\/\/pp.userapi.com\/\/..."
    }
  ]
}

Всё, у нас есть вся необходимая информация, осталось добавить это на обложку и загрузить её.

Обрабатываем изображение


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

// Фоновое изображение и аватар пользователя
BufferedImage background_image = ImageIO.read(new File("/some/folder/bg.png")),
              user_avatar = ImageIO.read(new URL("https://..."));

// Результат - отдельное изображение
BufferedImage result = new BufferedImage(background_image.getWidth(), background_image.getHeight(), BufferedImage.TYPE_INT_ARGB);

// В качестве "холста" берём наше новое изображение
Graphics2D g = (Graphics2D) result.getGraphics();

// Рисуем фон
g.drawImage(background_image, 0, 0, null);

// Рисуем аватар подписчика
g.drawImage(user_avatar, x_avatar, y_avatar, width, height, null);

// Подписываем имя подписчика
g.drawString(user_name, x_name, y_name);

// Записываем результат на диск
ImageIO.write(result, "PNG", new File("/some/folder/result.png"));

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

Я не стал приводить простыни кода, помогающие на Java нормально уменьшать изображение и делать CircleCrop по центру, это легко пишется собственноручно либо спокойно гуглится. Также, настройку шрифтов и прочие мелкие моменты я тоже опустил.

В принципе, всё — мы получили готовую обложку, осталось только загрузить её. Просто, не правда ли?

Загружаем обложку


Всё делается очень просто и подробно описано в документации к API.

Получаем сервер для загрузки обложки, отправив GET-запрос:

https://api.vk.com/method/photos.getOwnerCoverPhotoUploadServer?group_id=XXXXXXXX&crop_x=0&crop_y=0&crop_x2=1590&crop_y2=400&access_token=ACCESS_TOKEN&v=5.64

Где ACCESS_TOKEN — токен с правами доступа к фотографиям группы.

Из ответа берём upload_url:

{
    "response": {
        "upload_url": "https://..."
    }
}

Теперь на наш upload_url отправляем POST-запрос с полем photo в формате multipart/form-data, точно также, как и с любыми документами. Я уже освещал этот вопрос в другой статье.

В ответ мы получим следующее:

{"hash":"402784f0ec814632ac","photo":"eyJvaWQiOi0zNzI3MzTUsMjAwIiwwLCIxNjgwLDEwNTAiLCI3OTUsNDk3Il0sImJ3YWN0Ijoib3duZXJfY292ZXIiLCJzZXJ2ZXIiOjYzODYyOSwibWlkIjoyMzE0ODUyLCc4MSwiZGF0YSI6WyJ4QUFtLXBRQUFBQUFtRUxmY0FBS3A2VEh4bU5WYmJKOG5ZQUFLcDZ2VkMtWjRVMXdmbk9BQUtwNnnMXVvUGdxYkNBQUtwN21nSGJwQlJJdnMxRhpdWM5bldkRktwQUFBS3A3R1NhdFptbFJWNlNCQUFLcDdVamJEFBS3A3NUktQnJTSHotS0hFQUFLcDhLVVRTbzA4VURpTSIsIjAsMCw3OJfc2lnIjoiNjNkNmQ5NmY1ZmI0NWFiYzdjYjZjMjliOGM5NWNhNWMifQ"}
пример от ВКонтакте

Всё, осталось сделать один GET-запрос и обложка засияет в сообществе:

https://api.vk.com/method/photos.saveOwnerCoverPhoto?hash=HASH&photo=PHOTO&access_token=ACCESS_TOKEN&v=5.65

Где HASH и PHOTO получены из предыдущего пункта, а токен всё тот же.

Готово, динамическая обложка заработала.

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

Ранее мы не зря сохраняли результат обработки в отдельный файл. Теперь мы сможем делать «многослойную» обложку, не теряя предыдущую информацию.

Например, вот так можно транслировать текущее время на обложку:

while (true) {
    // Спим минуту
    Thread.sleep(1000*60);

    // Берём текущее время в формате "20:25"
    String current_tine = new SimpleDateFormat("H:m").format(new Date());

    // Рисуем!
    BufferedImage result = ImageIO.read(new File("/some/folder/result.png"));
    Graphics2D g = (Graphics2D) result.getGraphics();

    g.drawString(current_tine, x_time, y_time);

    // Можно перезаписать изображение, или сразу его загружать
    // Или делать что душе угодно 
    ImageIO.write(result, "PNG", new File("/some/folder/result.png");
}

Это самый примитивный способ добиться нужного результата. Аналогично можно сделать любой функционал, благо Callback API предоставляет довольно обширные возможности: можно вычислять пользователей, которые сделали больше всех репостов, оставили больше всех комментариев, и так далее. Правда, с лайками придётся заморочиться, но это тоже не проблема. Курс валют, погода, пробки и прочие радости можно свободно получить через общедоступные API.

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

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

Правда, жаль, что у Facebook нет аналогичной возможности обновлять обложку.



P.S. В ответ на комментарии. Картинка в начале — просто демонстрация. Сообщество является моим полигоном для тестов и на постоянной основе там не работает ничего.
Поделиться с друзьями
-->

Комментарии (44)


  1. zxweed
    11.06.2017 19:35

    название студии в студию!


    1. PeterSamokhin
      11.06.2017 20:48
      +5

      Зачем? Я думаю, что Хабр не площадка ни для рекламы, ни для антирекламы :)
      Студия своё еще получит, ибо есть клиенты, которые собрались даже в суд подавать, а я помогу собрать материалы.
      И в целом, статья нацелена на то, чтобы больше людей увидели, что эта тема довольно проста в реализации и тоже могли заняться этим.
      Больше конкурентов — выше качество рынка :)


  1. ds_pro
    11.06.2017 21:25

    Неплохо)

    while (true) {
        Thread.sleep(1000*60);
        ...
    }
    


    1. PeterSamokhin
      11.06.2017 21:29
      +2

      Я написал, что это примитивнейшний способ и всего лишь пример :)


  1. Assargin
    11.06.2017 23:14
    +4

    Пипец… Шестизначные суммы возможность динамически формировать и обновлять картиночки в социальной сети. Я явно не тем занимаюсь.


    1. PeterSamokhin
      11.06.2017 23:28
      +1

      Вы не поверите, но я тоже этим не занимался, пока не увидел ценники. И крайне сильно был удивлён, осознавая сложность работы и понимая несоизмеримость цен :)


      1. Agel_Nash
        12.06.2017 04:34
        +1

        Ради интереса спросил у гугла стоимость подобного — от 1000 до 5000 т.р. Вы в какой валюте 6 знаков увидели?


        1. vlanko
          12.06.2017 08:51

          1 000, 00 :)
          А на самом деле, пока предложеняи мало, находятся люди какие хотят заработать много.


          1. Sliworez
            12.06.2017 11:51
            +2

            vlanko, ещё до введения API для обложки, гулял скрипт за чуть большей ценник, чем ваш «шестизнак» выше.

            Я тоже было запилил даже услугу на фрилансе, но интереса к ней не наблюдал. К тому же «конкуренты», уже через месяц-полтора реализовали подобный функционал прикрутив админку с виджетами и прочими плюшками.
            Чего бы не придумал, а это уже кто-то сделал)

            Agel_Nash так то, «5000 т.р.» это уже даже чуть больше чем шестизнак ;)


        1. PeterSamokhin
          12.06.2017 15:27

          Опять же повторюсь, что Хабр не место для рекламы, и если вы не нашли таких ценников, это не значит, что их нет :)


        1. ITMatika
          12.06.2017 17:34
          +1

          5000 т.р — это 7 знаков, если считать в рублях ;)


          1. Itachi261092
            13.06.2017 13:32

            а почему пробел не считается за знак?


    1. Sergiy
      12.06.2017 12:51
      +2

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


      1. PeterSamokhin
        12.06.2017 15:26
        +1

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


  1. AlexUsov
    11.06.2017 23:46

    Обновляется ли обложка без перезагрузки страницы браузера?


    1. PeterSamokhin
      11.06.2017 23:47

      Нет, конечно. Ни ВКонтакте, ни где либо еще, где есть возможность установить обложку, такого нет. В фейсбуке того хуже — вообще нельзя менять обложки через API.


      1. AlexUsov
        12.06.2017 10:42

        Ясно, спасибо. А насколько часто можно загружать новую обложку, есть ограничения со стороны ВК?


        1. PeterSamokhin
          12.06.2017 15:08

          Нет ограничений, можете хоть каждые 5 секунд обновлять.


        1. Kwent
          13.06.2017 14:35

          There can be maximum 3 requests to API methods per second from a client. © dev vk


          1. AlexUsov
            14.06.2017 13:24

            Спасибо


  1. lxsmkv
    12.06.2017 02:21

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

    На правах того, что это туториал, задам вопрос:

    https://api.vk.com/method/photos.saveOwnerCoverPhoto?hash=HASH&photo=PHOTO&access_token=ACCESS_TOKEN&v=5.65

    Как выглядит параметр PHOTO? Это кодированное содержание файла, это url ссылка, это путь к файлу на диске? Немного не ясно. Полный пример был бы полезен.


    1. PeterSamokhin
      12.06.2017 02:36

      Шестизначные суммы «студия» брала за крупные проекты с крупными клиентами вроде каналов, банков и проч. Никакой админки там не было.

      Насчёт вопроса по параметрам — все это подробно описано в документации ВК :)
      Конкретно параметр PHOTO — просто набор символов, возможно, хэшированная строка.


      1. PeterSamokhin
        12.06.2017 02:50

        Дополнил материал.
        А урл может быть статическим, может быть не статическим, мы просто каждый раз его получаем.
        Да, всё проще некуда: просто обрабатываем картиночку самыми примитивными способами и с помощью парочки GET-запросов загружаем её как обложку. Задача проще некуда и реализуема, наверное, на любом языке программирования.


        1. lxsmkv
          12.06.2017 03:14

          А, вот теперь я понял где пробел.

          Теперь отправляем на наш upload_url отправляем POST-запрос с полем photo в формате multipart/form-data, точно также, как и с любыми документами.
          На правах того, что это туториал:) хотелось бы пример запроса.


          1. PeterSamokhin
            12.06.2017 15:31

            Пример проще некуда: в качестве адреса, на который будет отправлен запрос, выступает наш upload_url, а телом POST-запроса будет наипростейший json:

            {"photo":"...."}

            Только не стоит забывать про multipart/form-data формат. Повторюсь: более подробно я описывал в другой статье, да и в интернете немало информации на эту тему :)


      1. tasty_brains
        12.06.2017 11:52
        +1

        Шестизначные суммы «студия» брала за крупные проекты с крупными клиентами вроде каналов, банков и проч.

        Товар стоит столько, сколько за него готовы заплатить. Каналы, банки и проч., на свои услуги не устанавливают минимально возможные наценки, которые позволяли бы им только зарплату сотрудникам выдавать. Отдельные цены для физ. лиц, отдельные цены для юр. лиц, зарплата не больше средней по городу и т. д. Так зачем я, банку, с миллиардной годовой прибылью, буду выставлять счет на 10 т.р., когда они могут позволить себе миллион?


        1. iig
          12.06.2017 14:36

          Откаты? Не может быть!


        1. PeterSamokhin
          12.06.2017 15:21

          Товар стоит столько, сколько за него готовы заплатить.

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


  1. PeterSamokhin
    12.06.2017 03:27

    lxsmkv писал в другой статье, на которую привёл ссылку, да и информации на эту тему предостаточно — не вижу смысла дублировать здесь велосипедный код :)


  1. Virviil
    12.06.2017 08:26

    Я так и не понял, что тут динамического.


    Я могу точно так же свой аватар менять, слушая всякие коллбэки


    1. PeterSamokhin
      12.06.2017 09:03

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


      1. lpwaterhouse
        12.06.2017 11:49

        Ее сразу же проматывают даже не смотря на нее.


        1. PeterSamokhin
          12.06.2017 15:22

          Не всегда. С чего бы тогда подобные акции собирали по несколько десятков тысяч комментариев за один вечер? :)


    1. Dromok
      12.06.2017 12:31

      А это кстати крутая идея. Только что можно выводить на аватар, чтобы это реально было интересно? Минимальная идея это менять фоточки, типа разные эмоции.


      1. StallinHrusch
        12.06.2017 14:41

        и каждый раз после такого у всех друзей будет в ленте «пользователь обновил фотографию на странице»?


        1. Dromok
          12.06.2017 14:44

          Нет, это же на собственную стену добавляется и не обязательно постить. Я лично всегда фото у себя обновляю без этой хрени.


          1. StallinHrusch
            12.06.2017 15:04

            вот только сейчас проверил — обновил аватарку. она появилась в ленте друзей


          1. mannaro
            12.06.2017 15:04

            Ну, вроде как, если обновлять через API отменить такое поведение нельзя.


  1. Veryhonest
    12.06.2017 11:51
    +1

    я так понял студия эта называется лайв ковер :) не ожидал такого от них


  1. mannaro
    12.06.2017 15:10

    Недавно СТС проводили такую рекламную кампанию, но у них все провалилось из-за того, что при каждом обновлении они вылезали в ленте. PeterSamokhin, подскажи, починили ли это сейчас? Или все также уведомление сыпется каждый раз?


    1. PeterSamokhin
      12.06.2017 15:16
      +1

      Так вот для СТС это и делала та самая студия. Починили или нет — не знаю, ту обложку делал не я, а связи со студией я разорвал.
      А какое уведомление появлялось в ленте? Если обновлять только обложку, в ленте не будет ничего, это проверено. Видимо, рекламная кампания предусматривала что-то ещё, что и появлялось в ленте: добавление фотографий в альбом и отправка их в комментариях, и так далее. Подобные вещи тоже практиковались, да, и когда фотографии добавляются в альбом, в ленте это появляется.


  1. perfect_genius
    13.06.2017 14:03

    Может дать ссылку на какую-нибудь такую группу? Хочется вживую увидеть.


    1. PeterSamokhin
      16.06.2017 00:07

      Снова увидел комментарий, хотел ответить. Но вспомнил — ответил Вам в личные сообщения :)


      1. perfect_genius
        16.06.2017 12:32

        Похоже, таки ответили, но потом исправили =)