動機
WordPressのHPにQiitaに投稿した記事のリンクを公開しているのですが、その方法がQiitaリンクをWordPressに手動で張り付けるというものであり、これが結構手間で、自動化できないかと思い、自作することにしました。RPAで実現すればいいのかな・・・?
欲を言えば、Qiitaに投稿した瞬間に自動で連携してくれればベストですが、記事を投稿した時のイベントをフック(検知)する必要があります。
→QiitaにはWebhookというものがありました。
これは、記事投稿時等に指定されたURLへ作成した記事の情報をPOST送信する機能です。
その他には定期的にQiitaの記事を監視して同期する物を作ってもいいと思うんですけど、そのサービスなりプログラムが常駐していないといけないのもなぁと・・・
ベスト
- 記事を投稿したタイミングでWordPressに反映してほしい
ベストを実現するには
- WordPressに記事をインポートするサービス(Webサービス)の構築・・・①
- ①を配置するサーバーの用意 → 常時動いていてほしいので、ローカルではなく、クラウド上にする
- 記事を投稿した時にWebhookを用いて、WordPressに記事をインポートするサービスを呼び出す
段階的に進めて実現を目指す
いきなりベストの構築をやろうとするとなんかめんどくさいので、段階的に作っていって、動作や使用間を確認しながら、完成にもっていくようにしようと思います。そのほうが精神衛生上良い気がする。
以下にロードマップ的なプロセスを記載します。
プロセス
- Qiitaから記事を読み取って、WordPressに記事をインポートするアプリケーションを作る(c# コンソールアプリ)
- 「1.」をWebサービス化する(ローカルにWebサービスとして立てる)
- 「2.」のサービスをブラウザから1クリックで呼び出す。→ブックマークレット
- 「2.」のサービスをクラウド上のレンタルサーバーに乗せる
- 「2.」のサービスをWebhookから受けた情報を用いてWordPressに送信できるように改修する
まずは1. Qiitaから記事を読み取って、WordPressに記事をインポートするアプリケーションを作る(c# コンソールアプリ)からやっていきたいと思います。
環境
IDE:VisualStudio2019
アプリケーション:コンソールアプリ
フレームワーク:.NET Core 3.1
転送の仕様
- WordPressの記事一覧内にQiita側の記事が存在しない場合、WordPressに新規追加する
- WordPressの記事一覧内にQiita側の記事が存在する場合、WordPressの記事を更新する
- 存在可否の判定はWordPress記事内のQiitaリンクURLと、Qiitaの記事のURLを比較して行う。
Qiita APIを用いて、記事を取得
Qiita API v2 の概要(非公式)を参考にさせていただいて、指定ユーザの投稿記事一覧取得APIの/api/v2/users/:user_id/itemsを使用したいと思います。
GETのリクエストにはHttpClientを使用しようと思います。
基底クラス
HttpClientを使いまわすため、基底クラスを用意します。
usingNewtonsoft.Json.Linq;usingSystem.Net.Http;usingSystem.Threading.Tasks;namespaceTestProject.QiitaToWP{/// <summary>/// サービス基底クラス/// </summary>publicabstractclassServiceBase{/// <summary>/// HttpClient/// </summary>protectedstaticreadonlyHttpClientHpClient;/// <summary>/// staticコンストラクタ/// </summary>staticServiceBase(){HpClient=newHttpClient();}/// <summary>/// 記事一覧取得/// </summary>/// <param name="param">パラメータ</param>/// <returns>記事一覧</returns>publicabstractTask<JArray>GetArticleList(paramsstring[]param);}}Qiitaの記事一覧取得
usingNewtonsoft.Json.Linq;usingSystem.Threading.Tasks;namespaceTestProject.QiitaToWP{/// <summary>/// QiitaAPI呼び出しクラス/// </summary>publicclassQiitaService:ServiceBase{privateconststringURL_FIRST="https://qiita.com";privateconststringGET_ARTICLELIST="/api/v2/users/{0}/items";publicoverrideasyncTask<JArray>GetArticleList(paramsstring[]param){varbody=awaitHpClient.GetStringAsync(URL_FIRST+string.Format(GET_ARTICLELIST,param[0]));returnJArray.Parse(body);}}}WordPress APIを用いて、記事一覧取得
WordPressの記事取得
公式のリファレンスを参考にしました。
WordPress API 投稿の「Post一覧」の部分です。
※GetArticleListだけ参照してください。
usingNewtonsoft.Json.Linq;usingSystem;usingSystem.Net;usingSystem.Net.Http;usingSystem.Text;usingSystem.Threading.Tasks;namespaceTestProject.QiitaToWP{/// <summary>/// WordPress API呼び出しクラス/// </summary>publicclassWPService:ServiceBase{privateconststringURL_FIRST="http://kurosu.s1009.xrea.com";privateconststringGET_ARTICLELIST="/wp-json/wp/v2/posts";privateconststringUPDATE_ARTICLE="/wp-json/wp/v2/posts/{0}";publicoverrideasyncTask<JArray>GetArticleList(paramsstring[]param){varbody=awaitHpClient.GetStringAsync(URL_FIRST+GET_ARTICLELIST);returnJArray.Parse(body);}publicasyncTask<bool>UpdateWPArticle(stringid,stringjson){// TODO「Application Passwords」プラグインというプラグインを有効化にしていないせいかまだ動作しないvarcredentials=Convert.ToBase64String(Encoding.UTF8.GetBytes("XXXX:BBBBBBB"));varcontent=newStringContent(json,Encoding.UTF8,"application/json");content.Headers.TryAddWithoutValidation("Authorization",$"Basic {credentials}");varresult=awaitHpClient.PostAsync(URL_FIRST+string.Format(UPDATE_ARTICLE,id),content);if(result.StatusCode==HttpStatusCode.OK){returntrue;}else{returnfalse;}}}}上記2つのサービスクラスを操作するクラス
usingSystem.Linq;usingSystem.Threading.Tasks;namespaceTestProject.QiitaToWP{publicclassQiita2WP{publicasyncTaskQiita2WPArticle(){// Qiita記事取得varqiitaService=newQiitaService();varqiitaList=awaitqiitaService.GetArticleList("GodPhwng");// WP記事取得varwpService=newWPService();varwpList=awaitwpService.GetArticleList();foreach(varqiitainqiitaList){varurl=qiita["url"].ToString();vartitle=qiita["title"].ToString();// Qiitaの記事URLが含まれる物を取得varmatchArticle=wpList.FirstOrDefault(w=>w["content"]["rendered"].ToString().Contains(url));// 記事更新if(matchArticle!=null){// タイトルmatchArticle["title"]=title;// リンク部分matchArticle["content"]["rendered"]=$"\n<p>{title}<a href=\"{url}\">{url}</a></p>\n";// 更新varresult=awaitwpService.UpdateWPArticle(matchArticle["id"].ToString(),matchArticle.ToString());}// 記事新規追加else{// TODO}}}}}メインクラス
usingSystem;usingSystem.Threading.Tasks;namespaceTestProject.QiitaToWP{publicclassProgram{publicstaticasyncTaskMain(string[]args){try{varq2wp=newQiita2WP();// Qiitaの記事をWordPressに反映awaitq2wp.Qiita2WPArticle();}catch(Exceptionerr){Console.WriteLine(err.Message);}finally{Console.Read();}}}}取得は正常動作、更新はダメ
Qiita、WordPressの両方共取得処理は正常動作しました。
公開されているデータなので認証等も必要ありません。
追加、更新処理については認証が必要であり、OAuth認証/アプリケーションパスワードまたはベーシック認証を利用する必要があるようです。
まずWordPress側で設定をする必要があるようです。WordPress 認証
現状私のほうでその設定をする権限がないため(ある先輩のWordPressの環境を使わせてもらっており、先輩が管理者のため・・・)
今回はここまでとします。
次回は、設定を有効後、記事追加と更新をやっていきます。