てっくぼっとの最近のブログ執筆環境事情について

こんにちは。普段はクライアントエンジニアをしている向井です。
最近てっくぼっとでは、記事執筆環境の刷新を行いました。
今回は、その内容についてご紹介します。

いままでのてっくぼっとの執筆環境

いままでのてっくぼっとでは、GoogleDocsによって下書きを管理していました。
具体的には下記のフローとなります。

  1. 記事のネタになりそうなネタを週一定例で吸い上げ、依頼をする
  2. 担当者の方がGoogleDocsにて記事の下書きを書き、定例にてレビューする
  3. レビュー完了後に、担当者がWordPressにて記事をアップロードする
  4. 公開する

上記のフローで問題として上がっていたのは以下の点です。

  • GoogleDocsからWordPressへの記事のアップロードが煩雑である
  • ネタの吸い上げのコストが高い

いままで下書き環境としてGoogleDocsを利用していた理由は、任意の箇所にコメントを行える点や、「提案モード」を用いて記事の修正をスムーズに行える点などなど、主にレビュワーのコストを低く抑えられるというメリットのためでした。

一方で、記事のアップロードは担当者に手動で行ってもらっていたために、手間がかかる状況でした。
なによりも、GoogleDocsではソースコードを貼り付ける機能がなく、技術ブログなのにソースコードの貼り付けが苦痛というのは大変良くないと感じていました。

技術ブログというものは、記事の担当者への負担が大きいため、少しでも担当者への負担をへらす必要があると感じていたので、執筆環境の改善を決意しました。

Qiita:Teamの導入

これは技術ブログチームからの提案ではないのですが、弊社では組織横断の技術共有のためにQiita:Teamを取り入れました。

Qiita:Teamでは大小問わず、様々な技術共有が行われるようになりました。
そこでネタの吸い上げを、Qiita:Teamの成果物から行うことも視野に入れました。

Qiita2WordPress

上記の環境の変化もあり、ブログの執筆環境をQiita:Teamにすれば、担当者への負担も軽減できるのではと思い、ブログのすべての下書きをQiita:Team上で管理するように変更しました。
合わせて、前から問題になっていたWordPressへの記事のアップロードも、QiitaのAPIとWordPressのAPIを用いて自動化することで改善を試みました。

処理の流れは以下になります。

  1. 記事の下書きをQiita:Teamにあげる
  2. 記事情報と、記事中の画像をQiita APIから取得する
  3. 2.で取得した記事を、投稿用に整形する
  4. 3.で整形した記事と画像を、WordPress APIを用いてアップロードする

Qiita2WordPressの構成は以下の通りです。

Qiita2WordPressの概要

Qiita APIの利用

Qiita2WordPressでは、記事の取得と、画像情報の取得に、Qiita APIを利用しています。

Qiita:Teamは、通常のQiitaと同様にAPIが利用できるようです。

すべてのAPIの利用には認証が必要になります。認証はアクセストークンを用いて行います。今回やりたいことは、Qiita:Teamの読み込み権限(read_qiita_team)のみが必要になるので、事前に用意しておきます。
PHPでは、GuzzleというHTTP Cliehtを用いて、下記のように認証を実装できます。

$httpClient = new \GuzzleHttp\Client(
    array(
        'base_uri' => $baseUri, // $baseUriにはQiita:TeamのURI(チームID.qiita.com)が格納されている
    )
);

// リクエストヘッダーに、Authorizationを付加する
$options = array(
    'headers' => array(
        'Authorization' => "Bearer {$accessToken}", // $accessTokenは事前に取得しておく
    )
);

// APIリクエストを行う
$response = $httpClient->request(
    $method,
    $uri,
    $options
);

上記を用いて、記事情報は下記のように取得できます。

// APIリクエストを行う
$response = $httpClient->request(
    "GET",
    "/api/v2/items/{$itemId}", // $itemIdは、https://チームID.qiita.com/username/items/アイテムID のアイテムID部分
    $options // 先程の$options
);

// 通信が正常という前提で、レスポンスはjson形式で提供される
$item = json_decode($response->getBody()->getContents(), true);

記事中の画像を取得するAPIは提供されていないので、先程の記事データから、画像URLを抽出することで対応を試みました。
画像URLはhttps://*.qiita.com/files/ファイルID.拡張子であることから、正規表現を用いてURLを抽出しています。

$pattern = "/" . preg_quote($baseUrl, "/") . "\/files\/(.*?\.(gif|jpeg|png))/";
if (preg_match_all($pattern, $item['rendered_body'], $matchedResult) !== 0) {
    foreach ($matchedResult[1] as $fileName) {
        // $fileNameにファイルIDが格納されている
    }
}

画像のコンテンツそのものは、上記の認証を用いて、下記のように取得できるようです(ドキュメントには乗っていませんが…)。

$response = $httpClient(
    "GET",
    "/files/{$fileId}", // 上記のファイルID
    $options
);

WordPress APIの利用

Qiita2WordPressでは、記事の投稿とメディア(画像)の保存に利用しています。

WordPressでは4.7からREST APIが提供されており、記事の読み込みや書き込みなど、一連の操作を行うことができます。
認証は幾つかの方法がありますが、Application Passwordsを用いています。

PHPでは下記のように実装できます。

$httpClient = new \GuzzleHttp\Client(
    array(
        'base_uri' => $baseUri, // $baseUriにはWordPressのURLを格納されている
    )
);

$options = array(
    'auth' => (
        $username, // ユーザー名
        $password, // Application Passwordsで生成したトークン
    )
);

// APIリクエストを行う
$response = $httpClient->request(
    $method,
    $uri,
    $options
);

メディアの保存は下記で実現できます。

$options['multipart'] = array(
    'name' => 'file',
    'contents' => $content,
    'filename' => $fileName,
);

$response = $httpClient(
    "POST",
    "/wp-json/wp/v2/posts/{$entryId}",
    $options
);

// 通信が正常という前提で、レスポンスはjson形式で提供される
$media = json_decode($response->getBody()->getContents(), true);

// フルサイズの画像のURLが取得できる
$mediaUrl = $media['media_details']['sizes']['full']['source_url'];

$mediaUrlには、WordPress上での画像URLが格納されているので、投稿する記事HTML内の、Qiita上の画像URLを$mediaUrlで置換することで、記事中の画像をWordPressのものに置き換えられます。

記事の投稿は、下記のコードで実装できます。

$options['form_params'] = array(
    'slug' => $slug,       // スラッグ
    'title' => $title,     // 記事タイトル
    'status' => $status,   // 記事ステータス
    'content' => $content, // 記事HTML
);

$response = $httpClient(
    "POST",
    "/wp-json/wp/v2/posts",
    $options
);

まとめ

現状課題として上がっていたてっくぼっとの執筆環境を、Qiita APIとWordPress APIの2つを用いることで自動化を試みました。
この改善が、ブログ担当者の執筆の手間を省ければと思っています。