Пользователь
0,0
рейтинг
17 февраля 2011 в 14:10

Автоматическое оповещение читателей о новостях с помощью ВКонтакте из песочницы tutorial

Вторая часть

Предисловие


Те из вас, кто пользуется социальной сетью ВКонтакте и подписан на официальную страничку Хабры в ней, заметили, что все новые топики с главной появляются на страничке в виде сообщений-ссылок:
vk

Так вот, если у вас есть свой блог и вы хотите на своей личной страничке публиковать такие же сообщения-ссылки автоматически — топик может быть вам интересен. Сегодня мы попробуем публиковать простые сообщения ссылки, а далее добавлять к ним «превью»-картинки.

Реализация


Итак, для работы нам понадобится PHP с подключенным модулем curl. Для взаимодействия с сайтом ВКонтакте нам потребуется проходить авторизацию на нем, а так же получать значение уникальной переменной posthash, которая передается при публикации каждой записи на вашей стенке.

Рассмотрим простейшую функцию авторизации:
function _auth( $cookies ) {
    $e = urlencode('my@email.ru'); //mail
    $p = urlencode('password');    //password
    $c = curl_init();
    $s = 'act=login&q=1&al_frame=1&expire=&captcha_sid=&captcha_key=&from_host=vkontakte.ru&email=' . $e . '&pass=' . $p;
    curl_setopt($c, CURLOPT_URL,'http://login.vk.com/?act=login');
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($c, CURLOPT_COOKIEJAR, $cookies);
    curl_setopt($c, CURLOPT_POST, 1);  
    curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13)');
    curl_setopt($c, CURLOPT_POSTFIELDS, $s);
    $r = curl_exec($c);
    curl_close($c);
  }

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

Теперь нам необходима функция для получения id текущего пользователя, значения его posthash переменной, а также значение переменной id из блока handlePageParams, которая определяет какой пользователь в данный момент просматривает страницу — если он равен 0, то значит мы не авторизованы и необходимо обратиться к выше приведенной функции. Итак:
function _params($cookies) {
    $c = curl_init();  
    curl_setopt($c, CURLOPT_HEADER, 1);  
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);  
    curl_setopt($c, CURLOPT_REFERER, 'http://vkontakte.ru/settings.php');
    curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13');  
    curl_setopt($c, CURLOPT_COOKIEJAR, $cookies);
    curl_setopt($c, CURLOPT_COOKIEFILE, $cookies);
    curl_setopt($c, CURLOPT_URL, 'http://vkontakte.ru/');  
    $r = curl_exec($c);
    curl_close($c);
 
    preg_match_all('/"post_hash":"(\w+)"/i', $r, $f1);
    preg_match_all('/"user_id":(\d+),/i', $r, $f2);
    preg_match_all('/handlePageParams\(\{"id":(\d+),/i', $r, $f3);
    return $f = array(
           'post_hash' => $f1[1][0],  
           'user_id'   => $f2[1][0],
           'my_id'     => $f3[1][0]);
  }

В результате мы получим массив с тремя переменными, которые необходимы нам для работы. Теперь осталось реализовать функцию создания сообщения ссылки. За публикацию сообщений на вашей стенке отвечает файл al_wall.php, который имеет множество получаемых параметров и в зависимости от каждого может создавать различные сообщения. Для нас наиболее важными будут следующие параметры:
  • act — собственно action для данного php файла, мы передаем значение post
  • hash — тот самый post_hash, который мы получили ранее
  • message — наше сообщение, не длиннее 255 символов, иначе произойдет создание заметки 
  • note_title — название заметки, если выше вы превысили лимит символов
  • status_export — параметр, определяющий «Экспорт в твиттер», если таковой аккаунт у вас связан с ВКонтакте
  • to_id — id пользователя на чью стенку мы публикуем сообщение
  • type — пока что обнаружены два возможных значения, all — публикация на вашей стенке, feed — публикации в вашем разделе Новости (блок «Что у вас нового») media_type — тип сообщения, ставим share, чтобы получить ссылку
  • url — передаваемый нами url ссылки
  • title — название вашей ссылки, ограничение в 81 символ
  • description — всплывающее описание ссылки, сюда можно передавать, например, первые строчки вашей новости, ограничение в 255 символов


На основе этих данных напишем функцию создания сообщения:
function _status($cookies, $hash, $url, $message, $title, $descr, $id) {
    $u = urlencode($url);
    $m = urlencode($message);
    $t = urlencode($title);
    $d = urlencode($descr);
    $q = 'act=post&al=1&hash=' . $hash . '&message=' . $m . '¬e_title=&official=&status_export=&to_id=' . $id . '&type=all&media_type=share&url=' . $u . '&title=' . $t . '&description=' . $d;
    $c = curl_init();  
    curl_setopt($c, CURLOPT_HEADER, 0);  
    curl_setopt($c, CURLOPT_HTTPHEADER, array('X-Requested-With: XMLHttpRequest'));
    curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);  
    curl_setopt($c, CURLOPT_POST, 1);  
    curl_setopt($c, CURLOPT_REFERER, 'http://vkontakte.ru/id'.$id);
    curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13');  
    curl_setopt($c, CURLOPT_POSTFIELDS, $q);
    curl_setopt($c, CURLOPT_COOKIEJAR,  $cookies);
    curl_setopt($c, CURLOPT_COOKIEFILE, $cookies);
    curl_setopt($c, CURLOPT_TIMEOUT, 15);
    curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 15);
    curl_setopt($c, CURLOPT_URL, 'http://vkontakte.ru/al_wall.php');  
    $r = curl_exec($c);
    curl_close($c);
 
    return $r;
}

Функция вернет нам ответ сервера ВКонтакте — это будет либо текст ошибки, либо последние 10 сообщений со стенки, которые можно обработать по своему усмотрению. Собственно работа с сервером ВКонтакте закончена, осталось написать общую функцию, которая будет проверять авторизацию, получать переменные и создавать сообщение.
function vkPost($url='http://habrahabr.ru/', $message='message', $title='title', $descr='descr')  {    
    $o = 'aqwdhfyrfd.txt';
    $h = _params($o, 'http://vkontakte.ru/id1', true);
   
    if($h['my_id'] == 0) {
      _auth($o, $d, true);
      $h = _params($o, 'http://vkontakte.ru/id1', true);
    }
   
    if($h['my_id'] != 0) {
      $r = _status($o, $h['post_hash'], $url, $message, $title, $descr, $h['user_id']);
      $c = preg_match_all('/page_wall_count_all/smi',$r,$f);
      if( $c == 0 ) {
        return false;
      } else {
        return true;
      }
    }
}

Возможности интеграции


Теперь можно использовать ее где угодно, на любом движке. Или же создать отдельный php файл, через который публиковать любые ссылки со своим описанием у себя на стенке. В качестве примера я покажу интеграцию с движком Wordpress, где при публикации записи в блоге, вы автоматически опубликуете ссылку на нее. Итак, необходимо все вышеприведенные функции перенести в functions.php, который находится в каталоге с вашей темой, если его там нет, то создайте его. Затем в него же допишем следующую функцию и определим ее как хук:
function wp_vk_post_add($post_ID) {
        $post  = get_post($post_ID);
        $title = $post->post_title;
        $link  = get_permalink($post_ID);
        $descr = $post->post_content;
  $vkont = get_post_meta($post_ID, 'vkontakte', true);
 
  if(mb_strlen(trim($descr), 'UTF-8') >= 250) {
          $descr = strip_tags($descr);
    $descr = mb_substr($descr,0,250, 'UTF-8').'...';
  }
  $message = 'Текст песни ' . $title;  
  if(mb_strlen(trim($message), 'UTF-8') >= 250) {
    $message = mb_substr($message,0,250, 'UTF-8').'...';
  }  
  if(mb_strlen(trim($title), 'UTF-8') >= 78) {
    $title = mb_substr($title,0,78, 'UTF-8').'...';
  }
  if($vkont != '1') {
          $status = vkPost($link, $message, $title, $descr);
    if($status) {
      update_post_meta($post_ID, 'vkontakte','1');
    } else {
      update_post_meta($post_ID, 'vkontakte','0');
    }
  }
        return $post_ID;
}
add_action('publish_post', 'wp_vk_post_add');

Немного пояснений. Дело в том, что экшен publish_post в Вордпресс отрабатывается не только когда вы нажимаете кнопку Опубликовать в админке, но и при каждом сохранении записи. Получать каждый раз ссылку, когда вы редактируете свою запись после публикации, конечно же не комильфо. Поэтому при удачной публикации ссылки к нашему посту добавляется пользовательское поле vkontakte со значением 1, а перед публикацией проверяется ее наличие — если оно существует и содержит 1, то функция vkPost пропускается.

Заключение


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

Стоит так же заметить, что al_wals.php запросит дополнительный параметр captcha, если ваш скрипт будет слишком усердно посылать статусы или вообще вернет «Ошибка доступа» — поэтому в рассылке спама этот метод вряд ли вам поможет.

А вот и пример:
Торт!
Икс @xbreaker
карма
46,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

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

Самое читаемое

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

  • 0
    Fatal error: Call to undefined function _hash()
    • –1
      спасибо, поправил
  • –14
    Слоупок!
  • –1
    Как раз думал о чём то подобном.
    • 0
      Я давно реализовал это на одном из сайтов, после нормального использования решил поделиться. Теперь в планах расширить функционал с возможностью публикации статусов-ссылок с картинками.
  • +1
    Для чего это может понадобиться?
    • 0
      Приведу конкретный пример, допустим, Вы — блогер, который время от времени публикует интересные статьи у себя на сайте и имеет профиль ВКонтакте. Если реализовать указанный выше механизм, то у подписчиков Вашей страницы ВКонтакте будут появляться оповещения в новостях о новых записях у вас в блоге — этакий вариант урезанной RSS-подписки :).
      • 0
        Если действительно интересные новости и не в промышленных масштабах, то это конечно на пользу.
        Главное чтоб в итоге френдлента и новости не превращались с сплошную полосу спама и репостинга.
        • 0
          В этом случае всегда можно скрыть новости определенного человека, если спамит ваш друг или же отписаться от страницы вообще, если спамит она.
    • 0
      Дублировать новости еще и во ВКонтакте.
    • –3
      Ничего с ног сшибательного и архиполезного. Например тут(ни коим образом не реклама) человек одновременно транслирует хабр, башорг, ixbt и другие IT ресурсы.
      • 0
        И каким образом это связано с ВКонтакте? ;)
        • 0
          Ни коим, я просто привел пример того, для чего это может понадобиться.
          • 0
            Вы кардинально путаете принцип работы. Тут мы отправляем данные на ВК, а ваш пример демонстрирует противоположное, он забирает с сайтов (парсит).

            Оффтоп: каким боком башорг IT ресурс? :)
            • 0
              Да, тут я не много запутался, каюсь.
              Насчет баша — хорошо :) он был когда давным давно IT ресурсом.
  • –2
    Хабр — он.
  • +1
    Не понимаю, почему VK не сделали для этого API до сих пор.
    • 0
      Если судить по официальной страничке Хабра — сделали, просто общего доступа к нему нет.
  • +1
    А почему хук в функциях темы, а не плагином?
    Вот тема обновится — и нету хука. А если делать чтоб был — надо Child делать. А чтобы в другой теме работало — туда тоже надо дописать. Плагином бы вышло лучше.
    • 0
      Когда-нибудь кто-нибудь напишет, не переживайте.
      • 0
        Не переживаю, меня не особо волнует кросспост во вконтакте. Просто меня удивило, что если идет интеграция с WordPress, то почему она идет именно так…
        • 0
          Ничего противозаконного тут нет, хочешь — пиши плагин, хочешь добавляй в свою тему, никто ж не указывает. Но я вот сейчас думаю как раз о том, чтобы закончить один плагин для WP, следующим пойдёт наверное, реализация этого плагина.
          • 0
            При чем здесь противозаконность?:)
            Обычно на Хабр постят хорошие, правильные решения. А это — костыль фактически. Я ничего не скажу насчет внутреннего функционала взаимодействия с API (не работал с вконтакте), но меня удивляет, почему автор сделал это, но не оформил это нормально. Или хабр уже не тот?
            • 0
              Нда. )
              Лучше бы авто вообще не касался вордпресса тогда.
              Суть его статьи — не в том как сделать надстройку к WP — а в том, чтобы показать постинг на сайт вконтакте ж.
              • 0
                Лучше бы не касался, да :)
                Я не ищу к чему придраться, а просто спросил почему. Дальше можно было вообще не спорить.
                P.S. Надеюсь, ваш плагин с этим функционалом окажется в официальном репозитории WP.
    • 0
      Согласен, но пока что это наброски общей функциональности и говорить о плагине рано, да и Wordpress-реализация в статье — лишь небольшой пример возможности использования
  • +2
    Вы уверены что для этого нельзя использовать API? Вот например vkontakte.ru/developers.php?o=-1&p=wall.post
    А так изменит вконтакт дизайн или какие-то внутренности и все отвалится…
    • 0
      Можно, однако, как я понял, для этого придется реализовывать приложение ВКонтакте или нет?
    • 0
      Эти методы для приложений. Сам был удивлен, что нет инструментов для импорта RSS во вконтакте, или же API для импорта новостей в группы и т.д.
      • 0
        Ну я этим методом пользовался когда писал плагин к Gwibber для поддержки вконтакта.

        Единственное серьезное препятствие которое я заметил — сессионный токен привязан к IP адресу, поэтому получить сессию на домашнем компьютере и потом пользоваться ей на сервере не получится и это печально. Например в API Facebook можно получить так называемый «Оффлайн токен» и пользоваться им откуда угодно. Вконтакте такой штуки не нашел и это сильно ограничивает возможности применения API.
        • 0
          Если описанное в статье можно реализовать проще, то буду очень рад прочитать статью от Вас как это сделать :).
  • НЛО прилетело и опубликовало эту надпись здесь
  • –2
    А знали ли вы, что подобные действия запрещены правилами сайта.
    • 0
      Как и запрещено правилами 99% контента ВКонтакте? Да, знал :) Вообще там есть оговорка, что можно получить разрешение администрации, так что ничего невозможного я не вижу ;)
  • 0
    Хотел сделать подобное на своем проекте. Что бы «действие» пользователя появлялось у него на страничке. Остановила капча, с большим количеством людей им постоянно придется ее водить, а мне надо было автоматизировать. (попутно вопрос, ограничение на ресурс или на пользователя ВК?)

    Было бы не плохо, чтоб когда будет полноценная апи, была возможность добавить сайт в разрешенные.
    • 0
      Тут без приложения и ВКонтакте API Вам не обойтись, там можно реализовать все функции без ограничения, если пользователя разрешит доступ к своей стенке приложению Вашего сайта
      • 0
        Спасибо. Своего рода костыль. Подожду немного, если нечего лучше не появится, так и сделаю. Надо написать в ВК, что бы они присмотрелись к твиттеру. Сам ВК это большая содранная идея, так почему бы не содрать и там :)
        • 0
          Доверять сайту со стороны ВКонтакте тоже просто так не будет, а с помощью приложения он сможет контролировать действия сайта и доступ к данным пользователей или их стенке.
          • 0
            Насколько я знаю, любой подключенный к ВК сайт может пользоваться теми же методами, что и flash и iframe приложения.

            Через штуку, которая у них называет OpenAPI. Причем как с клиента, так и с сервера.
            И премодерации нет никакой.

            Единственное ограничение — он спрашивает у пользователя доступ к данным, стенке и т.д.
        • 0
          Если действие пользователя появляется на его же странице, то использование API вконтакта — это не костыль, а наоборот верное решение.

          Видал я одну онлайн-игрушку, про мафию вроде, авторизовавшись в которой через Тви, сильно пожалел: эта дрянь заспамила мне всю ленту, 30+ постов. Задолбался потом удалять это гавно из ленты, и извинятся перед фоловерами.
          • 0
            Кажется многие через это прошли… )
  • 0
    Как раз недавно завел страничку компании. Группа как-то не совсем то, что нужно для присутствия в соц.сети и от нее наверно откажусь в пользу странички. Теперь с помощью вашего топика, думаю, окончательно автоматизирую постинг новостей (main_site → rss & twitter & vkontakte).
  • 0
    опробовала, занятно! теперь в мою группу Вконтакте вступает намного больше людей, чем обычно. Спасибо!
  • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    старенькая статья, уже ничего не пашет :(((
    • 0
      не знаю, с момента написания этой статьи не менял в своих скриптах ничего — пока на всех сайтах работает как часы :)
      • 0
        Извините, наверное что-то применил не так, но вот переписав ф-ю авторизации, все вышло, на всякий случай приведу свой пример:
        function _auth( $cookies ) {
        $data=array(
        'act'=>'',
        'login'=>'',
        'q'=>'1',
        'al_frame'=>'1',
        'captcha_sid'=>'',
        'captcha_key'=>'',
        'from_host'=>'vkontakte.ru',
        'expire'=>'',
        'email'=>'---YOU E-mail---',
        'pass'=>'---YOU PASS---',
        'success_url'=>'',
        'fail_url'=>'',
        'try_to_login'=>'',
        'to'=>'',
        'vk'=>'',
        'al_test'=>'3'
        );
        $c = curl_init();
        curl_setopt($c, CURLOPT_URL, 'http://vkontakte.ru/login.php'); // login.vk.com/?act=login
        curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($c, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($c, CURLOPT_COOKIEJAR, $cookies);
        curl_setopt($c, CURLOPT_POST, 1);
        curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13)');
        curl_setopt($c, CURLOPT_POSTFIELDS, $data);
        $r = curl_exec($c);
        curl_close($c);
        }
        _auth('/home/lebnik/data/www/site.ru/cookies/cookies.txt');

        Далее проверял не все функции, но переписал на свой лад _status() и все работает, поэтому спасибо за статью, сразу не въехал.
  • +1
    Подтверждаю все работает
  • 0
    А можно аналогичное реализовать для жумлы? Я не суперический программер совсем, но если меня в нужные места потыкать носом, то осилю. Уж больно хочется на сохранение статей повесить публикацию ссылок на них в группу. В идеале было бы здорово создавать отдельное обсуждение с текстом материала, но пусть хотя бы ссылка будет на стене.
  • 0
    Подскажите, пожалуйста, в чем может быть проблема: все публикуется, если указать стену пользователя, а если указать ID оф.страницы (ID с минусом), то выдает «Ошибка доступа»?
    • 0
      а post_hash какой используется?
      • 0
        да-да, в нем дело. Спасибо, я уже разобрался
  • 0
    Скрипт постит ко мне на страницу, а как его заставить постит в группу, в которой я являюсь админом?
    Или я невнимателен?
    • 0
      Чтобы постить в группу нужно:
      1. Быть админом
      2. Записать ID группы
      3. В параметрах вместо ID страницы друга указать ID группы, но со знаком "-", например, -1234
  • 0
    У меня вроде логин проходит, но эта маразматическая безопасность через мобильный телефон достает уже. Требует ввести последние 4 цифры после входа через курл, и как ему их подсунуть, я не очень понимаю пока.
    • 0
      А что передается в соответствующем POST запросе, когда вы ввели последние четыре цифры? Какой то хеш или цифры в прямом виде?
      • 0
        Да передавалось все нормально. Я нашел уже решение, где подсовывается этот код (в третьей части этой же серии статей). Но в итоге, продолбавшись целый вечер с курлом, все сделал через API ;-)

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