Как программно добавить запись в жж (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 должен быть раздел: «Экспорт комментариев», там всё в принципе описано, как и что делать.