Как я сделала k2s-виджет для получения дополнительных продаж с форумов. Исходный код и описание алгоритма

Как я сделала k2s-виджет для получения дополнительных продаж с форумов. Исходный код и описание алгоритма

Slavegirl


Внешний вид виджета (курение может вредить вашему здоровью)


Как известно, практически на любом форуме для постинга 80-90% опубликованного материала — это бесполезный «мусор», который не приносит дохода владельцам сайта. Но часто бывает, что этот материал приводит трафик, который мне наконец захотелось нормально монетизировать. И делать это не с помощью сторонних рекламных площадок, перенаправляя посетителей непонятно куда, а напрямую, удерживая их на сайте в контексте файлообмена.


Существует несколько типов «мусорного» материала:

  • Это старые топики, скриншоты и ссылки на скачивание в которых уже давно нерабочие. Но за счёт наличия в некоторых из них ключевых слов для поиска, туда до сих пор приходят посетители из Google. Особенно если на других форумах эти посты за 2012-2017 годы уже почистили, а у тебя они ещё остались.
  • Топики, в которых постят ссылки на файлообменники, на которых нет доменных отчислений или они очень слабенько учитываются в статистике (uploaded.net, dfiles.eu, gigapeta.com и ещё 100+ других). На самом деле, из всего того разнообразия на рынке ФО количество партнёрок, которые приносят хоть какой-либо ощутимый доход владельцам сайтов, можно пересчитать на пальчиках одной руки.
  • Просто плохой материал с низкой конверсией или его некачественное оформление. Постеры часто сами не понимают что они постят, и не прекращают этого делать, даже если их файлы, размещённые на сотнях площадок по всему интернету, приносят всего $10-20 в месяц.


Так вот... мне захотелось внутрь всего этого «мусора» вставить в виде виджета частичку красиво оформленного материала, который действительно интересен посетителям и актуальный прям сейчас! Чтобы когда посетители попадают в самый плохой или даже полностью «мёртвый» топик, поднять вероятность продаж выше нуля. И собирать для виджета актуальные ролики не вручную, а чтобы это всё происходило автоматически. Для этой задачки идеально подошёл k2s-плеер и все связанные с ним инструменты (API и набор tube-миниатюр для каждого ролика).


Изначально я делала виджет для SMF-форума, поэтому с ним получилась тесная интеграция, и я опишу как я его «сочиняла» именно для этой платформы. Но с помощью описанного ниже алгоритма вы сможете переделать его абсолютно под любой другой форум или блог. И даже продавать его в виде отдельного дополнения.


Итак, приступим?


Исходный код


Keep2Share.php — файл для интеграции с форумом

Keep2ShareWidget.template.php — шаблон оформления виджета

k2s-preview.js — файл динамического создания видео-превью и виджета

Библиотека jQuery — требуется для работы k2s-preview.js

k2s-preview.css — стили оформления плеера и виджета


Сбор актуальных роликов


Создаём отдельную табличку в базе данных. В неё мы будем складывать данные всех роликов, которые смотрят посетители на форуме. У себя я её назвала smf_k2s_videos.


Структура таблицы


Так как роликов будет много, для экономии места в базе данных желательно не хранить там полные ссылки на файлы. Мы записываем только идентификатор файла (его длина — 13 символов), номер домена (0 — это k2s.cc, 1 — fboom.me, 2 — tezfiles.com), номер раздела на форуме, в котором находится ролик, количество и время его последнего просмотра.


Создаём поисковые индексы для полей, которые будут принимать участие в выборке (для ускорения выполнения запросов к базе данных).


Индексы полей


Когда табличка начнёт заполняться, она примет следующий вид:


Пример заполненной таблицы


Добавляем видео-превью на форум. Для этого я немножко переделала официальный код подключения плеера и преобразовываю k2s-ссылки в превьюшки с помощью функции createKeep2SharePreviews (k2s-preview.js). Но вы можете всё сделать как описано официальной в справке. В любом случае, на сайте должен появиться плеер, каким образом это будет выполнено — абсолютно неважно.


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


Добавляем в те места сайта, в которых мы хотим, чтобы регистрировались воспроизведения видео (у меня это странички всех топиков), JS-переменную, которая содержит номер текущего раздела и токен безопасности; функция keep2share_preview_after_template (Keep2Share.php):


   <script type="text/javascript">

      var k2sVideoLog = {

         boardId: ' . $context['current_board'] . ',

         sessionVar: "' . $context['session_var'] . '",

         sessionId: "' . $context['session_id'] . '"

      };

   </script>


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


Прикрепляем ко всем плеерам (их может быть несколько на страничке) событие, чтобы при клике по кнопке «Play» или обложке, когда пользователь запускает просмотр видео, можно было передать его идентификатор в базу данных (k2s-preview.js):


   $('#main_content').on('click', '.k2s-preview .play-btn, .k2s-preview .poster, .k2s_thumb', function() {

      // Получаем ссылку на ролик и отправляем запрос на добавление в базу данных. Параллельно, при желании, регистрируем событие в Google Analytics.

      logKeep2ShareVideo(url);

   });


Функция logKeep2ShareVideo (k2s-preview.js) извлекает из ссылки домен и идентификатор файла и отправляет GET-запрос на форум со следующими параметрами:


http://forum.com/index.php?action=k2s;sa=logvideo;host_id=0;video_id=28201e76c5d89;board_id=15;<session_var>=<session_id>

где:

host_id — номер домена (0 — k2s.cc, 1 — fboom.me, 2 — tezfiles.com);

video_id — идентификатор файла;

board_id — номер раздела, в котором кликнули по ролику;

<session_var>=<session_id> — токен безопасности.


Все такие GET-запросы мы «ловим» на форуме. Для этого я зарегистрировала действие ?action=k2s;sa=logvideo и если с полученными параметрами всё хорошо — аккуратненько кладу их в базу данных; функция Keep2Share (Keep2Share.php).


Обязательно проверяем GET-параметры на валидность, чтобы «доброжелатели» не подложили нам свинью в виде SQL-инъекции. Токен безопасности тоже желателен, иначе будем ловить ещё и CSRF-накрутки просмотров через межсайтовые запросы.


Сначала пробуем найти в базе данных запись о ролике по PRIMARY KEY (id_video). Если такая запись нашлась — обновляем все связанные с ней поля и увеличиваем счётчик просмотров на единичку. Если запись отсутствует — добавляем новую. Так запросы к БД будут выполняться чуточку быстрее.


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

  • Из-за нарушений правил форума и double-постинга, один и тот же ролик может находиться одновременно в нескольких разделах. Когда по нему кликнут впервые в «неправильном» разделе, в базе данных он так и останется записан навсегда, как принадлежащий нерелевантной тематике. А так есть шанс, что последующий просмотр из «правильного» раздела вернёт его в нужное место.
  • Постером могут использоваться несколько зеркал одного и того же файла в разных топиках. Если, к примеру, ссылку на k2s.cc, к которой «привязана» запись в базе данных, он удалит, а fboom.me оставит, то без обновления поля id_host тоже всё сломается без малейшего шанса на восстановление.


Далее один раз в день ищем в табличке все ролики, которые не просматривали в течение определённого времени и удаляем их, чтобы не засорять базу данных. У себя я храню ролики, по которым кликали последние 90 дней:


Небольшая панелька настроек Keep2Share превью


Функции из файла Keep2Share.php я интегрирую на форум с помощью Integration hooks (записи в табличке smf_settings с приставкой integrate_*). Так не приходится редактировать код форума, а выполнять всю работу в отдельных php-файлах. Подробнее об Integration hooks желающие могут почитать вот здесь.


Здесь хранится список интеграций от всех дополнений SMF


На этом процесс сбора роликов для виджета закончен.


Подготавливаем данные для виджета


Виджет состоит у меня из одной крупной превьюшки в виде плеера и 14 интерактивных миниатюр вокруг него. Всего 15 элементов.


Делаем выборку из таблички smf_k2s_videos, ищем 20 последних просматриваемых роликов из определённого раздела. Почему не 15? Объясню чуточку ниже. Но перед запросом к базе данных пробуем сначала получить нужный нам список роликов из кэша сервера (Keep2ShareWidget.template.php):


if (($k2s_videos = cache_get_data('k2s_videos_board-' . $board, 600)) == null)

{

   $request = $smcFunc['db_query']('', '

      SELECT id_video, id_host

      FROM {db_prefix}k2s_videos

      WHERE id_board = ' . $board . '

      ORDER BY last_view DESC

      LIMIT 20'

   );

   $k2s_videos = array();

   while ($row = $smcFunc['db_fetch_assoc']($request))

      $k2s_videos[] = $row;

   $smcFunc['db_free_result']($request);


   cache_put_data('k2s_videos_board-' . $board, $k2s_videos, 600);

}


Если кэш оказался пуст, после выполнения запроса помещаем результаты выборки снова в кэш, так мы сможем немножко снизить нагрузку на форум и избавиться от 1 постоянного запроса к БД. У себя я кэширую данные для виджета в течение 10 минут.


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


Получили список роликов? Перемешиваем его! Даже несмотря на то, что список мы (скорее всего) вытащили из статического кэша, при каждом обновлении странички миниатюры в виджете будут располагаться в произвольном порядке. Так намного лучше для визуального восприятия пользователями и повышения конверсии.


В этом списке нас интересуют идентификаторы роликов и номера доменов, к которым они относятся. «Склеиваем» их в единое целое, чтобы получить дли-и-инюющую нечитабельную строчку для переменной k2s_widget_data. Это нужно, чтобы защитить наши ссылки от роботизированных сканеров абузеров. Если публиковать ссылки в открытом html-виде, их можно будет легко обнаружить по поисковым шаблонам, собирать их на сайте и отправлять DMCA-жалобы на файлообменник. А с JavaScript-контентом ботики правообладателей (пока что?) работать не умеют...


В результате кодирования в месте добавления виджета должна получиться вот такая переменная:


Защита виджета от абуз


Шаблон виджета (код из файла Keep2ShareWidget.template.php) я добавляю в дополнение для вывода рекламы Ad Management. Так для меня намного удобнее: можно указать после какого поста вставлять виджет и в каких именно разделах это делать. И не нужно вносить лишние правки в код форума.


Дополнение Ad Management просто божественно!


Создаём виджет с помощью JavaScript


После окончания загрузки html-документа запускаем функцию createKeep2ShareWidget (k2s-preview.js). Функция проверяет наличие в памяти переменной k2s_widget_data, и если она определена, пытается разобрать вышеописанную длинную строчку на кусочки. Строка состоит из частей по 14 символов: 1-й символ — это код домена, 13 последующих — идентификатор ролика. Для каждой такой порции выполняем следующее.


Создаём IMG-элемент, присваиваем атрибуту "src" адрес:

https://api.<домен>/v1/files/<идентификатор_файла>/is-embeddable?asImage=1


Это специальный API-метод, который возвращает GIF-картинку размером 1х1 пикселей, если файл существует и для него можно создать плеер.


Ранее я упоминала, что из базы данных я запрашиваю 20 роликов, вместо 15. Дело в том, что на форуме могут быть малопопулярные разделы и там просматривают мало роликов. Соответственно, в виджет они добавляются медленно. И если выбрать точно 15 последних роликов, то некоторые из них могут оказаться уже удалены с файлообменника, и в виджете образуются пустые места. А так как я решила делать всё на JavaScript и переложить работу с API с сервера на «плечи пользователей», из-за кросс-доменных ограничений я не могу подлинно проверить валидный тот или иной файл или нет, чтобы сразу же удалять из базы данных нерабочие ролики при их первом обнаружении (проверочная картинка может не загрузиться и по вине браузера пользователя, а не файлообменника — это не слишком точная проверка существования файла). А так я пробую сразу загрузить 20 элементов (с небольшим запасом +30%), какие загрузились первыми в 15-местном виджете — те и остаются. При этом, пустые места если и появляются, то намного реже. И они находятся в конце виджета, а не в виде пробелов посредине — так тоже намного лучше в визуальном плане.


Итак... если проверочная картинка 1х1 пикселей загрузилась, значит с роликом всё хорошо и можно топать дальше.


Так как виджет у меня состоит из 1 плеера и 14 миниатюр, сначала проверяем, какой тип элемента нам нужно добавлять следующим: если плеер уже вставился — добавляем только миниатюры. Также проверяем, если виджет уже заполнен всем необходимым (имеет 15 элементов), останавливаемся, даже если осталась очередь из проверочных картинок.


С добавлением плеера всё просто: вставляем в виджет скрипт подключения, он сам в него трансформируется.


   previewScript = $('<script>')

      .appendTo(widget)

      .attr({

         'data-url': urlOf('file'),

         'src': 'https://' + host + '/js/preview.js'

      });


Главное, не забыть про его отдельные стили оформления в CSS-файле. А вот с миниатюрами придётся немножко повозиться...


Меняем атрибут "src" у созданного ранее IMG-элемента на следующий:

https://static-cache.<домен>/thumbnail/<идентификатор_файла>/main/0.jpeg


И только когда эта картинка загрузится — вставляем миниатюру в виджет. Иначе получим визуальные «глюки» в виде временно появляющихся пустых ячеек.


Назначаем миниатюре обработчики событий:

  • При наведении мышки сразу меняем атрибут "src" вот на такой:

https://static-cache.<домен>/thumbnail/<идентификатор_файла>/w320h240/0.jpeg


Загрузится первая небольшая картинка-слайд (всего их 10: от 0 до 9) из набора слайдов для туба. Так пользователь сразу же поймёт, что перед ним — интерактивный элемент и стоит задержать на нём курсор. И только потом запускаем таймер для слайдшоу с интервалом в 0.5 секунд. При каждой итерации просто увеличиваем индекс слайда на единичку, в конце возвращаемся снова на нулевой и т.д. При просмотре первого полного цикла слайдов у себя я отправляю событие в Google Analytics (мне нужно для сбора статистики по интересным превьюшкам).


  • После «бегства» курсора с миниатюрки останавливаем таймер и возвращаем атрибуту "src" изначальную картинку:

https://static-cache.<домен>/thumbnail/<идентификатор_файла>/main/0.jpeg


Вообще, использование картинки /main/0.jpeg для таких миниатюр — не совсем оптимальное, так как это скриншот из видеоролика в оригинальном разрешении и он загружается дольше, нежели картинки из специально для этого предназначенного набора /w320h240/0-9.jpeg. Пусть простят меня разработчики K2S, но main-картинки (именно они используются для обложек в их плеере) по сюжету выглядят намного более симпатичнее, чем уменьшенные слайды. Такое ощущение, что их там кто-то сидит и отбирает вручную!


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


Атрибут alt="<пробел>" в сочетании со стилем display: block; нужен, чтобы вокруг картинки не появлялась некрасивая рамка, если какой-нибудь слайд не загрузится из-за временной недоступности k2s-сервера.


Также к событиям "click" по миниаютрам я привязала повторную запись ролика в базу данных (см. выше описание функции logKeep2ShareVideo). Если картинка интересная и по ней кликают — она как можно дольше будет оставаться в виджете.


И ещё... в виджете я нигде не использую поле views из базы данных (количество просмотров каждого ролика). Изначально я хотела задействовать его для ранжирования, чтобы выводить наиболее интересные ролики в первую очередь. Но так как некоторые файлы, особенно самые популярные, могут быть удалены с файлообменника, такое ранжирование увеличит количество пустых мест в виджете, особенно, в малопосещаемых разделах. А дополнительные проверки на существование файла с помощью JS мне выполнять не сильно хочется... Поэтому оптимальным вариантом я пока решила оставить вывод только 15 последних роликов безо всякого ранжирования. Его уже я буду использовать на тубах, циферки из поля views там очень сильно пригодятся!


Итак, надеюсь, вы научились как сделать такой же k2s-виджет, как у меня. Теперь вперёд получать продажи из «мёртвых» топиков на форумах или таких же нежизнеспособных постов на блогах!


Спасибо за внимание.


С уважением,

Slavegirl


Telegram: https://t.me/pirategirl



Report Page