1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WordPressのREST APIをカスタム拡張して、Cocoonの独自PVデータをMakeで自動集計してみた

1
Posted at

はじめに

WordPressサイトを運営していると「今日のPV数」が気になるものですが、Googleアナリティクス(GA4)のAPIは仕様変更が激しく、認証やデータ取得のハードルが低くありません。また、外部プラグインでの通知は通知メールが英語だったり、不要な機能が多くてパフォーマンス低下に繋がることがあります。

そこで今回は、国内の人気テーマ「Cocoon」がデータベース内(wp_cocoon_accesses テーブル)に保持している高精度なアクセスログを直接活用することにしました。
WordPressの**REST APIをカスタム拡張(エンドポイントのフィールド追加)**し、ノーコードiPaaSの「Make(旧Integromat)」を使って、毎日指定時間に今日・今週・今月のPV数をメールへ自動通知する軽量なシステムを構築したため、その実装方法を共有します。


全体のシステム構成

  1. WordPress(データソース): register_rest_field を用いて、通常の posts および pages のエンドポイントに独自のPV集計オブジェクト(cocoon_pv_report)をインジェクションします。
  2. Make(iPaaS / 司令塔): 定期実行タイマーをトリガーに、HTTPモジュールでWordPress APIを叩いてデータを全件取得し、成形します。
  3. Gmail(通知): 集計したテキストデータを指定アドレス宛に送信します。

1. WordPress側の実装(REST APIの拡張)

WordPressの標準フック rest_api_init を利用し、各投稿データの取得時にCocoonのカスタムテーブルから該当記事の post_id に紐づくアクセス数をSQLで直接集計してレスポンスに含めます。

⚠️ 実装上の注意点

Cocoonのアクセス集計処理や独自フックの読み込み順の関係上、子テーマの functions.php ではAPI拡張が正常に動作しない(集計データがフックに噛み合わない)ケースがありました。
そのため、本実装は親テーマ(Cocoon)の functions.php の最下部に追記するか、カスタムプラグイン化して読み込みタイミングを担保することを推奨します。

// wp_cocoon_accessesから投稿・固定ページのPVを自動計算してREST APIに出力する
add_action('rest_api_init', 'register_cocoon_final_calculated_pv');
function register_cocoon_final_calculated_pv() {
    // 投稿(post)と固定ページ(page)のエンドポイントを対象にする
    foreach (array('post', 'page') as $post_type) {
        register_rest_field($post_type, 'cocoon_pv_report', array(
            'get_callback' => function($post_array) {
                global $wpdb;
                $post_id = $post_array['id'];
                $table_name = $wpdb->prefix . 'cocoon_accesses';
                
                // タイムゾーンを考慮した現在時刻と、集計期間の算出
                $current_time = current_time('mysql');
                $today_date   = current_time('Y-m-d');
                $seven_days_ago  = date('Y-m-d', strtotime('-7 days', strtotime($current_time)));
                $thirty_days_ago = date('Y-m-d', strtotime('-30 days', strtotime($current_time)));
                
                // 1. 本日のPV数(SUM)
                $daily_pv = $wpdb->get_var($wpdb->prepare(
                    "SELECT SUM(count) FROM $table_name WHERE post_id = %d AND date = %s",
                    $post_id, $today_date
                ));
                
                // 2. 過去7日間のPV数(SUM)
                $weekly_pv = $wpdb->get_var($wpdb->prepare(
                    "SELECT SUM(count) FROM $table_name WHERE post_id = %d AND date >= %s",
                    $post_id, $seven_days_ago
                ));
                
                // 3. 過去30日間のPV数(SUM)
                $monthly_pv = $wpdb->get_var($wpdb->prepare(
                    "SELECT SUM(count) FROM $table_name WHERE post_id = %d AND date >= %s",
                    $post_id, $thirty_days_ago
                ));
                
                // 4. 累計PV数(SUM)
                $overall_pv = $wpdb->get_var($wpdb->prepare(
                    "SELECT SUM(count) FROM $table_name WHERE post_id = %d",
                    $post_id
                ));
                
                // null の場合は 0 にキャストして返す
                return array(
                    'source'     => 'cocoon_calculated_success',
                    'daily_pv'   => $daily_pv ? (int)$daily_pv : 0,
                    'weekly_pv'  => $weekly_pv ? (int)$weekly_pv : 0,
                    'monthly_pv' => $monthly_pv ? (int)$monthly_pv : 0,
                    'overall_pv' => $overall_pv ? (int)$overall_pv : 0
                );
            },
            'schema' => null,
        ));
    }
}

拡張後のJSONレスポンス(スキーマ例)

コード適用後、 /wp-json/wp/v2/posts/wp-json/wp/v2/pages にリクエストを投げると、オブジェクト内に以下のような cocoon_pv_report フィールドが拡張されます。

[
  {
    "id": 123,
    "title": {
      "rendered": "サンプル記事タイトル"
    },
    "type": "post",
    "cocoon_pv_report": {
      "source": "cocoon_calculated_success",
      "daily_pv": 45,
      "weekly_pv": 312,
      "monthly_pv": 1250,
      "overall_pv": 5420
    }
  }
]

image.png

2. Make(旧Integromat)でのデータ集計・フロー構築

WordPressから出力された配列データを成形し、1通のメールに集約するためのデータパイプラインを直列(一本道)で構築します。

モジュール接続のアーキテクチャ

複数の異なるエンドポイント(posts / pages)を1通のメールにマージするため、以下のようにシリアルに接続します。

HTTP (posts) -> Iterator (posts) -> Text Aggregator (posts) -> HTTP (pages) -> Iterator (pages) -> Text Aggregator (pages) -> Gmail
image.png

① HTTPモジュールのペイロード制限の回避

WordPress REST APIのデフォルトの取得件数は1リクエストあたり10件です。全件、もしくは主要ページをカバーするため、クエリパラメータで per_page=100(最大値)を指定します。また、レスポンスを後続のモジュールでパースできるよう「Parse response: Yes」を設定します。

  • 投稿取得URL: https://example.com/wp-json/wp/v2/posts?per_page=100
  • 固定ページ取得URL: https://example.com/wp-json/wp/v2/pages?per_page=100

② Iterator と Text Aggregator によるデータ構造の平坦化

HTTPモジュールから返ってきたJSON配列を Iterator で1つのループに分解し、Text Aggregator で文字列として結合(リダクション)します。
「Row content」欄には、拡張したJSONスキーマをマッピングします。

■ 記事タイトル: {{1.title.rendered}}
  ・今日のPV: {{1.cocoon_pv_report.daily_pv}} PV
---------------------------------

③ Gmailモジュールでのメッセージ作成

最後に配置したGmailモジュールの「Content(本文)」に、それぞれのText Aggregator(例: モジュール3とモジュール6)の出力テキスト(text)を並べて配置し、1通のメールにマージします。

お疲れ様です。本日のPV数をお知らせします。

【投稿ページのPV】
{{3.text}}

【固定ページのPV】
{{6.text}}

あとはMakeのSchedulingスイッチをONにし、毎日希望の時間に実行されるようタイマーをセットすれば、サーバーレス&プラグインレスなPV通知システムが完成します。


💡 応用:カスタム投稿タイプ(CPT)への拡張

もしプロジェクト内でカスタム投稿タイプ(例:portfolioreviews など)を運用している場合でも、再利用性を高める設計にしているため容易に拡張可能です。

1. PHPコードの配列に追加

foreach の配列要素に、対象のカスタム投稿タイプ名(例: c1)を追加します。

// 修正前
foreach (array('post', 'page') as $post_type) {

// 修正後:カスタム投稿「c1」を追加する場合
foreach (array('post', 'page', 'c1') as $post_type) {

Makeのフローの途中に「HTTP」「Iterator」「Text Aggregator」の3連モジュールを複製して挟み込み、URLを https://example.com/wp-json/wp/v2/c1?per_page=100 に向けるだけで、メール本文に3つ目のセクションとして統合可能です。


おわりに

WordPressのREST APIは非常に強力で、 register_rest_field を使うだけでプラグインのデータベースや独自テーブルのデータすらも簡単に外部へ露出させることができます。

重いアクセス解析プラグインを導入したり、仕様変更の激しいGA4の認証に頭を抱えたりする代わりに、WordPress側を「軽量なデータソース(API)」として割り切り、集計や通知のロジックは外部iPaaS(Make)に任せるというアプローチは、サイトのパフォーマンス維持と開発効率の面で非常におすすめです。

WordPressのヘッドレス化や外部連携の参考になれば幸いです。

1
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?