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

1 марта 2008

Итак. Захотелось мне сделать так, чтобы новости с Автобегиннера транслировались в Живой Журнал. Т.е. добавляется новость на сайт и сразу же появляется в 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->getErrorCode().'] '.$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->getErrorCode().'] '.$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 записи :))))

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

Популярность: 100%

Понравилась заметка? Подписывайся на обновления блога!

Добавить в закладки:google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru
Категории: Интернет Теги: , , , , ,
Смотрите также:

Трекбэки & пингбэки
Комментарии
17 июля 2008

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

пишет Лина К
пишет Knave
14 августа 2008

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

14 августа 2008

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

14 августа 2008

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

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

пишет Knave
26 декабря 2008

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

пишет vadim s. sabinich
13 июня 2009

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

пишет Константин
13 июня 2009

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

пишет Knave
14 июня 2009

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

пишет Константин

RSS-лента комментариев к этой записи. TrackBack URI

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

(обязательно)

(обязательно)