弊社運営のウェブメディア「ブックレコメンド」では広告配信を自動化しています。

WordPressで広告配信管理する記事の続きです。今回は、

■ 広告料金支払いをStripeで受け付ける
■ 支払いがあったら、広告をカスタム投稿に自動登録する
■ 広告申し込みフォームで広告のプレビューを表示する

を紹介します。

広告料金支払いをStripeで受け付ける

Stripe決済には、プラグイン WPPayFormを使っています。選定理由としては、「フックが多数用意されている(=追加カスタマイズが行いやすい)」「プラグインの有償版がある(=開発元の経営が安定しやすい)」です。

プラグインをインストール・有効化します。
フォームを作成します。(admin.php?page=wppayform.php で、フォームを追加をクリックする)
フォームの各項目のIDをメモしておきます(下の画像のオレンジ楕円部分)。自動化するときにIDが必要になります。

商品数を設定
広告配信開始日を設定

支払いがあったら、広告をカスタム投稿に自動登録する

支払い時に広告を登録したいので、フックを探します。今回は、wppayform/wpf_before_submission_data_insert フックを使いました。

function ounziw_ad_register($submission, $form_data)
{
    // フォーム入力からデータ取得 // $form_data[ID] のIDはフォーム作成画面で調べておく
    $day = $form_data['item_quantity'];
    $price = $form_data['payment_item'] * $day;
    $url = $form_data['text'];

    if ($url && filter_var($url, FILTER_VALIDATE_URL)) {
        // 入力urlチェック okの場合

        // 広告urlを登録/更新
        $image =  $form_data['text_1'];
        $heading1 =  $form_data['text_2'];
        $heading2 =  $form_data['text_3'];
        $startday =  $form_data['date'];
        $starttime =  $form_data['date_1'];
        $ad_end = ounziw_update_ad($url, $day, $image, $heading1, $heading2, $startday, $starttime);

        $subject = "広告申し込みがありました。";
        $ad_interval_message = '広告期限:' . $ad_end . "まで\r\n";
    } else {
        // 入力urlチェック ngの場合
        $subject = "[url不備] 広告申し込みがありました。";
        $ad_interval_message = '';
    }

    // 管理者へ通知する
    // 送信元メール
    $from = "info@book-recommend.com";
    $headers[] = 'From: ' . $from;
    // 管理者のメール = 送付先
    $to = get_option('admin_email');
    //
    $body = '広告申し込みがありました。' . "\r\n";
    $body .= 'URL: ' . $url . "\r\n";
    $body .= '画像: ' . $image . "\r\n";
    $body .= '一行目: ' . $heading1 . "\r\n";
    $body .= '二行目: ' . $heading2 . "\r\n";
    $body .= '金額: ' . $price . '円(消費税込)' . "\r\n";
    $body .= $ad_interval_message;
    $body .= "\r\n";
    $body .= '--' . "\r\n";
    $body .= 'ブックレコメンド' . "\r\n";
    $body .= 'https://book-recommend.com/' . "\r\n";

    wp_mail($to, $subject, $body, $headers);
}

add_action('wppayform/wpf_before_submission_data_insert', 'ounziw_ad_register', 10, 2);

function ounziw_update_ad($url, $day, $image, $heading1, $heading2, $startday, $starttime)
{

    if (!$url) {
        return;
    }
    if (!filter_var($url, FILTER_VALIDATE_URL)) {
        return;
    }
    if (!$day) {
        return;
    }

    // 同じurlの投稿があるかをチェックする
    $now = new DateTime('now', wp_timezone());
    $args = [
        'post_type' => 'adurl',
        'posts_per_page' => 1,
        'title' => $url,
        'meta_key' => 'ad_end',
        'orderby' => 'meta_value',
        'order' => 'rand',
        'meta_query' => [
            [
                'key'     => 'ad_start',
                'value'   => $now->format('Y-m-d H:i:s'),
                'compare' => '<=',
            ],
            [
                'key' => 'ad_end',
                'value' => $now->format('Y-m-d H:i:s'),
                'compare' => '>=',
            ],
        ],
    ];
    $the_query = new WP_Query($args);

    if ($the_query->have_posts()) {
        // 同じurlの投稿がある -> その投稿IDを取得する (その投稿の広告期限を延長する)
        $the_query->the_post();
        $pid = get_the_ID();
        wp_reset_postdata();
    } else {
        // 同じurlの投稿がない -> 新しくカスタム投稿を作成する
        $postdata = [
            'post_title' => $url,
            'post_content' => '',
            'post_status' => 'publish',
            'post_type' => 'adurl',
        ];
        $pid = wp_insert_post($postdata);
    }
    // カスタムフィールドに保存する
    update_post_meta($pid, 'image', $image);
    update_post_meta($pid, 'heading1', $heading1);
    update_post_meta($pid, 'heading2', $heading2);

    // 広告の開始日時を現在に指定する
    $ad_start = new DateTime('now', wp_timezone());
    // フォームで広告開始日が指定されている場合の処理
    if ($startday) {
        // 日時をDateTimeクラスに設定 
        $day_array = explode('-', $startday);
        $ad_start->setDate($day_array[0], $day_array[1], $day_array[2]);
        $time_array = explode(':', $starttime);
        $ad_start->setTime($time_array[0], $time_array[1]);

        // 現在時刻と比較して、大きい方を取得
        $ad_start = max($ad_start, $now);
    }
    // カスタムフィールドに保存する
    $ad_start_time = $ad_start->format('Y-m-d H:i:s');
    update_post_meta($pid, 'ad_start', $ad_start_time);

    // 広告の基準時刻=現在
    $ad_time = $ad_start;
    // 有効期限が残っている場合は、そちらの時刻を採用する
    $ad_end_raw = get_post_meta($pid, 'ad_end', true);
    if ($ad_end_raw) {
        $ad_end = new DateTime($ad_end_raw, wp_timezone());
        $ad_time = max($ad_start, $ad_end);
    }

    // 日数を追加する
    $day_format = 'P' . intval($day) . 'D';
    $ad_days = new DateInterval($day_format);
    $ad_time->add($ad_days);
    // カスタムフィールドに保存する
    $ad_end_time = $ad_time->format('Y-m-d H:i:s');
    update_post_meta($pid, 'ad_end', $ad_end_time);
    // 広告終了日時を返す
    return $ad_end_time;
}

フォームからのデータは、$form_dataに入っています。$form_data[ID]と指定すればOKです。このときのIDは、フォーム作成画面でメモしておいたIDです。

Stripe決済されると、広告配信カスタム投稿が作成されます。前回の記事で紹介したショートコードと組み合わせると、広告配信の自動化が完成です。

フックの選定理由

wppayform/wpf_before_submission_data_insertフックを使いました。実はこのフックは決済処理の手前で実行されます。このため、決済申し込みしたが、Stripe決済できなかった場合でも、広告登録処理が行われます。

このプラグインには、決済処理の後にもフックが用意されているので、そちらのフックを使うことも考えました。こちらの場合は、決済処理・画面遷移に時間がかかった場合に自サーバーでタイムアウトになるリスクがあります。

広告配信サービスのため、決済失敗でも広告配信してしまうトラブル < 決済したのに広告配信されないトラブル、と考えて、決済処理の手前で広告配信処理を行うようにしています。

広告申し込みフォームで広告のプレビューを表示する

決済処理とは直接関係しないですが、広告申し込みフォームで広告プレビューできるようにしました。広告画像URLの指定ミスなどを事前に気づける可能性が高くなります。

function ounziw_form_url_check($form)
{
    if (2216 == $form->ID) { // 広告配信のフォームのみ実行する
        ?>
        <p>広告のプレビュー&darr; (画像は 4:3 推奨)</p>
        <!-- htmlはsnow monkeyテーマを想定 -->
        <div class="snow-monkey-posts snow-monkey-recent-posts">
            <ul class="c-entries c-entries--simple" data-has-infeed-ads="false" data-force-sm-1col="false">
                <li class="c-entries__item">

                    <a href="">
                        <section class="c-entry-summary c-entry-summary--post">

                            <div class="c-entry-summary__figure"><img width="400" height="300"
                                                                      src="https://book-recommend.com/wp-content/uploads/2020/04/recommend.png"
                                                                      class="attachment-post-thumbnail size-post-thumbnail wp-post-image jetpack-lazy-image"
                                                                      id="ounziw_image"></div>

                            <div class="c-entry-summary__body">
                                <header class="c-entry-summary__header">

                                    <h2 class="c-entry-summary__title" id="ounziw_headingform1">ブックレコメンド</h2>
                                </header>
                                <div class="c-entry-summary__content" id="ounziw_headingform2">読書家がおすすめ書籍を紹介!</div>

                            </div>
                        </section>
                    </a>
                </li>
            </ul>
        </div>
        <script type="text/javascript">
            var urlform = document.getElementById("wpf_input_<?php echo intval( $form->ID );?>_text");
            urlform.type = 'url';
            var imageform = document.getElementById("wpf_input_<?php echo intval( $form->ID );?>_text_1");
            imageform.type = 'url';
            var headingform1 = document.getElementById("wpf_input_<?php echo intval( $form->ID );?>_text_2");
            var headingform2 = document.getElementById("wpf_input_<?php echo intval( $form->ID );?>_text_3");

            // フォーム内容が変更されたら、画面に反映する
            imageform.onchange = function () {
                var newimg = document.getElementById("wpf_input_<?php echo intval( $form->ID );?>_text_1").value;
                document.getElementById("ounziw_image").src = newimg;
            };
            headingform1.onchange = function () {
                var newtext1 = document.getElementById("wpf_input_<?php echo intval( $form->ID );?>_text_2").value;
                document.getElementById("ounziw_headingform1").innerText = newtext1.substr(0, 100);
            };
            headingform2.onchange = function () {
                var newtext2 = document.getElementById("wpf_input_<?php echo intval( $form->ID );?>_text_3").value;
                document.getElementById("ounziw_headingform2").innerText = newtext2.substr(0, 100);
            };
        </script>
        <?php
    }
}

add_action('wppayform/form_render_after', 'ounziw_form_url_check');

これで、Stripe決済→広告配信、が自動化できました。

実際に活用しているページは↓です。

記事公開日: 2020年08月17日
#

第二版では、大きなセクションとして「get_postsを使ってメイ... 詳細はこちら

#

6月24日6月25日に、京都大学(京都市左京区​)でWordCamp Kyoto... 詳細はこちら