Главная XML-RPC и кросспостинг в ЖЖ

XML-RPC и кросспостинг в ЖЖ

Раздел: Livejournal, PHP, XML, 1 марта 2008 28 комментариев
XML-RPC и кросспостинг в ЖЖ

Итак. Захотелось мне сделать так, чтобы новости с Автобегиннера транслировались в Живой Журнал. Т.е. добавляется новость на сайт и сразу же появляется в LiveJournal. После недолгих поисков, я набрел на этот документ. Из него видно, что ЖЖ поддерживает 2 протокола взаимодействия: “Тонкий клиент” и XML-RPC протокол.

“Тонкий клиент” – довольно примитивная технология, поэтому ее я даже не расматривал, и стал изучать XML-RPC. Wikipedia любезно сообщает нам, что

XML-RPC (сокр. от англ. Extensible Markup Language Remote Procedure Call — XML-вызов удалённых процедур) — стандарт/протокол вызова удалённых процедур, основанный на XML, является прародителем SOAP, отличается исключительной простотой применения. XML-RPC, как и любой другой интерфейс RPC, определяет набор стандартных типов данных и команд, которые программист может использовать для доступа к функциональности другой программы, находящейся на другом компьютере в сети.

Здорово, правда? Итак. Нам нужна библиотека, которая могла бы формировать, посылать, получать и обрабатывать XMP-RPC-запросы. Для этих целей я использовал The Incutio XML-RPC Library for PHP весом всего 27 Кбайт.

Вот код, который добавляет новую запись в ЖЖ:

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
require('IXR_Library.inc.php');
 
// Кросспостинг в ЖЖ
define('LJ_HOST',   'www.livejournal.com');
define('LJ_PATH',   '/interface/xmlrpc');
define('LJ_LOGIN',  'ваш_ЖЖ_логин');
define('LJ_PASSWD', 'ваш_ЖЖ_пароль');
 
// Создаем xml-rpc клиента
$ljClient = new IXR_Client(LJ_HOST, LJ_PATH);
 
// Посылаем challange-запрос (что такое - читайте ниже)
if (!$ljClient->query('LJ.XMLRPC.getchallenge')) {
    echo 'Ошибка [' . $ljClient->getErrorpre().'] '.$ljClient->getErrorMessage();
}
else {
    // Получаем ответ
    $ljResponse = $ljClient->getResponse();
    // Вытягиваем challenge
    $ljChallenge = $ljResponse['challenge'];
 
    // Заполняем поля XML-запроса
    $ljArgs = array();
    // Имя пользователя
    $ljArgs['username']       = LJ_LOGIN;
    // Указываем способ идентификации
    $ljArgs['auth_method']    = 'challenge';
    // Указываем полученный challenge
    $ljArgs['auth_challenge'] = $ljChallenge;
    // Посылаем зафрованный пароль
    // формула md5(challenge + md5(password))
    $ljArgs['auth_response']  = md5($ljChallenge . md5(LJ_PASSWD));
    // Версия протокола, 1 - все данные в кодировке UTF-8
    $ljArgs['ver']            = "1";
    // Текст записи (перекодируем из windows-1251 в UTF-8)
    $ljArgs['event']          = iconv('windows-1251', 'UTF-8', 'текст записи');
    // Заголовок записи (перекодируем из windows-1251 в UTF-8)
    $ljArgs['subject']        = iconv('windows-1251', 'UTF-8', 'заголовок');
 
    // Дата
    $ljArgs['year']           = 2008; // год
    $ljArgs['mon']            = 2; // месяц
    $ljArgs['day']            = 11; // день
    $ljArgs['hour']           = 14; // часы
    $ljArgs['min']            = 58; // минуты
 
    // Доп параметры
    $ljArgs['props']          = array(
                                    // Текст уже отформатирован (содержит HTML-теги)
                                    'opt_preformatted' => true,
                                    // Добавляем запись "задним числом"
                                    'opt_backdated'    => true,
                                    'taglist'          => iconv('windows-1251', 'UTF-8', 'список тегов (меток), разделенный запятыми'),
                                );
 
    // Доступность записи - доступна всем (по-умолчанию)
    $ljArgs['security']       = 'public';
 
    // Добавляем новое сообщение
    $ljMethod = 'LJ.XMLRPC.postevent';
 
    // Посылаем запрос
    if (!$ljClient->query($ljMethod, $ljArgs)) {
        echo 'Ошибка ['.$ljClient->getErrorpre().'] '.$ljClient->getErrorMessage();
    }
    else {
        // Получаем ответ
        $ljResponse = $ljClient->getResponse();
        print_r($ljResponse);
    }
}

В коде можно заметить странные пассы с паролем. Зачем? Объясняю.

ЖЖ поддерживает несколько схем авторизации. Самая простая – clear: пароль посылается обычным текстом, что согласитесь, небезопасно. Схема, когда посылается MD5-хэш пароля тоже не идеальна. Наиболее надежна, так называемая challenge-response схема (“вызов – ответ”, “отзыв – пароль” и т.д.).

Мы запрашиваем у сервера “секретное слово”:

1.
2.
3.
if (!$ljClient->query('LJ.XMLRPC.getchallenge')) {
    echo 'Ошибка [' . $ljClient->getErrorCode().'] '.$ljClient->getErrorMessage();
}

И шифруем наш пароль (по формуле md5(“секретное слово” + md5(“пароль”))) с использованием этого слова:

1.
$ljArgs['auth_response']  = md5($ljChallenge . md5(LJ_PASSWD));

Элегантно и надежно )))

Кстати, похожая схема используется в сотовой связи.

В приведенном коде я использую iconv для перекодирования из windows-1251 (стандартная кодировка для бегиннера) в UTF-8.

Если все ОК, от сервера придет ответ такого вида:

1.
2.
3.
4.
5.
6.
Array
(
    [itemid] => 23
    [url] => http://адрес_записи
    [anum] => 105
)

Главное, что нас интересует – это itemid. С помощью него можно эту запись редактировать. Для этого в коде меняем строки 59-60:

1.
2.
    // Добавляем новое сообщение
    $ljMethod = 'LJ.XMLRPC.postevent';

на

1.
2.
3.
    // Редактируем запись
    $ljMethod = 'LJ.XMLRPC.editevent';
    $ljArgs['itemid'] = itemid;

Где itemid – это itemid записи :))))

В случае успеха ответ будет таким же, как при добавлении.

Смотрите также:

28 комментариев

  1. Live Stalker пишет:

    Mobile Blogger Start…

    Потихоньку начинаю реализовывать идею по созданию клиента для ведения блога с коммуникатора.
    Клиент будет работать через XML-RPC. Интерфейс…

  2. [...] продолжение этого поста расскажу как написать собственный XML-RPC сервер, [...]

  3. [...] sape.ru. Кто-то знает что такое XML-RPC (кто не знает, прошу сюда и сюда). И лишь немногие знают, что с Сапой можно [...]

  4. Лина К пишет:

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

    1. Knave пишет:

      [ссылка]

  5. Хочется уподобиться боту и написать нечто вроде “Спасибо, очень полезный материал” ;) и ведь не совру же )))

  6. да и еще один момент )
    в Вашем коде с датами заморочка… защита от дурака? Это чтобы абсолютные нубы не заюзали?

    1. Knave пишет:

      Нет. Это остатки работающего кода на сайте, из которого брался пример.

      Исправил. Спасибо за замечание.

  7. [...] XML-RPC и кросспостинг в ЖЖ – Константин Лихачев [...]

  8. [...] Функция LJPost взята отсюда [...]

  9. vadim s. sabinich пишет:

    Я не программер. И не совсем ясно куда этот код прилеплять.

  10. Константин пишет:

    Привет, можешь помочь написать что-то подобное для добавления-удаления друзей в аккаунте LJ? в долгу не останусь!

  11. Knave пишет:

    Если есть API функции для этого – попробую.

  12. Константин пишет:

    Хорошо, написал на почту

  13. mike пишет:

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

  14. Keo пишет:

    Доброго дня!
    Подскажите, после выполнения выдается следующая ошибка:
    “Ошибка [-32300] transport error – HTTP status code was not 200″
    в какую сторону смотреть?

    1. Knave пишет:

      Какая ошибка при получении ответа (статус не 200). Попробуйте посмотреть что возвращает запрос. Может 404 или 502 или что-нибудь другое.

  15. Keo пишет:

    Запрос возвращает полностью сгенерированные данные, если Вы об этом…

  16. Keo пишет:

    Ошибка [-32300] transport error – HTTP status code was not 200

  17. Mut@NT пишет:

    А как постить в blogger.com?

  18. Андрей пишет:

    Мне не совсем понятно,как сие к джумле прикрутить.поясните плиз.

  19. [...] не был и подходящая инструкция быстро нашлась. XML-RPC и кросспостинг в ЖЖ. Константин Лихачев в ней подробно рассказывает об [...]

  20. Егор пишет:

    Здравствуйте. Спасибо за пример.
    Почему-то не могу запостить запись в сообщество, хотя в свой ЖЖ получается.
    добавляю аргумент:
    $ljArgs['usejournal'] = iconv(‘windows-1251′, ‘UTF-8′, $post_target);
    если в переменной мой жж — всё работает, если сообщество — “Fatal error: Call to undefined method IXR_Client::getErrorpre() … ”
    Не подскажете в чём дело?

    1. Егор пишет:

      ну вот, только пожаловался, как сам разобрался.
      оказался лишним параметр $ljArgs['security']

  21. Sat` пишет:

    а откуда взялся метод $ljClient->getErrorpre()
    в бибилиотеки такого нет

    1. Knave пишет:

      Исправил. Это ошибка – должно быть ErrorCode

  22. WebSeoLife пишет:

    А возможно с помощью интерфейса XML-RPC добавлять в друзья в ЖЖ

  23. WebSeoLife пишет:

    А как с тобой связаться, тоже это интересует.

Оставить комментарий


© 2008–2010 Копилефт и все такое...