Как программно добавить запись в жж (livejournal) ?
В этой статье хочу показать, как можно программно добавить новую запись в жж (livejournal) с помощью протокола XML-RPC и языка c#. Не давно пришлось решать такую задачу, возможно, кому-то тоже понадобиться, поэтому решил оставить здесь готовое решение. Сразу же скажу, что работу протокола объяснять в этой статье не буду, если что-то будет не понятно, то спрашивайте в комментариях либо попробуйте найти ответ в статье: Вызов удаленной процедуры WordPress с помощью протокола XML-RPC.
И так, как обычно для начала создадим Windows Forms приложение, после чего поместим на форму кнопку и текстовое поле (textBox), которое будем использовать для отладки, то есть будем туда выводить различные ошибки, сообщение об успешном выполненном действии и так далее. Затем добавим в проект xml файл (NewPost.xml), в котором будут храниться все передаваемые в запросе параметры.
Добавление новой записи
И так, чтобы создать и добавить новую запись в жж, необходимо вызвать удаленную процедуру postevent.
<?xml version="1.0" encoding="UTF-8"?> <methodCall> <methodName>LJ.XMLRPC.postevent;</methodName> </methodCall>
Обратите внимание, что при указании названия функции используется полное наименование: LJ.XMLRPC.postevent, где первая часть — это префикс, который всегда остаётся неизменным, а вторая часть — это название функции. Это важно помнить, чтобы не допустить ошибку уже в самом начале своей работы.
В качестве аргументов данная функция принимает структуру, которая состоит из 18 параметров:
Аутентификация:
- username(required)
- auth_method(optional)
- password(optional)
- hpassword(optional)
- auth_challenge(optional)
- auth_response(optional)
Пост:
- ver(optional)
- event(required)
- lineendings(required)
- subject(required)
- security(optional)
- allowmask(optional)
- year(required)
- mon(required)
- day(required)
- hour(required)
- min(required)
- props(optional)
Среди доступных параметров всего 9 являются обязательными (required), остальные являются необязательными, поэтому в этой статье многие из них рассматриваться не будут.
Аутентификация в жж
Перед тем, как вызвать удаленную процедуру на сервере, Вам нужно пройти процедуру аутентификации, то есть проверку, например указанного или введенного Вами пароля с паролем, который хранится в базе данных сервера. Всего доступно 3 способа аутентификации: Clear, HTTP Cookies и Challenge-Response. В этой статье рассмотрим первый способ, так как он самый простой, а в следующей статье я расскажу про два оставшихся.
Clear
Для указания способа аутентификации на сервере используется параметр auth_method.
<member> <name>auth_method</name> <value>Clear</value> </member>
Но, так как выбранное нами значение (Clear) используется по умолчанию, то его можно не указывать явно в запросе, как и сам параметр. Но при этом Вам обязательно нужно передать на сервер два дополнительных параметра: username (имя пользователя) и либо параметр password (пароль), который передается открытым текстом (plaintext), либо hpassword, чуть более защищенный способ, который позволяет передать MD5 хэш пароля.
Пример с параметром password.
<params> <param> <value> <struct> <member> <name>username</name> <value>указываем имя пользователя</value> </member> <member> <name>password </name> <value>указываем пароль</value> </member> </struct> </value> </param> </params>

Тип параметра необязательно указывать явно, так как по умолчанию все параметры уже имеют тип string, поэтому хотите, указывайте его, хотите, нет, ошибки не будет.
И ещё один пример с параметром hpassword. В отличие от предыдущего примера, в этом нам сначала нужно получить md5-хэш пароля, а затем добавить полученное значение в элемент value.
using System.Security.Cryptography; //добавить
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] bts = System.Text.Encoding.UTF8.GetBytes(указываем пароль);
bts = md5.ComputeHash(bts);
StringBuilder md5hash = new StringBuilder();
foreach (byte b in bts)
{
md5hash.Append(b.ToString("x2").ToLower());
} Подставляем полученный хэш.
member> <name>username</name> <value>указываем логин</value> </member> <member> <name>hpassword</name> <value>md5hash</value> </member>
Создание новой записи
А теперь переходим к созданию нового поста в жж. Для этого необходимо воспользоваться несколькими оставшимися параметрами:
- event — содержимое поста
- lineendings — указываете, какой тип завершения строк Вы используете. Здесь всё просто, если у Вас Windows, то указываете pc, если linux то unix, если mac — то идентичное название.
- subject — название поста. Длина не более 255 символов в одну строчку без переноса строки.
- year (год)
- Mon (месяц)
- Day (день)
- Hour (часы от 0 до 23)
- Min (минуты)
Помимо обязательных параметров Вы можете добавить и необязательные параметры, например:
ver (версия протокола) — имеет два значения: 0 (по умолчанию) и 1. Основное отличие в том, что протокол версии 1 имеет поддержку Unicode, что даёт Вам возможность обмениваться текстовой информации в кодировке UTF8 между клиентом и сервером.
security (безопасность) — позволяет указать, кто может прочитать созданный пост. Допустимые значения: public (по умолчанию) — для всех и private — личная запись. Так же Вы можете добавить любые другие параметры.
Полная версия XML файла
<?xml version="1.0" encoding="utf-8" ?> <methodCall> <methodName>LJ.XMLRPC.postevent</methodName> <params> <param> <value> <struct> <member> <name>username</name> <value>Vasya</value> </member> <member> <name>password</name> <value>12345<</value> </member> <member> <name>ver</name> <value>1</value> </member> <member> <name>event</name> <value>Hello World!</value> </member> <member> <name>lineendings</name> <value>pc</value> </member> <member> <name>subject</name> <value>Первая запись</value> </member> <member> <name>year</name> <value>2014</value> </member> <member> <name>mon</name> <value>2</value> </member> <member> <name>day</name> <value>3</value> </member> <member> <name>hour</name> <value>15</value> </member> <member> <name>min</name> <value>24</value> </member> </struct> </value> </param> </params> </methodCall>
В ответ на отправленный нами запрос, мы получаем xml документ, который содержит четыре параметра, среди которых Вы можете найти id и ссылку (URL адрес) созданной или добавленной записи. Но, в данном примере нас это не особо интересует, главное убедиться в том, что запрос был успешно выполнен и в документе не содержится элемент fault, который говорит о наличие каких-то ошибок.
Полный листинг кода
//добавить
using System.Xml.Linq;
using System.Net;
using System.IO;
namespace LiveJournalXmlRpcClient
{
public partial class Form1 : Form
{
XDocument XDoc;
//страница, принимающая запрос
string URL = @"http://www.livejournal.com/interface/xmlrpc";
//путь к xml файлу
string xmlFilePath = @"NewPost.xml";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
AddNewPost();
}
private void AddNewPost()
{
try
{
XDoc = XDocument.Load(xmlFilePath);
byte[] byteArray=Encoding.UTF8.GetBytes(XDoc.ToString());
//Создаём запрос
WebRequest request = WebRequest.Create(URL);
//Указываем обязательные заголовки и метод передачи данных
((HttpWebRequest)request).UserAgent = "MyBrowser";
request.Method = "POST";
request.ContentType = "text/xml";
request.ContentLength = byteArray.Length;
request.Credentials = CredentialCache.DefaultCredentials;
//Отправляем данные на сервер
using (Stream dataStream = request.GetRequestStream())
{
if (dataStream != null)
dataStream.Write(byteArray, 0, byteArray.Length);
}
//принимаем ответ
using (WebResponse webResponse = request.GetResponse())
{
//проверяем код ответа
if (((HttpWebResponse)webResponse).StatusCode ==
HttpStatusCode.OK)
{
using (Stream responseStream =
webResponse.GetResponseStream())
{
if (responseStream != null)
{
//загружаем xml документ из потока ответа
XDoc = XDocument.Load(responseStream);
//ответ содержит ошибки?
if (XDoc.Descendants("fault").Count() > 0)
{
debugTxt.Text = "Код ошибки: " +
XDoc.Descendants("value").ElementAt(1).Value +
"\r\n\r\nТекст ошибки: " +
XDoc.Descendants("value").ElementAt(2).Value;
}
else
{
debugTxt.Text = "Запись успешно добавлена!";
}
}
}
}
else
{
debugTxt.Text = "Код ответа: " +
((HttpWebResponse)webResponse).
StatusCode.ToString();
}
}
}
catch (Exception ex)
{
debugTxt.Text = ex.Message;
}
}
}
} результат

Читайте также:
Супер! Как раз начал разбираться с API жж, а нет ли у вас подробных примеров о работе с комментариями. Интересует процесс отслеживания новых комментариев и чтобы на них можно было отвечать.
Готового примера в данный момент нет.
Уже точно не помню, но в их API должен быть раздел: «Экспорт комментариев», там всё в принципе описано, как и что делать.