Постинг в группу в одноклассниках автоматически с сайта

Давно уже озаботился данным вопросом и сколько не гуглил натыкался всегда на одно и тоже: Нельзя постить в группу с помощью API.Поняв что попал в тупик, я начал изобретать велосипед на QT WebView, все вроде работало, но иногда происходили сбои и я отказался от использования этого способа и вернулся к ручному добавлению контента в группу. Я не следил за обновлением API одноклассников, но видимо они решили все таки разрешить публикацию контента в группу с помощью REST API, но только после получения соответствующих прав доступа, в частности GROUP_CONTENT.

Пожалуй начнем

Для начала нам потребуется создать приложение в одноклассниках, нам понадобится приложение для OAuth авторизации. После регистрации приложения нам необходимо получить права GROUP_CONTENT которые позволят осуществлять постинг в группу  в одноклассниках. Для этого нам необходимо написать письмо на адрес [email protected], в письме необходимо указать ID приложения, указать требуемые права доступа и пояснить для каких целей они вам необходимы.

Обратите внимание: вы можете не получить ответ на ваше письмо (как это было у меня), поэтому проверяйте настройки своего приложения, там должны появиться требуемые права доступа

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

Мне необходимы были права GROUP_CONTENT и VALUABLE_ACCESS, в письме я объяснил что VALUABLE_ACCESS мне необходимы для публикации объявления поданного пользователем на его странице, а GROUP_CONTENT необходим для публикации объявлений в группе моего сайта. Честно говоря я не совсем понимаю зачем мейловцы ограничивают возможности своего API.

Отправляем посты

Как только наше приложение получает права на публикацию в группу, нам необходимо получить access_token, для этого необходимо ткнуть на кнопку «Получить access_token».

Снимок экрана от 2015-11-05 20:28:13

Копируем полученные ключи.

Обратите внимание на то, что после добавления дополнительных прав доступа приложения access_token работать перестанет, его необходимо будет получить заново.

Теперь мы можем отправлять запросы на публикацию постов, я в своей группе публикую ссылки на объявления со своего сайта вот так:

	function getUrl($url, $type="GET", $params=array(), $timeout=30) {
		if ($ch = curl_init()) {
			curl_setopt($ch, CURLOPT_URL, $url);
			curl_setopt($ch, CURLOPT_HEADER, false);
			if ($type == "POST") {
				curl_setopt($ch, CURLOPT_POST, 1);
				curl_setopt($ch, CURLOPT_POSTFIELDS, urldecode(http_build_query($params)));
			}
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
			curl_setopt($ch, CURLOPT_USERAGENT, 'PHP Bot (http://bazarbratsk.ru)');
			$data = curl_exec($ch);
			curl_close($ch);
			return $data;
		} else {
			return "{}";
		}
	}

	function arInStr($array) {
		ksort($array);
		$string = "";
		foreach($array as $key=>$val) {
			if (is_array($val)) {
				$string .= $key."=".arInStr($val);
			} else {
				$string .= $key."=".$val;
			}
		}
		return $string;
	}
	$ok_access_token = "";//Наш вечный токен
	$ok_private_key = "";//Секретный ключ приложения
	$ok_public_key = "";//Публичный ключ приложения
	$params = array(
		"application_key"=>$ok_public_key,
		"method"=>"mediatopic.post",
		"gid"=>"52990304649",//ID нашей группы
		"type"=>"GROUP_THEME",
		"attachment"=>'{"media": [{"type": "link","url": "https://www.google.com"}]}',//Вместо https://www.google.com естественно надо подставить нашу ссылку
		"format"=>"json"
	);
	$sig = md5(arInStr($params).md5("{$ok_access_token}{$ok_private_key}"));
	$params["access_token"]=$ok_access_token;
	$params["sig"]=$sig;
	$result = json_decode(getUrl("https://api.ok.ru/fb.do", "POST", $params), true);
	//Если парсер не смог открыть нашу ссылку (иногда он это делает со второй попытки), то отправляем ещё раз
	if (isset($result['error_code']) && $result['error_code'] == 5000) {
		getUrl("https://api.ok.ru/fb.do", "POST", $params);
	}

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

Если у вас возникли вопросы, то оставляйте комментарии, постараюсь ответить оперативно.

Пожалуйста, оцените статью

Полная фигняУзнал немного новогоНормальная статьяХорошая статьяСупер! (Пока оценок нет)
Загрузка...

57 thoughts on “Постинг в группу в одноклассниках автоматически с сайта

  1. А не могли бы привести пример кода который собирает информацию с сайта (текст, картинки) и потом публикует ее в OK ?

    1. Информацию собирает парсер одноклассников, Вам просто надо отправить ссылку на материал.
      $params = array(
      «application_key»=>$ok_pub[ic_key,
      «method»=>»mediatopic.post»,
      «gid»=>»52990304649»,//ID нашей группы
      «type»=>»GROUP_THEME»,
      «attachment»=>'{«media»: [{«type»: «link»,»url»: «наша ссылка»}]}’,
      «format»=>»json»
      );

      Парсер сам уже найдет что ему нужно на Вашей странице, но для этого необходимо что бы на странице были добавлены теги, к примеру, Open Graph. Для отправки другого содержимого надо отправлять другие данные. За отправку данных отвечает параметр «attachment». В моем примере указан type: «link», для других типов надо указывать другой тип.

  2. Добрый день, скажите на каком языке этот код на писан и можно ли его в зеннопостер загрузить?

    1. Ну очевидно же что код на PHP. Я с трудом представляю как этот код можно куда то загрузить, разве что на сервер где работает сайт в виде PHP-скрипта с дописанным функционалом под свои нужды

  3. Денис, метод mediatopic.post возможно использовать в такой форме?

    Примеры
    Запрос: api/group/getInfo?application_key=[Application Key]&sig=[Signature]&session_key=[Session Key]&uids=53923499278353&fields=uid,name,description,shortname,pic_avatar,shop_visible_admin,shop_visible_public,members_count

    Или зарез JavaScript?

    1. Вы привели пример GET запроса, а mediatopic.post отправляется POST запросом и все поля соответственно внутри тела запроса. И разницы нет JS или PHP, разница на другом уровне

  4. Если вместо ссылки отправлять данные типом текст и в тексте будет присутствовать + сигнатура не проходит, ответ сервера возвращает вместо + пробел, соответственно сигнатура не проходит, как быть ? не подскажите

  5. вот этот момент
    «attachment»=>'{«media»: [{«type»: «link»,»url»: «https://www.google.com»}]}’,

    если например указать
    «attachment»=>'{«media»: [{«type»: «text»,»text»: «Hello + world»}]}’,
    то сервер вернет «Hello world» соответственно сигнатура не прокатывает, решил этот момент тем что сигнатуру делаю с оригиналом а отправляю текст в urlencode тогда сервер возвратит Hello + world, вот просто интересно как бы без костыля это реализовать

    p.s. «+» в тексте ещё пол беды, а вот токены на фотографии приходят 95% с наличием «+» и если в тексте можно и вырезать, то из токена уже некуда «+» не денешь

    1. Я думаю с этим вопросом Вам лучше обратиться в поддержку, поскольку я вряд ли могу чем то помочь. Проверять данный метод, к сожалению. нет времени совсем.

  6. получил права VALUABLE_ACCESS и GROUP_CONTENT, при запуске скрипта получаю ошибку:
    Array ( [error_code] => 100 [error_msg] => PARAM : Parameter access_token specified but application is not EXTERNAL [error_data] => )

    подскажите куда копать?

    1. error_msg как бы намекает на то, что приложение не внешнее. Видимо при создании приложения был выбран неверный тип приложения.

  7. Спасибо разобрался, уже успешно могу постить текст в группу, не могу понять как загружать картинки через API, да и вообще API непонятный… оч нужно загружать картинки, если есть опыт подскажите пожалуйста.

    1. Загрузку фотографий не доводилось реализовывать, но из документации видно что процесс весьма замороченный. Загрузка выполняется в несколько этапов. Это читали?

      1. Да конечно, на данный момент всё реализовано, но есть заморочки с этим плюсом, опять же костыль помог, просто спросил может есть какие то наработки или сталкивался кто

        1. Подскажите по поводу костыля с символом плюса, не могу его победить никак.

  8. Через какое время вы обнаружили что у вас есть данные права, после отправки письма разработчикам ok.ru?

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

  9. Привет Денис) Подскажи пожалуйста, а ты пробовал менять пользователей, если да то подскажи как)

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

        1. Ну вот поэтому все и отправляется от одного пользователя. Атрибуты приложения у нас id приложения, публичный и секретный ключ, а access_token — это «идентификатор» пользователя, поскольку access_token мы получаем когда авторизуем пользователя с помощью OAuth.
          Я дико извиняюсь, могу в чем-то ошибаться ибо давно не окунался в эту тему ибо настроил и все давным-давно забыл ))

          1. это супер)) А я вот столкнулся теперь наслаждаюсь=))

            А кстати у тебя параметр sig- на сайте сейчас так и высчитывается как написано в примере?

          2. Да, код не менял, как есть так и работает.

  11. А когда пытаюсь добавить поля
    onBehalfOfGroup — будет ли тема опубликована от имени группы или от имени пользователя, который создал тему (возможные значения — “true”/”false”).
    disableComments — выключить ли комментарии к теме (возможные значения — “true”/”false”)

    вот тело
    {
    «media»: [
    {
    «type»: «text»,
    «text»: «Hello world!»
    }
    ]
    «onBehalfOfGroup»: «false»,
    «disableComments»: «true»
    }

    пишет ошибку
    {
    «media»: [
    {
    «type»: «text»,
    «text»: «Hello world!»
    }
    ]
    «onBehalfOfGroup»: «false»,
    «disableComments»: «true»
    }

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

      1. Та вроде все настроил, и когда пишу пост по обычному со страницы, то показывает автора который реально писал…. а ты не знаешь, для того что-бы пригласить в приложение его должны еще одобрить в службе поддержки ? А то я пытаюсь как то его найти вторым акк и не получается…

        1. Тут мне кажется все зависит от типа приложения, если оно для OAuth-авторизации, то смысл ему тусоваться в общем списке приложений? У него по сути не подразумевается никакого функционала (насколько я понимаю).

          1. да согласен, просто я делаю бота для ВК и ОК. Так мне такие детали требуются….

          2. Сложно что-либо посоветовать не зная конкретной задачи. Из личного опыта могу сказать одно: если бот облегчает жизнь, то тема попрет, если затрудняет (по принципу шило на мыло), то не попрет. Поскольку мне приходится администрировать группу с объявлениями, то заметил что много «бизнесменов» торчат во всяких группах, где открытая публикация, и чуть ли не каждый час постят свои гавнапосты. Для таких идиотов можно поднять сервис, который бы делал это все за них, то есть заполнил раз форму, выбрал группы, куда постить, оплатил постинг (например рубль за энное количество постов) и готово.

  12. Слушай $sig = md5(arInStr($params).md5(«{$ok_access_token}{$ok_private_key}»));
    Это запись значит, что ты делаешь хеш из 1 строки или двух по отдельности??

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

    1. Так ключ сессии генерируется OAuth-авторизацией и, насколько мне известно, живет две недели. Вечная сессия только у владельца приложения. Но может быть уже что-то изменилось в этом плане, не слежу за новостями в этой сфере.

  14. Народ подскажите пожалуйста! Почему выдаёт ошибку подписи sig? И поститься из-за этого через раз?

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

    Может кому-то пригодиться, делал просто чтобы опубликовывал текст без ссылок и картинок: https://yadi.sk/d/9A67kIoi3HShR5

    Все настройки которые нужно заполнить находятся в папке settings (settings.php) и в index.php переменная $message это текст который пойдет в пост в группу.

  16. Здравствуйте!
    Подскажите как мне загрузить несколько фотографий для добавления товара через api?
    Пишу запрос:
    $param = array(
    «application_key»=>$ok_public_key,
    «method»=>»photosV2.getUploadUrl»,
    «gid»=>»id_group»,
    «count» => «2»,
    «placeholders» => true,
    «format»=>»json»
    );
    Ссылка приходит, дальше отправляю постом несколько фоток,
    в ответ приходит массив с одним токеном,
    а должен с несколькими, как тут —
    {
    «photos»:{
    «qxJnTUZEifEHlaZ2Nz81g3EaHKQnxlbd7Qu8TWddumIXGV5DTMbiQQ==»:{ «token»:»6P+dZaVxD9ApR6YstI/4SzLPS2T7m2Z5ViZSaqVl6X8LMBKFE4Tmjmm8U6zCcN1ZrBiQHfPmtzKrn6xnNhGnA5LoVecHl5PWf+f7ucCbl41Jii8ZzsVdIoOe79D/lsv7″
    },
    «Tt7Aoxg7aAyyAgbgCsFpjhjBkgmJvbBS5wdNd8/qGY6rphKGXXYwRg==»:{ «token»:»9x9LSso95pGTv3Zwyhy6cbCpOz5wUrSFjYLGRLy6i7AnS1l2cOrWtvPOJKL9ps7V8KAaMpvgMXsMaVdCTB5BTsKZ4gMv1bOk7MGDbeS+3NQqwPIR4VIldkHydaI0KYQg»
    },
    «RGZb34XWM+gbO739cLshQIh2DOdQAuJ6ss8MUaS3N9QVz/6eMNGaLg==»:{ «token»:»IBi/GFg7L4tTdNcACoLghzZzyS/YDdLHreESHOep5i2vL82nHavL3Ku4z/NerqvQOPyQh2kVfbFzVk2K2KJd5FqLsXR5VLzIYwQ5KMO/zk3faAP2fJpUhwfy6LHFxblH»
    }
    }
    }
    Подскажите что надо написать для загрузки нескольких фотографий?

      1. Отправляю Curl-ом,
        Получаю ссылку через вашу функцию getUrl();
        Загружаю фотки из БД,
        И id каждой фотки заношу в массив.
        $sel12 = mysql_query(«SELECT * FROM photos WHERE id_ob=’$id_ob’ LIMIT 2») or die(mysql_error());
        while($data = mysql_fetch_array($sel12, MYSQL_ASSOC)) {
        $result1 = json_decode(getUrl(«https://api.ok.ru/fb.do», «POST», $param), true);

        if (isset($result1[‘error_code’]) && $result1[‘error_code’] == 5000) {
        getUrl(«https://api.ok.ru/fb.do», «POST», $param);
        }
        print_r($name_ph12 = $data[‘name_photo’]);
        $image_path1 = dirname(__FILE__).’/photos/’.$name_ph12;
        $cfile1 = curl_file_create($image_path1,’image/jpeg’,$name_ph12);
        $ch1 = curl_init($result1[‘upload_url’]);
        curl_setopt($ch1, CURLOPT_POST, true);
        curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch1, CURLOPT_POSTFIELDS, array(«file» => $cfile1));
        $safee[$i] = json_decode(curl_exec($ch1), true);
        $i++;
        curl_close($ch1);
        }
        // print_r($safee[0]);
        // Выводит массив с одним токеном:
        Array ( [photos] => Array ( [nnwG9QJ4OAInok4+Mu8+ni2p0uRoXEI3fwPSLpoDHBjgMwWnTdMvkQ==] =>
        Array ( [token] => lhxlo/NU37JtornQP2lhwHVREIb21Oe1LRm/U/ptSEvjA3hr75Xlu1rSB6NWjZ6dc+3z6DYDLw/FD8SMjE3zFWBxbM6P8PyzaF8iWY9JpRs7eINyGuRvln0L+OmentLBmfhouk6gJoiAB5BjhcfrhVKRbEYpB2cYgY20wUFMigw= )
        ) )
        На сайте api ok написано добавить заполнители, я так понял что это для загрузки нескольких фоток,
        только как их записать я не понял.

        1. О боже ж ты мой…. Михаил, зачем Вы в цикле выполняете целый запрос? Достаточно ведь просто запихать в массив кучу $cfile1, а потом вне цикла отдать этот массив в curl_setopt($ch1, CURLOPT_POSTFIELDS, $array);.

          Теперь ржака:
          print_r($safee[0]); // выведет 1 токен потому что Вы указываете [0], то есть распечатываете первый элемент массива, а не весь массив.

          Вам необходимо привести код в порядок )))

          1. Спасибо, получилось.
            Выводит несколько токенов в одном массиве.
            В цикле делаю:
            while($data_ph1 = mysql_fetch_array($sel12, MYSQL_ASSOC)) {

            $name[$i] = $data_ph1[‘name_photo’];
            $image_path[$i] = dirname(__FILE__).’/photos/’.$name[$i];
            $cfile1[$i] = curl_file_create($image_path[$i],’image/jpeg’,$name[$i]);

            $i++;
            }
            $ch1 = curl_init($result1[‘upload_url’]);
            curl_setopt($ch1, CURLOPT_POST, true);
            curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch1, CURLOPT_POSTFIELDS, $cfile1);
            $res = json_decode(curl_exec($ch1), true);
            curl_close($ch1);
            Теперь добавляю к товару эти токены и пишет, что неверная подпись:
            $paramss = array(
            «application_key»=>’$app_key’,
            «method»=>»market.add»,
            «gid»=>»$id_group»,//ID нашей группы
            «type»=>»GROUP_PRODUCT»,
            «attachment»=>'{«media»:[
            {«type»:»text»,»text»:»Text1″},
            {«type»:»text»,»text»:»Text2″},
            {
            «type»: «photo»,
            «list»: [
            {«id»: «‘.urlencode($res[‘photos’][$result1[‘photo_ids’][0]][‘token’]).'»},
            {«id»: «‘.urlencode($res[‘photos’][$result1[‘photo_ids’][1]][‘token’]).'»}
            ]
            },
            {«type»:»product»,»price»:1000,»lifetime»: 30}]}’,
            «format»=>»json»
            //Вместо https://www.google.com естественно надо подставить нашу ссылку
            );
            $sig = md5(arInStr($paramss).md5(«{$ok_access_token}{$ok_private_key}»));
            $paramss[«access_token»]=$ok_access_token;
            $paramss[«sig»]=$sig;

            print_r($result = json_decode(getUrl(«https://api.ok.ru/fb.do», «POST», $paramss), true));
            Иногда добавляю один токен, все проходит замечательно,
            Потом обновляю и может не пройти.
            Такое чувство как будь-то через раз срабатывает.
            Где-то видел, что может из-за плюсов «+» в токене это не проходит.
            Еще на сайте api пишут в примере {«existing_photo_id»: «1234», «group»: true}
            где его брать? Подскажите.

          2. Ну вот опять Вы плодите ненужные сущности, вместо:
            $name[$i] = $data_ph1[‘name_photo’];
            $image_path[$i] = dirname(__FILE__).’/photos/’.$name[$i];
            $cfile1[$i] = curl_file_create($image_path[$i],’image/jpeg’,$name[$i]);

            Можно указать:
            $cfile1[ $i ] = curl_file_create( dirname(__FILE__).’/photos/’.$data_ph1[‘name_photo’], ’image/jpeg’, $data_ph1[‘name_photo’] );

            И зачем Вы делаете urlencode токенам?

  17. Без них тоже не работает,
    Не знаю в чём ошибка, вроде всё правильно написал.
    Еще не знаю что указать в existing_photo_id,
    и нужен ли он вообще.

    1. Ну в документации наверняка должно быть пояснение для чего existing_photo_id и является ли он обязательным. По поводу неверной подписи, попробуйте в json’е, который Вы формируете и отправляете в качестве attachment, убрать пробелы и переносы. Может в этом причина. Вообще формируйте его не явно, а через json_encode предварительно сформировав массив с подобной структурой. Так Ваш код будет выглядеть аккуратнее и меньше возможностей для возникновения ошибки.

  18. Денис не подскажете как можно получить ссылку медиатопика после публикации?
    В ответе метода получаю ИД топика, но он не совпадает с ид топика с веб версии.
    метод mediatopic.post мне вернул id: 67814792386136
    а на сайте id: 67691302122925

    1. К сожалению тут я Вами ничем не могу помочь. Такой задачи передо мной не стояло, а скрипт я трогал последний раз несколько лет назад ))

  19. замучился уже!
    использую ваш пример для поста текста, выдает ошибку 104
    104
    PARAM_SIGNATURE : Invalid signature

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Подпишитесь на рассылку и получайте новые статьи на почту