Пользователь
0,0
рейтинг
4 августа 2014 в 13:31

Разработка → Пишем Instagram виджет для сайта. Инструкция для любопытных. Готовое решение для всех остальных из песочницы

image Недавно мне потребовалось интегрировать в сайт Instagram виджет. Чтобы пользователи видели последние опубликованные фотографии. Может даже подписывались.

Тут же выяснилось, что официального виджета у Instagram нет. Более того, с Instagram можно взаимодействовать исключительно через запросы к API. Никаких тебе JavaScript библиотек, генераторов кода и дизайна. Всё нужно делать руками.

Сразу нашлось множество сторонних сервисов разной степени платности и бесплатности. Объединяло их одно – клиент получает лишь код вызова виджета, всё остальное тянется с сервиса. Меня лично это не устраивало. Почему нет бесплатного standalone решения с открытым исходным кодом? Может быть я плохо искал? В общем, я решил внести свои пять копеек.

Инструкция по созданию виджета и готовое решение под катом.

Небольшое примечание. С момента написания этой статьи прошло уже семь месяцев. За это время виджет был установлен на около 80 ресурсах, создан репозиторий на GitHub, добрый человек подарил мне инвайт, виджет сменил механизм кэширования, обзавёлся собственным сайтом, добрые люди на его основе сделали плагин для CMS Битрикс, а я так и не нашёл аналогов в сети.

1. Требования к виджету:


Для начала сформулирую, что за виджет я хотел сделать.
Итак, виджет должен иметь:

  • Иконку Instagram;
  • Заголовок;
  • Фотографию профиля;
  • Статистику профиля;
  • Кнопку перехода к странице профиля;
  • Кликабельные фотографии;
  • Настраиваемое количество фотографий (общее количество и сколько выводить в строку);
  • Резиновый дизайн и автомаштаб фотографий в зависимости от нужной ширины виджета;
  • Вывод фотографий по хэш-тегу (добавилось в процессе);
  • Вставка виджета одной строчкой в HTML-код.

Вот, что получилось в итоге:
Демонстрация работы >

Пример в картинках:



А вот так вставляется в HTML:

<iframe src='/inwidget/index.php' scrolling='no' frameborder='no'></iframe>

Если заинтересовались, то приглашаю ознакомится с деталями реализации.

2. Регистрация сайта в Instagram:


На сайте Instagram есть документация к API. Вот прямая ссылка:
http://instagram.com/developer/



Сначала нас интересует раздел «Управлять программами». В нём на требуется зарегистрировать новое приложение (наш сайт), от лица которого и будет работать виджет. Так что переходим в этот раздел. Нажимаем кнопку «Регистрация новой программы» и заполняем форму:

  • Application Name – Название нашего приложение. Можете написать название сайта;
  • Description – Описание приложения;
  • Website – URL-адрес нашего сайта;
  • OAuth redirect_uri – URL на который перейдёт пользователь после авторизации. Т.к. у нас просто виджет и никого авторизовывать мы не будем, можно просто продублировать адрес нашего сайта.

Дальше нажимаем кнопку «Register».



После регистрации мы получаем два ключа. Нас интересует CLIENT ID. С ним мы будем работать в дальнейшем.

3. Получение данных через API:


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



Тут выясняется, что для получения каких-либо данных по аккаунту, нужно знать идентификатор этого аккаунта. Пользователи знают только свой логин, но не ID. Где же его взять?

Идентификатор можно подсмотреть в HTML-коде страницы профиля, а можно отправить запрос на вот этот URL:

https://api.instagram.com/v1/users/search?q=LOGIN&client_id=CLIENT_ID

Где LOGIN – это искомый логин в Instagram, а CLIENT_ID – это ключ, которые мы получили на этапе регистрация приложения. В результате мы получим JSON массив, который по мимо идентификатора также будет содержать URL аватарку пользователя.

Далее, для получения списка новых фотографий из нашего профиля, нужно отправить GET запрос на вот этот URL:

https://api.instagram.com/v1/users/USER_ID/media/recent/?client_id=CLIENT_ID

Где USER_ID – это идентификатор который мы получили из предыдущего запроса. Также в запрос можно добавить дополнительные аргументы. Перечень вы найдёте на странице документации.

Ну и последний запрос на получение статистики профиля:

https://api.instagram.com/v1/users/USER_ID/?client_id=CLIENT_ID

С получением данных разобрались. Приступаем к реализации.

4. Реализация виджета


Начну с неприятной новости. API Instagram явно ориентирован на полноценные приложения, а не простенькие виджеты для сайтов. От сюда вытекает две проблемы:

  1. К API можно отправить лишь 5000 запросов в час от одного CLIENT_ID или авторизованного пользователя;
  2. Нежелательно, чтобы CLIENT_ID был в свободном доступе, т.к. любой желающий может делать запросы на получение данных от имени вашего приложения.

Т.к. для просмотра виджета глупо просить авторизацию у посетителей, отправка/получение запроса занимает время, а наш сайт имеет 700 тыс. просмотров в день (до 80 000 запрос в час в вечернее время), нужно реализовать механизм кэширования данных.

В результате я решил, что виджет должен отрисовываться сервером. Поэтому релизация будет на PHP+HTML+CSS.
Подключать виджет будем через iframe.

4.1 Кэширование:

Первая версия виджета записывала кэш в БД MySQL, но затем я одумался и перенёс кэш в файл.
Как итог — выше скорость работы, меньше телодвижений с настройками, и не у всех есть MySQL.

Кэш хранится в формате JSON. Актуальность проверяется по дате последней модификации файла. Если кэш устарел, то происходит запрос к API на получение актуальных данных.

Если при отправке запроса происходит ошибка, то она с пояснением записывается в кэш как обычный текст. Если в кэше обычный текст, то он выводится вместо виджета. Запросы к API не будут отправляться пока кэш снова не устареет. Тем самым виджет не будет нагружать сервер регулярными запросами к API, если что-то пойдёт не так. И можно будет понять, почему виджет перестал работать.

4.2 Исходный код:

Отправляем запросы cURL, записываем данные в кэш, рисуем виджет с помощью HTML+CSS, пишем подробную инструкцию и занимаемся перфекционизмом ещё несколько бессонных ночей. В результате получилось вот это:

Скачать исходный код виджета (актуальная версия) >
Репозиторий на GitHub >

Самое интересное происходит в файле inwidget.php
config.php – отвечает за настройки, а template.php за вёрстку.
И, конечно, всё бесплатно. Всё для народа.

4.3 Как подключить виджет к сайту?:

Инструкция по шагам:

  1. Зарегистрируйте сайт в Instagram (обсудили в начале статьи).
  2. Скачайте исходный код виджета.
  3. Загрузите папку с виджетом на сервер.
  4. Установите права на запись для папки /inwidget/cache.
  5. Настройте параметры виджета (файл config.php).
  6. Вставьте виджет в сайт с помощью следующего кода:

Примеры вставки с различным отображением виджета
<!-- По умолчанию -->
<iframe src='/inwidget/index.php' scrolling='no' frameborder='no' style='border:none;width:260px;height:330px;overflow:hidden;'></iframe>

<!-- Без профиля -->
<iframe src='/inwidget/index.php?toolbar=false' scrolling='no' frameborder='no' style='border:none;width:260px;height:320px;overflow:hidden;'></iframe>

<!-- Мини 1 -->
<iframe src='/inwidget/index.php?width=100&inline=2&view=12&toolbar=false' scrolling='no' frameborder='no' style='border:none;width:100px;height:320px;overflow:hidden;'></iframe>

<!-- Мини 2 -->
<iframe src='/inwidget/index.php?width=100&inline=1&view=3&toolbar=false' scrolling='no' frameborder='no' style='border:none;width:100px;height:320px;overflow:hidden;'></iframe>

<!-- Горизонтальная ориентация -->
<iframe src='/inwidget/index.php?width=800&inline=7&view=14&toolbar=false' scrolling='no' frameborder='no' style='border:none;width:800px;height:295px;overflow:hidden;'></iframe>

<!-- Крупные preview -->
<iframe src='/inwidget/index.php?width=800&inline=3&view=9&toolbar=false&preview=large' scrolling='no' frameborder='no' style='border:none;width:800px;height:850px;overflow:hidden;'></iframe>

По своему вкусу можете настроить параметры вставки, которые передаются как GET параметры при обращении к скрипту:

  • width – ширина виджета (по умолчанию 260px).
  • inline – количество фотографий в строке (по умолчанию 4 шт.).
  • view – сколько фотографий отображать в виджете (по умолчанию 12 шт., максимально 30 шт., можно исправить в confing.php).
  • toolbar – отобразить тулбар с аватаркой и статистикой (значения true/false, по умолчанию true).
  • preview – размер и качество изображений (small – маленькие до 150px, large – большие до 306px, fullsize – полноразмерые до 640px, по умолчанию small).
  • lang – язык виджета (значения ru/en, по умолчанию берутся настройки из config.php). Приоритет этого параметра выше чем для настроек в config.php.

При изменении ширины или количества фотографий не забудьте изменить размер iframe.

Вот, собственно, и всё.

Сайт виджета: http://inwidget.ru
Репозиторий на GitHub: https://github.com/aik27/inwidget

P.S.: Буду рад отзывам, комментариям и обратной связи.

Пасхалка!
Это мой кот. Каждая строчка виджета написана под его неусыпным контролем. Несколько раз котэ вносил корректировки в процесс пробегая по клавиатуре. Уделяйте больше времени своим питомцам! Ловите смешные моменты с ними. Фотографируйте больше!


@VanZan
карма
13,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

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

  • 0
    Спасибо за исходники, давно хочу написать тулзу для себя, но все время было лениво, вы дали пинок!
    • +3
      Пожалуйста! Рад, что статья с подвигла к чему-то. Значит всё не зря.
  • 0
    кот очень порадовал…
    ну и за статью спасибо
  • 0
    А ещё есть SnapWidget для простой галереи фотографий.
    • 0
      SnapWidget не standalone. По крайне мере, бесплатная версия. В бесплатной просмотр фотографии осуществляется на их сайте, который завешан рекламой. В общем, это и отталкивало. Реклама, непрямые ссылки, скрипты тянутся с сервиса.
      • 0
        Такова плата за возможность использовать на неподдерживающих PHP сервисах.
  • 0
    Есть замечательная js-библиотечка instafeedjs.
  • 0
    В версии 1.0.3 исправлена ошибка из-за которой виджет мог начать транслировать фотографии другого пользователя.
    Ссылки в посте обновлены.
  • 0
    Виджет отличный, но почему-то у меня на WP не отображаются oembed инстаграм фото-видео в постах( подозреваю, что из-за него, пока не копал
    кто-то сталкивался?
  • 0
    С 17 ноября 2015 года всё значительно усложнилось, теперь все новые приложения рабоют в sandbox режиме, Review Process невозможно пройти до 3го декабря, кнопка Go Live недоступна, и API соответственно выдаёт {«meta»:{«error_type»:«OAuthAccessTokenException»,«code»:400,«error_message»:«The access_token provided is invalid.»}}
  • 0
    К сожалению, виджет совершенно не подходит для адаптивных макетов: нет способа автоматически узнать высоту виджета для заданных параметров. Приходится для каждой ширины вручную задавать высоту.

    Было бы очень удобно, если бы вместо установки количества выводимых фотографий нужно было задавать высоту виджета, а количество фотографий вычислялось бы автоматически в зависимости от заданной высоты.
    • 0
      Почему не подходит? Вёрстка кастомизируется как угодно.
      Пишите классы типа col-lg и всё
  • 0
    Отличная библиотека, спасибо большое
  • 0
    Виджет отличный! Только возникла проблема: access token у одного аккаунта стал меняться. С чем это может быть связано?

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