0
0

More than 3 years have passed since last update.

Qiitaに投稿した記事のリンクを楽にWordPressに送りたい #3

Last updated at Posted at 2020-03-03

2020/03/04
デッドロックする可能性があったので一部修正しました。

2020/03/11
WordPressの記事一覧取得が10記事までしか取得できなかったので、すべての記事を取得するように修正しました。WPService.cs

シリーズ

Qiitaに投稿した記事のリンクを楽にWordPressに送りたい #1
Qiitaに投稿した記事のリンクを楽にWordPressに送りたい #2
Qiitaに投稿した記事のリンクを楽にWordPressに送りたい #4

環境

IDE:VisualStudio2019
アプリケーション:コンソールアプリ
フレームワーク:.NET Core 3.1

Qiitaタグを連携する

前回の続きです。

前回、記事の追加/更新は実現できましたが、タグが反映できていなかったので、連携できるようチャレンジしてみます。
tagsは名称ではなく、タグのidを指定する必要があるため、Qiita側とWordPress側で名前が同じもののidを求めて設定する必要があります。
また、同じものがない場合は新規追加して発行されたidを用います。

その前に
前回、記事の作成順がばらばらだったのですが、リクエスト時のJSONのdateにQiitaの記事作成日時を設定することでうまくいきました。

JSON作成部分

                // リクエストBody作成
                var json = new
                {
                    // 作成日時
                    date = DateTime.Parse(qiita["created_at"].ToString()).ToString("s"),

                    // 公開範囲
                    status = "publish",

                    // タイトル
                    title = title,

                    // 本文
                    content = $"\n<p>{title}<a href=\"{url}\">{url}</a></p>\n",
                };

設計

①WordPressタグ一覧取得

②Qiita記事をループしながら、対象のタグが①に存在する場合は、そのidを用いて記事を更新/追加する

③対象のタグが①に存在しない場合は、WordPressのタグ追加リクエストを行い、①に追加したタグの情報を追加する

WordPressタグ一覧取得

API説明
https://ja.wp-api.org/reference/tags/

ネット上で情報を探すと、どうやら全ていっぺんにタグを取得することは不可能とのこと。(PHP側ではやりようがあるとのこと)
上記リンクにあるように {何}ページ目の{何件}取得するかを指定する必要がある模様
特に指定しなかった場合は、1ページ目の10010件が取得される

すべてのページのタグを取得したいので、再起処理を行う

※2020/03/11 GetGetArticleListも修正してます

WPService.cs

        /// <summary>
        /// TOPURL
        /// </summary>
        private const string TOP_URL = "http://kurosu.s1009.xrea.com";

        /// <summary>
        /// 記事取得、投稿時の定義
        /// </summary>
        private const string POSTS = "/wp-json/wp/v2/posts";

        /// <summary>
        /// タグ取得、投稿時の定義
        /// </summary>
        private const string TAGS = "/wp-json/wp/v2/tags";

        /// <summary>
        /// 記事一覧取得
        /// </summary>
        /// <param name="param">パラメータ群</param>
        /// <returns>返り値JSON配列</returns>
        public override async Task<JArray> GetArticleList(params string[] param)
        {
            return await this.GetList(POSTS);
        }

        /// <summary>
        /// タグ一覧取得
        /// </summary>
        /// <param name="page">ページIndex</param>
        /// <returns>返り値JSON配列</returns>
        public async Task<JArray> GetTagList()
        {
            return await this.GetList(TAGS);
        }

        /// <summary>
        /// 指定された要素すべてを取得
        /// </summary>
        /// <param name="url">要素のURL</param>
        /// <param name="page">ページIndex</param>
        /// <returns>返り値JSON配列</returns>
        private async Task<JArray> GetList(string url, int page = 1)
        {
            // 1ページ単位、100件取得
            var responce = await HpClient.GetAsync($"{TOP_URL}{url}?page={page}&per_page=100");

            // 100件区切りした場合のトータルのページ
            // 例えば201件ある場合、3ページとなる
            var toalPage = responce.Headers.GetValues("X-WP-TotalPages").First();

            var body = await responce.Content.ReadAsStringAsync();
            var tagArray = JArray.Parse(body);

            if (Convert.ToInt32(toalPage) > page)
            {
                // 再起処理 すべてのページの要素を収集
                tagArray.Merge(await this.GetList(url, ++page));
            }

            return tagArray;
        }

JSONにtagsを追加

JSON作成部分

    // リクエストBody作成
    var json = new
    {
        // 作成日時
        date = DateTime.Parse(qiita["created_at"].ToString()).ToString("s"),

        // 公開範囲
        status = "publish",

        // タイトル
        title = title,

        // 本文
        content = $"\n<p>{title}<a href=\"{url}\">{url}</a></p>\n",

        // タグ(インサート処理は非同期で実行し、すべての処理が終わるのを待つ)
        tags = await Task.WhenAll(qiita["tags"].Select(async q => await this.GetAndAddTagListAsync(wpService, q, tagList)))
    };

タグ取得 OR 追加メソッド

        /// <summary>
        /// Qiitaタグと同一のWordPressタグIDを取得
        /// WordPress側に存在しない場合は、新規追加を行う
        /// </summary>
        /// <param name="wpService">WPService</param>
        /// <param name="tag">Qiitaタグ</param>
        /// <param name="wpTagList">WordPressタグ一覧</param>
        /// <returns>Qiitaタグと同一のWordPressタグID</returns>
        private async Task<int> GetAndAddTagListAsync(WPService wpService, JToken tag, JArray wpTagList)
        {
            var findTag = wpTagList.FirstOrDefault(wpt => wpt["name"].ToString() == tag["name"].ToString());
            if (findTag == null)
            {
                // Tag追加リクエスト
                var id = await wpService.InsertTag(new { name = tag["name"].ToString() });

                // リストに追加
                wpTagList.Add(JToken.FromObject(new { id = id ?? -1, name = tag["name"].ToString() }));

                return id ?? -1;
            }
            else
            {
                return findTag["id"].Value<int>();
            }
        }

WPService.InsertTagメソッド

        /// <summary>
        /// タグ追加
        /// </summary>
        /// <param name="json">タグ情報JSON</param>
        /// <returns>作成したタグのID</returns>
        public async Task<int?> InsertTag(object json)
        {
            var request = this.CreateHttpRequestMessage(HttpMethod.Post, TOP_URL + TAGS);
            request.Content = new StringContent(JsonConvert.SerializeObject(json), Encoding.UTF8, "application/json");

            // リクエスト
            var result = await HpClient.SendAsync(request);

            // レスポンスbody
            var resultJson = JObject.Parse(await result.Content.ReadAsStringAsync());

            if (result.StatusCode == HttpStatusCode.Created)
            {
                // 追加したタグのIDを返却
                return resultJson["id"].Value<int>();
            }
            else
            {
                // エラーメッセージ
                Console.WriteLine(resultJson["message"].ToString());

                return null;
            }
        }

動作確認

わかりやすいようにすべて削除しておきます。

image.png

タグも空にします。
image.png

実行後
記事一覧
image.png

タグ一覧
image.png

サンプル全文

以下GitHubから取得できます。
TestProject

次回は本アプリをWebサービスに置き換えたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0