Публикация постов в блог Wordpress при помощи API через XML RPC

Просто о NET | создано: 14.06.2017 | опубликовано: 14.06.2017 | обновлено: 22.10.2017 | просмотров: 2461

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

Протокол XML RPC

Выдержка из описания с сайта Wikipedia:

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

Протокол XML-RPC был изначально разработан Дэйвом Винером из компании «UserLand Software» в сотрудничестве с Майкрософт, в 1998 году. Однако корпорация Майкрософт вскоре сочла этот протокол слишком упрощённым, и начала расширять его функциональность. После нескольких циклов по расширению функциональности, появилась система, ныне известная как SOAP. Позднее Майкрософт начала широко рекламировать и внедрять SOAP, а изначальный XML-RPC был отвергнут. Но, несмотря на отвержение его Майкрософтом, стандарт XML-RPC очаровал многих программистов своей необычайной простотой и, за счёт этого, существует по сей день и даже постепенно набирает популярность.

Где используется

На данный момент существует множество полезных и очень полезных ресурсов, которые используют данный транспортный протокол в основе коммуникаций для своих API. В качестве примера могу привести SAPE.RU XML-RPC или XML-RPC WordPress API.

История про блог

Собственно говоря, история такова. Мой блог, который вы сейчас читаете, до недавнего времени был написан на ASP.NET MVC 5. В блоге работала система продажи ссылок Sape (ссылки не особо конечно продавались, но разговор не про них). После выхода в статус Release платформы ASP.NET Core у меня не получилось найти примеров кода для реализации этой же системы продажи ссылок на новой платформе. Пришлось немного углубиться в тему XML RPC и написать подобную систему собственноручно.

В общем, у меня получилось написать XML RPC Client nuget-пакет, который может отправлять запросы и обрабатывать ответы по протоколу XML RPC без привязки к конкретному сервису. А также, в дополнение к этому пакету, я сделал другой nuget-пакет Calabonga.Sape.Loader, который может работать уже непосредственно с Sape XML API, но речь в статье про первый, поэтому перейдем к примерам кода.

Блог на Wordpress

У меня есть блог на сайте wordpress. Редко, но всё-таки бывает такое, что я публикую туда посты, которые не связаны с программированием, хотя и про .NET бывают там публикации. И как раз на примере моего блога я хочу продемонстрировать работу моего nuget-пакета. У Wordpress есть отлично документированный Wordpress API XML RPC. Вперед!

Демонстрация работы XML RPC Client

Я создал небольшое консольное приложение, в которое установил упомянутый выше nuget-пакет.

Сервис предоставляет обширные возможности по управлению сущностями через API. Вот только основные методы:

список основных методов сервиса

Я создал небольшой класс, в котором прописал названия только некоторых из перечисленных методов:

public class WordpressClient {
    public const string ApiUrl = "https://calabonga.wordpress.com/xmlrpc.php";
    public const string Login = "WordPressAccount";
    public const string Password = "xxxxxxxxxxxxxxx";
    public const int UserId = 000000;
    public const int BlogId = 0;

    public class Requests {
        public const string Hello = "demo.sayHello";
        public const string GetUser = "wp.getUser";
        public const string GetUsers = "wp.getUsers";
        public const string GetProfile = "wp.getProfile";
        public const string GetAuthors = "wp.getAuthors";
        public const string GetPosts = "wp.getPosts";
        public const string GetPost = "wp.getPost";
        public const string GetNewPost = "wp.newPost";
        public const string GetPostType = "wp.getPostType";
        public const string GetPostStatusList = "wp.getPostStatusList";
        public const string GetPostTypes = "wp.getPostTypes";
        public const string GetMediaLibrary = "wp.getMediaLibrary";
        public const string GetMediaItem = "wp.getMediaItem";
        public const string UploadFile = "wp.uploadFile";
    }
}

Примеры XML RPC запросов

Вот основной код моего консольного приложения:

class Program {

    private static readonly XmlRpcClient Client = 
                 new XmlRpcClient { Url = WordpressClient.ApiUrl };

    static void Main(string[] args) {

        GetHelloMessage();

        GetPostStatusList();

        GetPostTypeList();

        GetPosts();

        GetPost(666);

        GetMediaLibrary();

        GetMediaItem(185);
    }

    // сами методы удалены для краткости
}

demo.sayHello

А теперь по порядку описание методов. Первый метод GetHelloMessage():

private static void GetHelloMessage() {
    var request = new XmlRpcRequest(WordpressClient.Methods.Hello);
    var result = Client.Execute(request);
    if (result.XmlRpcResponse.IsFault()) {
        Console.WriteLine(result.XmlRpcResponse.GetFaultString());
    }
    Console.WriteLine(result.XmlRpcResponse.GetString());
}

Результат выполнения данного метода такой:

wp.getPostStatusList

Получение списка статусов для постов:

private static void GetPostStatusList() {
    var request = new XmlRpcRequest(WordpressClient.Methods.GetPostStatusList);
    request.AddParams(WordpressClient.BlogId, WordpressClient.Login, WordpressClient.Password);
    var result = Client.Execute(request);
    if (result.XmlRpcResponse.IsFault()) {
        Console.WriteLine(result.XmlRpcResponse.GetFaultString());
    }
    Console.WriteLine(result.XmlRpcResponse.GetString());
}

Результат:

wp.getPostTypes

Получение списка доступных типов для поста:

private static void GetPostTypeList() {
    var request = new XmlRpcRequest(WordpressClient.Methods.GetPostTypes);
    request.AddParams(WordpressClient.BlogId, WordpressClient.Login, WordpressClient.Password);
    var result = Client.Execute(request);
    if (result.XmlRpcResponse.IsFault()) {
        Console.WriteLine(result.XmlRpcResponse.GetFaultString());
    }
    Console.WriteLine(result.XmlRpcResponse.GetString());
}

Результат запроса вернул много букв, поэтому сокращу ответ:

wp.getPosts

Этот метод GetPosts() возвращает постранично все ваши посты с Wordpress.

private static void GetPosts() {
    var request = new XmlRpcRequest(WordpressClient.Methods.GetPosts);
    request.AddParams(WordpressClient.BlogId, WordpressClient.Login, WordpressClient.Password);
    var result = Client.Execute(request);
    if (result.XmlRpcResponse.IsFault()) {
        Console.WriteLine(result.XmlRpcResponse.GetFaultString());
    }
    var posts = result.XmlRpcResponse.GetObject();
    Console.WriteLine(JsonConvert.SerializeObject(posts));
}

Результат запроса тоже покажу в JSON-формате. В листинге в строке 8, я как раз его и сериащизую:

wp.getPost

Данный метод GetPost() получает пост по идентификатору. Так как я в прошлом запросе получил список, то получить любой из них по идентификатору не составит труда:

private static void GetPost(int postId) {
    var request = new XmlRpcRequest(WordpressClient.Methods.GetPost);
    request.AddParams(WordpressClient.BlogId, WordpressClient.Login, WordpressClient.Password, postId);
    var result = Client.Execute(request);
    if (result.XmlRpcResponse.IsFault()) {
        Console.WriteLine(result.XmlRpcResponse.GetFaultString());
    }
    var post = result.XmlRpcResponse.GetObject();
    Console.WriteLine(JsonConvert.SerializeObject(post));
}

Я также полученный результат сериализую в JSON:

wp.getMediaLibrary

Метод возвращает коллекцию медиа файлов, которые хранятся в вашем блоге. В моем случае, это набор картинок:

private static void GetMediaLibrary() {
    var request = new XmlRpcRequest(WordpressClient.Methods.GetMediaLibrary);
    request.AddParams(WordpressClient.BlogId, WordpressClient.Login, WordpressClient.Password);
    var result = Client.Execute(request);
    if (result.XmlRpcResponse.IsFault()) {
        Console.WriteLine(result.XmlRpcResponse.GetFaultString());
    }
    var library = result.XmlRpcResponse.GetObject();
    Console.WriteLine(JsonConvert.SerializeObject(library));
}

Полученный ответ также сериализую в JSON, но теперь покажу как результат в консоле.

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

wp.getMediaItem

Метод возвращает одну сущность из этой медиа-коллекции:

private static void GetMediaItem(int attachmentId) {
    var request = new XmlRpcRequest(WordpressClient.Methods.GetMediaItem);
    request.AddParams(WordpressClient.BlogId, WordpressClient.Login, WordpressClient.Password, attachmentId);
    var result = Client.Execute(request);
    if (result.XmlRpcResponse.IsFault()) {
        Console.WriteLine(result.XmlRpcResponse.GetFaultString());
    }
    var library = result.XmlRpcResponse.GetString();
    Console.WriteLine(library);
}

Результат также покажу в окне консольного приложения:

Можете поверить, всё работает исключительно быстро и правильно.

Заключение

Я привел несколько примеров использования nuget-пакета XML RPC Client. А вы, в свою очередь, можете с легкостью реализовать другие нужные вам методы, посмотрев параметры метода в документации. В примерах я не делал десериализацию в объекты пришедшего от сервера ответа, но сделать это можно, например, при помощи Newtonsoft.JSON библиотеки. Думаю, понятно, что для добавления новой статьи в блог на Wordpress надо реализовать подобным способом метод wp.newPost.

Другими словами, nuget-пакет получился универсальным, вы можете его использовать для работы с любыми XML RPC сервисами.