Google Formsの回答をWordPressに連携させる

WordPress REST APIとGASを使って、Google Formsの回答をWordPressに連携させる方法を紹介します。
回答は選択形式にして、WordPress側でデータを集計して出力します。

フォームはこちら。ご自由に回答してください。
集計のデモページはこちら

独自エンドポイントの追加

まず、WordPressに独自のエンドポイントを追加します。
リクエストを受けたら、データを本文に挿入して新規投稿を登録します。
permission_callbackに関数を登録して、publish_postsの権限があるユーザーに限定しましょう。

// エンドポイントを追加
add_action('rest_api_init', function() {
  register_rest_route('myapi/v1', '/formtest', [
      'methods' => 'POST',
      'callback' => 'my_register_google_form_data',
      'permission_callback' => 'my_rest_permission'
  ]);
});

// リクエストを処理
function my_register_google_form_data($request) {
  $data = json_decode($request->get_body(), true);
  
  $args = array(
    'post_type' => 'form-data-demo',
    'post_status' => 'publish',
    'post_title' => 'Googleフォームデータ',
    'post_content' => sanitize_text_field($data['answer'])
  );
  $id = wp_insert_post($args, TRUE);
  return new WP_REST_Response(null, 200);
}

// 権限をチェック
function my_rest_permission() {
  return current_user_can('publish_posts');
}

アプリケーションパスワードの発行

REST APIの認証にはアプリケーションパスワードを使います。
管理画面のプロフィールから発行できるので、【user_login:application-password】の形式でbase64エンコードしたものをメモしておきましょう。

Google側の設定

Google Formsでフォームを作成します。
質問を2つ、どちらもラジオボタンで作成しました。

続いて、GASを記述します。

function onFormSubmit(event) {
  const answerArray = [];
  const items = event.response.getItemResponses();
  for (let i = 0; i < items.length; i++) {
    answerArray.push(items[i].getResponse());
  }
  const answer = answerArray.join(':');  // 回答をコロンで連結

  UrlFetchApp.fetch(
    "https://ishilog.net/wp-json/myapi/v1/formtest",  // 追加した独自エンドポイント
    {
      "method" : "POST",
      "contentType" : "application/json",
      "payload" : JSON.stringify({"answer": answer}),
      "headers" : {
        "Authorization" : "Basic {base64エンコードしたuser_login:application-password}"
      }
    }
  );
}

テンプレート作成

最後に、テンプレートを作成します。まずはアンケートを集計しましょう。

$surveys = array(
  'q1' => array(
    'title' => '今回のセミナーはどうでしたか?',
    'answer' => array(
      'とても良い' => 0,
      '良い' => 0,
      '普通' => 0,
      '悪い' => 0,
    ),
  ),
  'q2' => array(
    'title' => 'また参加したいですか?',
    'answer' => array(
      'はい' => 0,
      'いいえ' => 0,
    ),
  ),
);
// アンケートを集計
$args = array(
  'post_type' => 'form-data-demo',
  'posts_per_page' => -1,
);
$form_data_list = get_posts($args);
foreach ( $form_data_list as $form_data ) {
  $answers = explode(':', $form_data->post_content);
  $count = count($answers);
  for ( $i = 0; $i < $count; $i++ ) {
    if ( isset($surveys['q' . ($i + 1)]) && array_key_exists($answers[$i], $surveys['q' . ($i + 1)]['answer']) ) {
      $surveys['q' . ($i + 1)]['answer'][$answers[$i]]++;
    }
  }
}

あとは結果を出力して、実装完了です。

<?php
  foreach ( $surveys as $survey_num => $survey ) :
?>
<h2><?php echo strtoupper($survey_num); ?>. <?php echo $survey['title']; ?></h2>
<table>
  <thead>
    <tr>
      <th>回答</th>
      <th>回答数</th>
      <th>割合</th>      
    </tr>
  </thead>
  <tbody>
<?php
    $answer_total_num = array_sum($survey['answer']);
    foreach ( $survey['answer'] as $answer_name => $answer_num ) :
?>
    <tr>
      <td><?php echo $answer_name; ?></td>
      <td><?php echo $answer_num; ?></td>
      <td>
<?php
      if ( $answer_total_num ) {
        echo round(( $answer_num / $answer_total_num ) * 100) . '%';
      } else {
        echo '0%';
      }
?>
      </td>
    </tr>
<?php
    endforeach;
?>
    <tr>
      <td><strong>全体</strong></td>
      <td><strong><?php echo $answer_total_num; ?></strong></td>
      <td><strong>
<?php
      if ( $answer_total_num ) {
        echo '100%';
      } else {
        echo '0%';
      }
?>
      </strong></td>
    </tr>
  </tbody>
</table>
<?php
  endforeach;

コメント