Динамическая обложка для группы ВК, последний подписчик, топ комментатор и прочее
Для установки динамической шапки требуется совсем немного, мы будем использовать компьютер как сервер, в дальнейшем сам скрипт можете установить на купленный сервер или обратиться в нашу группу для установки вашей шапки на ваше сообщество -> В личные сообщения сообщества KotOFF
Создание шапки происходит в 4 этапа, о них по порядку
1. Создание самой шапки.
2. Создание скрипта.
3. Установка OpenServer.
4. Настройка сервера и шапки.
1. Создание самой шапки.
Шапка должна иметь вот такой вид примерно:
На шапке заранее размещаете будущие отделы для аватарок и имен тех пользователей, который мы будем определять с помощью скрипта
Для создания такой шапки можно обратиться в группу, которая делает очень дешево такие шапки и оформления для сообществ — > В личные сообщения сообщества Тот самый Лев
На этом с 1 пунктом закончим, переходим к созданию скрипта
2. Создание скрипта.
Этот процесс самый трудоемкий, поэтому если Вы не хотите вдаваться в подробности, то можете сразу скачать архив и перейти к 3 и 4 пункту настройки.
Создаем файл с расширением api.php (Скрипт работает на версии php +5.6) и переходим в редактор Sublime Text или любой другой и вставляем туда этот код:
<?php require_once('config.php'); function DownloadImages($url, $filename){ $ch = curl_init($url); $fp = fopen($filename, 'wb'); curl_setopt($ch, CURLOPT_FILE, $fp); curl_setopt($ch, CURLOPT_HEADER, 0); curl_exec($ch); curl_close($ch); fclose($fp); } function getPOST($url, $post) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); //урл сайта к которому обращаемся curl_setopt($ch, CURLOPT_HEADER, false); //выводим заголовки curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); //теперь curl вернет нам ответ, а не выведет curl_setopt($ch, CURLOPT_POST, true); //передача данных методом POST curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36'); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); //тут переменные которые будут переданы методом POST $result = curl_exec($ch); curl_close($ch); return $result; } function getApiMethod($method_name, $params) { global $access_token; global $api_version; // Сделаем проверки на токен и версию апи, если их не указали, добавим. if (!array_key_exists('access_token', $params) && !is_null($access_token)) { $params['access_token'] = $access_token; } if (!array_key_exists('v', $params) && !is_null($api_version)) { $params['v'] = $api_version; } // Сортируем массив по ключам ksort($params); // Отправим запрос return(getPOST('https://api.vk.com/method/'.$method_name, $params)); } ?>
сохраняем и создаем еще 1 файл с названием config.php и вставляем в него следующий код:
<?php // KOTOFF.NET // Здесь вводим токен своего ПРОФИЛЯ а не сообщества. Получить можно здесь https://vkhost.github.io/ $access_token = 'ТОКЕН'; // ID группы $group_id = 'ИД ГРУППЫ'; // Круглые аватарки [true - круглые false - квадратные] $roundingOff = true; // Шрифт текста (положить свой в папку font) $font = "UniNeue-HeavyItalic.otf"; /* ----------------------- ПОСЛЕДНИЙ ПОДПИСАВШИЙСЯ ----------------------- */ // Показывать последнего подписчика [true - показывать false - нет] $show_last_subscribe = true; // Размер шрифта $last_subscribe_font_size = 20; // Цвет текста $last_subscribe_font_color = '255,255,255'; // Ширина аватарки $last_subscribe_width = 137; // Высота аватарки $last_subscribe_height = 137; // Координаты аватарки по оси Х $last_subscribe_photo_pixel_x = 44; // Координаты аватарки по оси Y $last_subscribe_photo_pixel_y = 66; // Координаты имени и фамилии по оси Х $last_subscribe_text_pixel_x = 108; // Координаты имени и фамилии по оси Y $last_subscribe_text_pixel_y = 235; /* ------------------------ ТОП ПО КОЛ-ВУ ЛАЙКОВ ------------------------ */ // Показывать пользователя который за сегодня набрал большее кол-во лайков к комментариям [true - показывать false - нет] $show_top_like = true; // Размер шрифта $top_like_font_size = 20; // Цвет текста $top_like_font_color = '255,255,255'; // Ширина аватарки $top_like_width = 137; // Высота аватарки $top_like_height = 137; // Координаты аватарки по оси Х $top_like_photo_pixel_x = 229; // Координаты аватарки по оси Y $top_like_photo_pixel_y = 66; // Координаты имени и фамилии по оси Х $top_like_text_pixel_x = 295; // Координаты имени и фамилии по оси Y $top_like_text_pixel_y = 235; /* ----------------------- ТОП ПО КОЛ-ВУ КОММЕНТОВ ----------------------- */ // Показывать пользователя который за сегодня оставил большее кол-во комментариев [true - показывать false - нет] $show_top_comments = true; // Размер шрифта $top_comments_font_size = 20; // Цвет текста $top_comments_font_color = '255,255,255'; // Ширина аватарки $top_comments_width = 137; // Высота аватарки $top_comments_height = 137; // Координаты аватарки по оси Х $top_comments_photo_pixel_x = 416; // Координаты аватарки по оси Y $top_comments_photo_pixel_y = 66; // Координаты имени и фамилии по оси Х $top_comments_text_pixel_x = 485; // Координаты имени и фамилии по оси Y $top_comments_text_pixel_y = 235; // Домашняя директория скрипта define('BASEPATH', str_replace('\\', '/', dirname(__FILE__)) . '/'); // Временная зона date_default_timezone_set('Europe/Moscow'); // Путь к финальному изображению. // Минимальный размер обложки 795 x 200 $output_header = BASEPATH.'header/output.png'; // Путь к изображению которое будет браться за основу. // Минимальный размер обложки 795 x 200 $image_bg = BASEPATH.'header/bg.jpg'; // Версия API $api_version = "5.63"; ?>
В данном коде нужно указать токен и ID самой группы. Токен должен быть пользовательский
Пример:
$access_token = 'd398d012e185e01edf145450b7899d90b49a6dfee30af063a788deb6a33219249db3463664cd4a0354a57';
$group_id = '176771278';
Теперь создаем директорию (папку) с названием header и туда загружаем нашу шапку с таким навзанием — bg.jpg
После этого нужно создать еще 1 папку, где будут хранится наши шрифты для имен пользователей, назовем ее font и загружаем туда наши шрифты, скачать можно ниже
Возвращаемся туда, где создавали наши файлы и создаем финальный файл под названием index.php и давайте более детальнее разберем этот код
<?php require_once('config.php'); require_once('api.php'); header('Content-type: text/html; charset=utf-8'); // Получим текущую дату $date_today = date('Ymd'); if($show_top_like or $show_top_comments) { setLog('Получаю посты группы'); // Получим посты со стены // больше 100 постов получать нет смысла, так как в вк ограничение // разрешено постить не больше 50 постов в сутки. $wall_get = getApiMethod('wall.get', array( 'owner_id' => '-'.$group_id, 'count' => '50' )); if($wall_get) { $wall_get = json_decode($wall_get, true); $countlike = array(); $countcomments = array(); foreach($wall_get['response']['items'] as $wall) { // Получим кол-во комментариев к посту $count = $wall['comments']['count']; $offset = 0; if($count > 0) { // Получим все комментарии, так как их может быть больше 100. while($offset < $count){ setLog('Получаю кол-во комментариев к посту '.$wall['id']); // Отправим запрос на получение комментариев $comments_get = getApiMethod('wall.getComments', array( 'owner_id' => '-'.$group_id, 'post_id' => $wall['id'], 'need_likes' => '1', 'count' => '100', 'offset' => $offset )); if($comments_get) { $comments_get = json_decode($comments_get, true); foreach($comments_get['response']['items'] as $comments) { if($date_today == date('Ymd', $comments['date'])) { // В двух словах мы заносим данные в массив, суммируя их if(!isset($countcomments[$comments['from_id']]) and !isset($countlike[$comments['from_id']])) { $countcomments[$comments['from_id']] = 1; $countlike[$comments['from_id']] = $comments['likes']['count']; } else { $countcomments[$comments['from_id']]++; $countlike[$comments['from_id']] += $comments['likes']['count']; } var_dump($comments); } } } if($offset<$count) $offset = $offset + 100; } } } } } if($show_top_like) { $day_like_top = 0; if(count($countlike) > 0) { // Теперь найдем кто суммарно получил большее кол-во лайков к комментариям $value = max($countlike); $day_like_top = array_search($value, $countlike); setLog('Получаю ID кто сумарно набрал большее кол-во лайков к комментариям '.$day_like_top); if($day_like_top > 0) { $user_top_like = getApiMethod('users.get', array( 'user_ids' => $day_like_top, 'fields' => 'photo_200' )); if($user_top_like) { $user_top_like = json_decode($user_top_like, true); $top_like_name = $user_top_like['response'][0]['first_name']; $top_like_lastname = $user_top_like['response'][0]['last_name']; $top_like_photo = $user_top_like['response'][0]['photo_200']; // Скачиваем фото if(!empty($top_like_name) && !empty($top_like_lastname) && !empty($top_like_photo)){ DownloadImages($top_like_photo, 'header/top_likes.jpg'); } } } } } if($show_top_comments) { $day_comment_top = 0; if(count($countcomments) > 0) { // Теперь найдем кто суммарно написал больше всех комментариев $value = max($countcomments); $day_comment_top = array_search($value, $countcomments); setLog('Получаю ID кто суммарно написал больше всех комментариев '.$day_comment_top); if($day_comment_top > 0) { $user_top_comment = getApiMethod('users.get', array( 'user_ids' => $day_comment_top, 'fields' => 'photo_200' )); if($user_top_comment) { $user_top_comment = json_decode($user_top_comment, true); $top_comment_name = $user_top_comment['response'][0]['first_name']; $top_comment_lastname = $user_top_comment['response'][0]['last_name']; $top_comment_photo = $user_top_comment['response'][0]['photo_200']; // Скачиваем фото if(!empty($top_comment_name) && !empty($top_comment_lastname) && !empty($top_comment_photo)){ DownloadImages($top_comment_photo, 'header/top_comments.jpg'); } } } } } if($show_last_subscribe) { // Теперь найдем последнего подписчика $last_subscribe = getApiMethod('groups.getMembers', array( 'group_id' => $group_id, 'sort' => 'time_desc', 'count' => '1', 'fields' => 'photo_200', 'access_token' => $access_token )); if($last_subscribe) { $last_subscribe = json_decode($last_subscribe, true); $members_count = $last_subscribe['response']['count']; $last_subscribe_firstname = $last_subscribe['response']['items'][0]['first_name']; $last_subscribe_lastname = $last_subscribe['response']['items'][0]['last_name']; $last_subscribe_photo = $last_subscribe['response']['items'][0]['photo_200']; setLog('Получаю последнего вступившего в группу '.$last_subscribe_firstname.' '.$last_subscribe_lastname); // Скачиваем фото if(!empty($last_subscribe_firstname) && !empty($last_subscribe_lastname) && !empty($last_subscribe_photo)){ DownloadImages($last_subscribe_photo, 'header/last_subscribe.jpg'); } } } sleep(3); if($show_weather){ $ResultWeatherApi = getPOST('http://api.openweathermap.org/data/2.5/weather', array( 'id' => $weather_city_id, 'units' => 'metric', 'CNT' => '1', 'lang' => 'ru', 'appid' => $weather_api_id )); $s = array( 'id' => $weather_city_id, 'units' => 'metric', 'CNT' => '1', 'lang' => 'ru', 'appid' => $weather_api_id ); } // ----------------------------------------------------------------------------- // --------------------------------- РИСОВАНИЕ --------------------------------- // ----------------------------------------------------------------------------- setLog('Создание обложки'); $draw = new ImagickDraw(); $bg = new Imagick($image_bg); $draw->setFont(BASEPATH."/font/".$font); $draw->setTextAlignment(Imagick::ALIGN_CENTER); // Последний подписчик if($show_last_subscribe) { $file_name = BASEPATH.'header/last_subscribe.jpg'; if(file_exists($file_name) && $show_last_subscribe) { $last_subscribe_photo = new Imagick($file_name); if($roundingOff==true) { RoundingOff($last_subscribe_photo, $last_subscribe_width,$last_subscribe_height); } $draw->setFontSize($last_subscribe_font_size); $draw->setFillColor("rgb(".$last_subscribe_font_color.")"); $bg->compositeImage($last_subscribe_photo, Imagick::COMPOSITE_DEFAULT, $last_subscribe_photo_pixel_x, $last_subscribe_photo_pixel_y); $bg->annotateImage($draw, $last_subscribe_text_pixel_x, $last_subscribe_text_pixel_y, 0, mb_strtoupper($last_subscribe_firstname."\n".$last_subscribe_lastname, 'UTF-8')); } } // Топ по комментам $file_name = BASEPATH.'header/top_comments.jpg'; if(file_exists($file_name) && $show_top_comments) { $top_comments_photo = new Imagick($file_name); if($roundingOff==true) { RoundingOff($top_comments_photo, $top_comments_width,$top_comments_height); } $draw->setFontSize($top_comments_font_size); $draw->setFillColor("rgb(".$top_comments_font_color.")"); $bg->compositeImage($top_comments_photo, Imagick::COMPOSITE_DEFAULT, $top_comments_photo_pixel_x, $top_comments_photo_pixel_y); $bg->annotateImage($draw, $top_comments_text_pixel_x, $top_comments_text_pixel_y, 0, mb_strtoupper($top_comment_name."\n".$top_comment_lastname, 'UTF-8')); } // Топ по лайкам $file_name = BASEPATH.'header/top_likes.jpg'; if(file_exists($file_name) && $show_top_like) { $top_like_photo = new Imagick($file_name); if($roundingOff==true) { RoundingOff($top_like_photo, $top_like_width,$top_like_height); } $draw->setFontSize($top_like_font_size); $draw->setFillColor("rgb(".$top_like_font_color.")"); $bg->compositeImage($top_like_photo, Imagick::COMPOSITE_DEFAULT, $top_like_photo_pixel_x, $top_like_photo_pixel_y); $bg->annotateImage($draw, $top_like_text_pixel_x, $top_like_text_pixel_y, 0, mb_strtoupper($top_like_name."\n".$top_like_lastname, 'UTF-8')); } $bg->setImageFormat("png"); $bg->writeImage($output_header); //echo '<img src="'.'header/output.png'.'">'; // ----------------------------------------------------------------------------- // --------------------------- ЗАГРУЗКА НА СЕРВЕР ------------------------------ // ----------------------------------------------------------------------------- // Получим адресс сервера $getUrl = getApiMethod('photos.getOwnerCoverPhotoUploadServer', array( 'group_id' => $group_id, 'crop_x2' => '1590' )); setLog('Получаю адресс сервера '.$getUrl); if($getUrl) { $getUrl = json_decode($getUrl, true); $url = $getUrl['response']['upload_url']; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_POSTFIELDS, array('photo' => new CURLFile($output_header, 'image/jpeg', 'image0'))); $upload = curl_exec( $ch ); curl_close( $ch ); if($upload) { $upload = json_decode($upload, true); $getUrl = getApiMethod('photos.saveOwnerCoverPhoto', array( 'hash' => $upload['hash'], 'photo' => $upload['photo'], )); setLog('Загружаю обложку '.$getUrl); if(stripos($getUrl, 'response":{"images":[{')) { print_r('Успешно загрузили обложку <a href ="https://kotoff.net/ target="_blank" >kotoff.net</a></br>'); echo '<p>*** Больше всех сегодня лайков набрал: <a href ="https://vk.com/id'.$day_like_top.'" target="_blank" >'.$top_like_name.' '.$top_like_lastname.' - '.$countlike[$day_like_top].'</a> шт.</p></br>'; echo '<p>*** Больше всех сегодня комментариев написал: <a href ="https://vk.com/id'.$day_comment_top.'" target="_blank" >'.$top_comment_name.' '.$top_comment_lastname.' - '.$countcomments[$day_comment_top].'</a> шт.</p></br>'; echo '<p>*** Последний подписчик <a href ="https://vk.com/id'.$day_like_top.'" target="_blank" >'.$last_subscribe_firstname.' '.$last_subscribe_lastname.'</a></p></br>'; echo '<br><img src="'.'header/output.png'.'">'; setLog('Загружаю обложку в '.$group_id); } else { print_r('Ошибка при загрузке обложки '.$getUrl); setLog('Ошибка при загрузке обложки '.$getUrl); } } } function RoundingOff($_imagick, $width, $height) { $_imagick->adaptiveResizeImage($width, $height, 100); $_imagick->setImageFormat('png'); $_imagick->roundCornersImage( 90, 90, 0, 0, 0 ); } function setLog($message) { $log_file_name = 'logs.txt'; if(file_exists($log_file_name)) { $log = array_diff(explode("\r\n", file_get_contents($log_file_name)), array('')); } $log[] = date("m.d.Y-H:i:s").' | '.$message; if(file_put_contents($log_file_name, implode("\r\n", $log))) { return true; } else { return false; } } ?>
Данный код собирает посты и с помощью циклов считает лайки, комментарии и определяет последнего вступившего. Код полностью рабочий, более детальную настройку рассмотрим в 4 пункте данной статьи. У данного скрипта есть несколько недоработок, часть из них была уже исправлена, для платных групп мы используем собственную версию скрипта. Сохраняем все файлы и переходим к 3 пункту настроек.
3. Установка OpenServer.
Для работы шапки нам потребуется сервер, а что бы не покупать и не платить деньги, мы будем использовать Open Server Panel — это портативная серверная платформа и программная среда для разработки
Переходим на официальный сайт и скачиваем дистрибутив-> Скачать Open Server
Нам предлагают на выбор 3 версии дистрибутива (ULTIMATE PREMIUM BASIC) с различным включенным функционалом, нам подойдет самый простой — BASIC, но если есть возможность, советую скачивать ULTIMATE версию!
После скачивания, распаковываем архив в удобное для Вас место, у Вас появится папка OSPanel
Заходим в нее и запускаем наш сервер
В трее, у Вас появится красный флажок, сервер нужно запустить выбрав зеленый
После запуска, там же выбираем Папка с сайтами и открываем уже созданный каталог с сайтом localhost, удаляем все что там есть и загружаем наши созданные файлы
Все готово, переходим к настройке и запуску.
4. Настройка сервера и шапки.
После успешной настройки, переходим к настройке, перейдя в браузере по адресу — http://localhost/index.php:
Если получили Warning похожий на этот:
То Вам нужно проверить правильно ли Вы указали токен профиля или ID группы, получить ID группы можно перейдя настройки сообщества
Если у Вас стоит короткое название, то просто откройте любую фотографию в группе и скопируйте ID с браузерной строки, все что после photo-ID_ЦИФРЫ (без минуса):
Если же Вы получили шапку:
Это значит что Вы сделали все правильно, давайте перейдем в группу, напишем пост, комментарий и поставим лайк:
Снова переходим на — http://localhost/index.php и смотрим что у нас получилось:
Как видим все работает, аватарки и текст можно перемещать, так как в Вашей шапке расположение может быть другое как тут например
Для этого открываем файл config.php
И меняем координаты, это один из трудоемких процессов, так как здесь нужно будет поиграться с положением и найти те самые координаты, примерное расположение можно узнавать используя Paint, наводим курсор в верхнюю правую точку устанавливаемого аватара и ниже получаем координаты:
Это условные координаты по оси Х и Y, далее просто смещаете по несколько пикселей в одну из сторон и находите оптимальную точку.
Настройка на этом практически завершена. Осталось сделать так, что бы скрипт сам обновлял ее, допустим каждые 5 минут, заходим в настройки OpenServer из трея и выбираем вкладку планировщик задач, прописываем команду:
%progdir%\modules\wget\bin\wget.exe -q —no-cache http://localhost/index.php
И указываем тайминги, в какое время нужно запускать скрипт, мы выставили что бы скрипт запускался каждые 5 минут в любой час, день, неделю и месяц, нажимаем добавить и сохраняем, сервер сам перезагрузится и планировщик задач начнет выполнять команду в указанные временные интервалы
При желании, можете загрузить скрипт на хостинг, и использовать CRON для запуска этого скрипта в нужное время.
На этом у меня все, пишите свои комментарии, задавайте вопросы, мы постараемся ответить на них, всем динамичных шапок