{"id":14291,"url":"\/distributions\/14291\/click?bit=1&hash=257d5375fbb462be671b713a7a4184bd5d4f9c6ce46e0d204104db0e88eadadd","hash":"257d5375fbb462be671b713a7a4184bd5d4f9c6ce46e0d204104db0e88eadadd","title":"\u0420\u0435\u043a\u043b\u0430\u043c\u0430 \u043d\u0430 Ozon \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u0442\u0430\u043c \u043d\u0435 \u043f\u0440\u043e\u0434\u0430\u0451\u0442","buttonText":"","imageUuid":""}

Как мы на сайте автопостинг внедряли

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

В первую очередь после того, как автор подготовил статью, она попадает к нашему редактору. Задача редактора оценивать этику контента, и при необходимости помогать автору в редактировании статьи. Затем редактор размещает статьи на сайте, и контент попадает к нашему читателю.

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

Для того чтобы проводить кросспостинг публикаций с сайта, мы использовали стороннее решение, которое по факту требовало от редактора двойную работу – помимо размещения статьи на сайте, контент частично нужно было размещать в SMM-планере и выставлять время с разницей, чтобы сначала статья вышла на сайте, а через минуту уже в социальных сетях.

Поэтому перед нами была поставлена задача: автоматизировать размещение статей с сайта и исключить лишнюю работу для наших редакторов.

Разработка решения делалась для трёх социальных сетей — «ВКонтакте», Telegram, Facebook (о каждом из них расскажем подробнее).

Для начала добавляем хук в нашу систему СMS на изменение статуса записи.

// Хук срабатывает на изменение статуса записи add_action( 'transition_post_status' , 'sendContentToSocial' , 10,3 );

Обязательно проверяем, чтобы наш хук не срабатывал на обновление записи, а только на изменение статуса на «опубликован».

If( 'publish' === $new_status && 'publish' !== $old_status && 'post' === &post->post_type )

«ВКонтакте»

Для начала работы с VK API переходим по ссылке и создаем новое Singletone приложение.

Далее переходим в настройки приложения, и все что нам нужно — ID приложения.

Для получения токена доступа к методам API от имени вашей страницы нужно сделать запрос по открытому протоколу Oauth. В строке браузера формируем строку, подобной ниже, где:

Client_id — ID вашего приложения.

Scope — разрешения, которые вы запрашиваете. Конкретно для этой задачи нам потребовались photos (загрузка фото), pages (доступ к странице), groups (доступ к группам).

Переходим по сформированной ссылке и даем доступ приложению к запрошенным разрешениям.

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

Чтобы отправить пост на стену, нужно сформировать запрос на серверной части сайта. Все необходимые данные мы получаем из встроенного массива $post (создается в момент изменения статус записи)

Для того чтобы добавить картинку посту, грузим вложение на сервер, а после добавляем ID, полученный от сервера к запросу в API. Затем, используя метод API wall.post, отправляем запрос и пост появляется группе. В ответ приходит post_id, по которому можно легко найти наш опубликованный пост!

$post_image=$_SERVER['DOCUMENTROOT'].substr($post_image, strlen($_SERVER['SERVERNAME’])+8); // Узнаем сервер VK куда будем запивать изображение, $photoServerName=json_decode(file_get_contents('https://api.vk.com/method/photos.getWallUploadServer?group_id=’.$vkgroup.'&v=5.37&access_token=’.$vk_token)); // Заливаем изображение на сервер. $photoServerUpload=json_decode(curlPost($photoServerName->response->upload_url, $post_image)); // Сохраняем изображение., как фото к посту на стене. $photoServerSave=json_decode(file_get_contents('https://api.vk.com/method/photos.saveWallPhoto?group_id='.$vk_group.'&photo='.$photoServerUpload->photo.'&server='.$photoServerUpload- -server. 'fihash=' .photoServerUpload-J-hash. ' 8v=5.37&access_token=' .fvk_token)) j //Узнаём ID залитого изображения. uploadedPhotoID = $photoServerSave->response[0]->id; // Формируем запрос для отправки поста. $st_zap='https://api.vk.com/method/wall.post?owner_id»-'.$vk_group.'&friends_only=0&from_group=l&message='.urlencode($post_text).’attachments='; // Если изображение было загружено., то добавляем его. if(mb_strlen($uploadedPhotoID)) { $st_zap .= 'photo'.$photoServerSave->response[0]->owner_id.'_'.uploadedPhotoID.; } // Добавляем URL и завершаем формировать запрос. $st_zap .= $post_url.'&v=5.37&access_token=‘.$vk_token; // Отправляем сформированный запрос. $st_res = json_decode(file_get_contents(str_replace(' ', '%20', $st_zap))); // Узнаём ID опубликованного ВКонтакте поста. $st_id = $st_res->response->post_id;

Функцию CURL выделяем отдельно, для отправки запроса по нужному URL.

// Функция cURL. function curlPost($url, $img) { if(!isset($url) || !isset($img)) { return false; } $ch « curl_init(); curl_setopt($ch, CURLOPTJJSERAGENT, $_SERVER['HTTP_USER_AGENT’]); curl_setopt($ch,CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($chj CURLOPT_URL, $url); curl_setopt($chj CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, ['filel' => new CurlFile($img)]); $response = curl_exec($ch); curl_close($ch); echo $response; return $response;}

Telegram

Все действия, которые мы будем совершать, обязательно требуют наличие бота.

Бота нужно зарегистрировать и получить его ID, являющийся в том числе и токеном. Для этого в Telegram существует специальный бот — @BotFather.

Отправляем сообщение /start и в ответ получаем список его методов. Следом пишем /newbot, отправляем, и бот попросить придумать новое имя вашему боту. Название обязательно должно оканчиваться на «bot».

В случае успеха BotFather возвращает токен бота и ссылку для быстрого добавления бота в контакты. Полученных данных достаточно для начала работы с API. Подключаем VPN и начинаем читать документацию.

Не забудьте проверить полученный токен с помощью ссылки

api.telegram.org/bot<TOKEN>/getMe

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

Конечная функция, которая отправляет в группу сообщение, приведена ниже:

function sendMessage($chatID, $articleLink, $articleExcerpt, $articlePictureUrl, $token) { $finalMessage = $articleExcerpt . " " . $articIeLink; $bot_url = "https://api.telegram.org/bot- . $token; $url = $bot_url . "/sendPhoto?chat_id=" . $chatID ; $post_fields = array('chat_id' => $chatID, 'photo' => $articlePictureUrl 'caption' => $finalMessage ); $ch = curl_init(); curl_setopt($ch, CURUDPTHTTPHEADER, array ( "Content - Type: multipart/form-data" )); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOFT_SAFE_UPLOAD, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); $output = curl_exec($ch); echo $output; curl_close($ch); return $output;

Facebook

Чтобы получить доступ к работе с Facebook API, нам потребуется создать приложение, разработать прототип, а после уже пройти App Review.

Создаем приложение по ссылке → Сreate new App.

После создания приложения переходим на его страницу и видим основные параметры приложения, которые понадобятся нам в будущем (App ID и App Secret):

Так как мы разрабатываем решение для сайта, правила Facebook требуют наличия политики конфиденциальности на сайте. Ссылку на нее вставляем в поле Privacy Policy URL. После внизу нажимаем «Добавить платформу», выбираем Web App и прописываем в полях, где написано URL, название сайта.

Приложение будет реализовать функцию «Войти через Facebook», соответственно все те страницы, которые будут использованы в прототипе, нужно обязательно внести в поля «Действительные URI для перенаправления OAuth».

После подготовки всех нужных данных приступаем к разработке прототипа.

Facebook предоставляет свой SDK для работы с методами, поэтому качаем его с официального аккаунта на Github и включаем в проект. Также можно подключить с использованием composer.

Чтобы пройти App Review, нам понадобилось три страницы:

  • Первая страница должна обрабатывать данные постера и позволять пользователю получить тот самый заветный токен страницы через свою учетку Facebook. Cама страница состоит из простейшей разметки HTML и скрипта JavaScript, который шлет POST-запросы на наш callback.php.
  • Вторая страница (callback.php) обрабатывает действия пользователя и выводит в конце токены к тем страницам, к которым он разрешил доступ.
  • Третья страница (sendpostfb.php) отправляет данные поста в Facebook.

На всех страницах всегда проверяем сессию:

If (!session_id()) { session_start(); } require_once _DIR_ . ‘/facebook/autoload.php'; // инклудим SDK от FACEBOOK $fb = new Facebook\Facebook([ 'app_id' => '', //Замените на ваш id приложения 'app_secret' => '' //Ваш секрет приложения ]);

Добавляем в наш запрос к файлу callback.php разрешения, которые хотим получить от пользователя.

$helper = $fb->getRedirectLoginHelper() ; //Добавьте разрешение publish_actions, чтобы постить от имени пользователя, а не от имени страницы $permissions = ['manage_pages','publish_pages']; $loginUrl = $helper->getLoginUrl('https://your-url.ru/callback.php', $permissions);

Код страницы, которую покажем пользователю:

echo '<p style="color: blue;"> Текст вашего поста </p>'; echo '<span id="post-text"> ' . $postText . '</span>'; echo '<p style="color: blue;"> Ссылка на пост </p>'; echo '<p id="post-link"> ' . $postLink . '</p>'; echo '<p> Введите здесь ID страницы, куда будет размещаться пост. Он потребуется как для размещения поста, так и для получения токена доступа Facebook </p>'; echo '<input id="pageid-fb"></br>'; echo '<a id="fb-token" href="' . htmlspecialchars($loginUrl) . '" target="_blank">Получить токен facebook ( пользовательский и страницы ) ( при отсутствии )</a>'; echo '<p> Если у вас нет токена для вашей страницы Facebook, получите его по ссылке выше. Если у вас есть токен, просто введите его в поле ниже. </p>'; echo '<p> Впишите сюда ваш токен страницы Facebook </p>'; echo '<input id="accesstoken-fb"></br>'; echo '<button id="facebook-post"> Разместить пост в Facebook </button>';

По клику на кнопку «facebook-post» отправляем пост на страницу. В дальнейшем, после App Review, необходимость в данной странице отпала и в действии оставили только код, который отправляет пост, с некоторыми доработками.

Страница callback.php содержит в себе код, который позволяет пользователю перейдя в Facebook дать разрешения к страницам, в которых пользователь имеет права администратора, а после возвращает в виде ответа массив с токенами (если страниц несколько). Нам в полученном ответе нужны только access_token и pageID. Их используем на предыдущей странице размещения поста.

Важный момент: сессия при получении токена не должна отличаться, иначе Facebook SDK вернет ошибку вместо токена.

if(!session_id()) { session_start(); } require_once __DIR__ . '/facebook/autoload.php'; $fb = new Facebook\Facebook([ 'app_id' => '', //Замените на ваш id приложения 'app_secret' => '' //Ваш секрет приложения ]); $helper = $fb->getRedirectLoginHelper(); try { $accessToken = $helper->getAccessToken(); } catch(Facebook\Exceptions\FacebookResponseException $e) { echo 'Graph вернул ошибку: ' . $e->getMessage(); exit; } catch(Facebook\Exceptions\FacebookSDKException $e) { echo 'Facebook SDK вернул ошибку: ' . $e->getMessage(); exit; } if (isset($accessToken)) $_SESSION['facebook_access_token'] = (string) $accessToken; elseif ($helper->getError()) exit; try { $response = $fb->get('/me/accounts', $_SESSION['facebook_access_token']); $response = $response->getDecodedBody(); } catch (Facebook\Exceptions\FacebookResponseException $e) { echo 'Graph вернул ошибку: ' . $e->getMessage(); exit; } catch (Facebook\Exceptions\FacebookSDKException $e) { echo 'Facebook SDK вернул ошибку: ' . $e->getMessage(); exit; } //Токен страницы print_r($response);

Ну и наконец код страницы, которая непосредственно отправляет пост в Facebook:

$str_page = '/' . $pageID . '/feed'; $feed = array('message' => $postText , "link" => ‘'); try { $response = $fb->post($str_page, $feed, $accessToken); } catch (Facebook\Exceptions\FacebookResponseException $e) { echo 'Graph вернул ошибку: ' . $e->getMessage(); exit; } catch (Facebook\Exceptions\FacebookSDKException $e) { echo 'Facebook SDK вернул ошибку: ' . $e->getMessage(); exit; } $graphNode = $response->getGraphNode(); echo 'Опубликован пост, id: ' . $graphNode['id']; ?>

После разработки и тестирования, готовим текст запроса в App Review.

При отправке запроса, мы должны предоставить:

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

Б) Видео (cкринкаст), который явно покажет, как будет использоваться ваше приложение.

Само окно запроса выглядит так:

Важные рекомендации, следуя которым вы сможете увеличить шанс успешного прохождения проверки:

  1. Расписывайте все подробно. Сотрудники Facebook не будут разбираться или думать, куда им нажать лишний раз. Они выполняют ваши инструкции и, если где-то что-то идет не по плану, сразу пишут отказ без пояснения причин.
  2. Путь, по которому будет идти проверка, должен быть максимально простым. Все кнопки, переходы и ссылки должны быть на виду.
  3. Мы писали текст на русском и английском. Думаю, это тоже критично влияет.
  4. Записывая скринкаст, делайте все не в быстром темпе, обязательно делайте остановки и показывайте места, где проверяющий может ошибиться. Либо заранее предусматривайте все подводные камни и закрывайте их.

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

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

0
1 комментарий
Zoibana

Какой отвратительный код.

Ответить
Развернуть ветку
-2 комментариев
Раскрывать всегда