mizusame

【Blogger】リアクションボタンを Google フォームで作る方法

更新日: 公開日:

ブログを運営していると、読者の方からの反応が欲しいと思うことがあります。しかし、読者にとってコメントを残すという行為は意外とハードルが高いものです(筆者もコメント書くのめちゃくちゃ苦手です)。コメントよりも気軽に記事に反応できる仕組みがあるといいですよね。

かつて Blogger には公式のリアクションウィジェットが存在しましたが、残念ながら廃止されてしまいました。代わりに類似の外部サービスを導入するにしても、その多くは会員登録を伴ったり、無料版だと制限があったりします。

しかし、Google フォームを改造すれば、前述のようなしがらみもなくリアクションボタンを作成できます。その方法を以下に記します。

アイキャッチ

Google フォームを作成

以下のページの「フォームに移動」をクリックし、Google フォームを新規作成します。

フォームのタイトルは「リアクションボタン」など、各々でわかりやすいものにしておけば大丈夫です🙆‍♀

次に、フォームに以下の 4 つの項目を用意します。全ての項目の「必須」のトグルスイッチをオンにしておきます。

  • 記事 ID(記述式テキスト)
  • 記事タイトル(記述式テキスト)
  • 記事 URL(記述式テキスト)
  • リアクション(ラジオボタン)
項目を4つ設定したあとのGoogleフォームのプレビュー画面

どの記事にリアクションをもらったかわかるように、記事 ID、タイトル、URL 用の項目をそれぞれ用意しています。記事のタイトルや URL を変更しても、記事 ID が同じならば同一の記事とみなせます。

リアクションはラジオボタンを用いて選択式にします。今回は「いいね!」「面白い」「ためになる」という項目を用意しました。のちに Blogger に設置するコードで用いるので、これらの文言はメモ帳等に控えておいてください。

最後に、フォームの設定画面で「回答」の「メールアドレスを収集する」を「収集しない」、「表示設定」の「制限事項」の「すべての回答者に対して自動保存を無効にする」のトグルスイッチをオンにしておけば、Google フォームの作成は完了です。

HTML でリアクション送信フォームを作成

リアクションを Google フォームに送信するためのフォームを HTML で作成していきます。

まず、以下の記事の「Google フォームのソースから、フォームと各質問の値を拾ってコピー」の項を参考にして、先程作成した Google フォームからフォーム自体の値と前項で設定した 4 つの項目の値を抜き出しておきます。

値が取得できたら、Blogger のテーマ編集に移動し、ブログの投稿ウィジェット内の記事本文 <data:post.body/> の下辺りに以下のコードを貼り付けます。

<b:if cond='data:view.isPost'>
  <div class='reaction'>

    <!-- フォームの送信先 URL -->
    <form action='https://docs.google.com/forms/u/0/d/e/●●●●/formResponse' class='reaction-form' method='POST' target='send_reaction'>

      <!-- 記事 ID, タイトル, URL -->
      <input expr:value='data:post.id' name='entry.●●●●' type='hidden'/>
      <input expr:value='data:post.title.escaped' name='entry.●●●●' type='hidden'/>
      <input expr:value='data:post.url.canonical' name='entry.●●●●' type='hidden'/>

      <!-- リアクション選択 -->
      <fieldset class='reaction-fieldset'>
        <legend>リアクションを送る</legend>
        <b:loop values='["いいね!", "面白い", "ためになる"]' var='reaction'>
          <label><input expr:value='data:reaction' name='entry.●●●●' required='required' type='radio'/><span><data:reaction/></span></label>
        </b:loop>
      </fieldset>

      <!-- 送信ボタン -->
      <button class='reaction-button' type='submit'>送信</button>

      <!-- 送信完了後の処理用 iframe -->
      <iframe class='reaction-iframe' name='send_reaction' style='display:none'/>

    </form>
  </div>
</b:if>

上のコードの ●●●● の部分を、先程取得したフォームの値と各質問項目の値に書き換えてください。また、b:loopvalues 内に前項で控えておいたラジオボタンの項目の文言を記し(詳しくは後述)、テーマを保存してください。

以下、コードの簡単な解説です。

下に示すコードでは、Blogger 独自タグの記事 ID data:post.id、記事タイトル data:post.title.escaped と記事 URL data:post.url.canonical をそれぞれ inputvalue 属性に埋め込んでいます。

<input expr:value='data:post.id' name='entry.●●●●' type='hidden'/>
<input expr:value='data:post.title.escaped' name='entry.●●●●' type='hidden'/>
<input expr:value='data:post.url.canonical' name='entry.●●●●' type='hidden'/>

文字列型のデータに .escaped を付けると文字列がエスケープされ、思わぬ誤作動を防げます。また、URL 型のデータに .canonical を付けることで URL の正規化を行い、これにより ?m=1 などのパラメータが付与されるのを防ぎます。

さらに、inputtype='hidden' を付けることでユーザーから見えない隠しデータとして扱うことができます。

このように記事の情報を Google フォームに送信することで、どの記事にリアクションをもらったのかを回答ページで確認できます。

次に解説しておきたいのが、リアクション回答用のラジオボタンに関する以下のコードです。

<b:loop values='["いいね!", "面白い", "ためになる"]' var='reaction'>
  <label><input expr:value='data:reaction' name='entry.●●●●' required='required' type='radio'/><span><data:reaction/></span></label>
</b:loop>

Blogger で繰り返し処理を行う独自タグ b:loopvalues 属性には、data:*** のようなデータタグだけでなく、任意の配列も設定できます。

そこで、ラジオボタンの各項目を以下のように半角二重引用符 " 内に記し、半角コンマ ,(最後の項目のあとは不要)で繋げたあと、外側を半角大括弧 [ ]で囲むことで b:loopvalues に埋め込む用の配列が完成します。

["いいね!", "面白い", "ためになる"]

配列内の値は、独自タグ <data:reaction/> で出力できます。

上の例では項目が 3 つしかないためこの方法を使う必要性は薄いですが、もう少し項目が増えてくると b:loop の中身を書き換えればリアクション全項目の HTML が一括で変更できるのでとても楽です。

また、inputrequired='required' を設定しておくことで、ラジオボタンの項目をどれか 1 つ選択しないと送信できないようにしています。

CSS の例は以下の通りです(要改変)。テーマ編集の </head> の上辺りへの追加を推奨します。

<b:if cond='data:view.isPost'>
<style>
/* リアクションボタン */
.reaction{
  margin: 3em 0;
  line-height: 1;
  font: #333;
}
.reaction-fieldset{
  display: flex;
  justify-content: center;
}
.reaction-fieldset legend{
  font-size: 1.8rem;
  line-height: 1.6;
  margin: 2.5em 0 1em;
  font-weight: bold;
  text-align: center;
}
.reaction-fieldset label{
  margin: 0 .25em;
}
.reaction-fieldset span{
  padding: .75em .5em;
}
.reaction-fieldset input:checked + span{
  font-weight: bold;
  color: #333;
}
.reaction-button{
  display: block;
  margin: 2em auto 0;
  background: #333;
  color: #fff;
  padding: .75em 1.5em;
  border-radius: 2em;
}
.reaction-button:focus{
  outline: solid 2px #333;
  background: #fff;
  color: #333;
}
</style>
</b:if>

JavaScript でお礼メッセージを表示

リアクションボタンを押したのになにも反応がないとなんだか物悲しいので、JavaScript でお礼メッセージを表示させようと思います。

以下のコードをテーマ編集の </body> の上辺りに追加します。

<b:if cond='data:view.isPost'>
<script>//<![CDATA[
window.addEventListener('DOMContentLoaded', () => {

  // フォーム内の要素を取得
  const form = document.querySelector('.reaction-form');
  const iframe = form.querySelector('.reaction-iframe');
  const fieldset = form.querySelector('.reaction-fieldset');
  const button = form.querySelector('.reaction-button');

  // フラグの初期化
  let submitted = false;

  // 送信が完了したらフラグを立てる
  form.addEventListener('submit', () => {
    submitted = true;
  })

  // iframe 読み込み完了後に実行
  iframe.addEventListener('load', () => {

    // 送信完了後の処理
    if(submitted){

      // ラジオボタンを無効化
      fieldset.disabled = true;

      // 送信ボタンを無効化、非表示
      button.disabled = true;
      button.style.display = 'none';

      // 送信完了メッセージを表示
      alert('リアクションありがとうございました!!')

    }
  })
})
//]]></script>
</b:if>

フォームへの送信が完了したらフラグを立て、隠し要素の iframe の読み込みが完了したら、ラジオボタンの無効化、送信ボタンの無効化と非表示を行い、最後にお礼メッセージを表示させます。

fieldset でフォームの一部(今回はラジオボタン)を囲んでいる場合、fieldsetdisabled を設定するだけで自身とその中身を一気に無効化できます。

加えて送信ボタンを無効化することで、リアクションを連続で送信できないようにしています。お察しの通りページをリロードしたら何度でもボタンが押せますがそこはご愛嬌ということで……。

ここまでできたらテスト送信をして、Google フォームの回答ページで記事 ID、タイトル、URL、選択したリアクションが反映されていることを確認します。

リアクション送信後のGoogleフォームの回答ページ

(自分が書いた記事に自分で「面白い」ってリアクションするの、テスト送信だとしてもちょっと恥ずかしいですね……)

テスト送信をした記事や時刻、リアクションの種類を覚えておかないと、テスト送信したものと読者の方が送ってくれたものとの区別が付かなくなるので気を付けてください。

無事に動作確認ができたら、これでリアクションボタンの完成です!!

GAS でリアクション通知メールを受け取る

Google フォーム純正のメール通知機能では回答が送信されたという事実しかわからず、肝心の回答の内容は教えてくれません。

そのたびに Google フォームを確認するのはちょっと面倒なので、どの記事にどんなリアクションをもらえたかをメールで受け取れるようにしたいと思います。Google App Script(GAS)を使う方法について説明します。

GAS の導入方法は以下の記事を参考にして行ってください。スクリプトの内容が違うこと以外は同じ流れで進めていただければオッケーです。

Google フォームからスクリプトエディタを開いたら、以下のコードを記述します。

function submitForm(e){
  const itemResponses = e.response.getItemResponses();
  let title, url, reaction;
  for(const itemResponse of itemResponses){
    const question = itemResponse.getItem().getTitle();
    const answer = itemResponse.getResponse();
    switch(question){
      case '記事タイトル':
        title = answer;
        break;
      case '記事 URL':
        url = answer;
        break;
      case 'リアクション':
        reaction = answer;
        break;
    }
  }
  const recipient = 'mail@example.com';
  const subject = '記事にリアクションをもらいました';
  const body = `以下の記事にリアクション「${reaction}」をもらいました。\n\n${title}\n${url}\n\nGoogleフォームで確認する\n${e.source.getEditUrl()}`;
  GmailApp.sendEmail(recipient, subject, body);
}

mail@example.com の部分はご自身のメールアドレスに変更して保存してください。

プロジェクトのタイトルは「リアクションボタン」など、各々でわかりやすいものにしておけば大丈夫です🙆‍♀

トリガーまで設定し終えたら再びテスト送信をして、指定したメールアドレス宛にメールが届いているか、以下の画像のように記事タイトル、記事 URL、リアクション、Googleフォームの編集 URL がメールの本文に反映されているかを確認してください。

リアクション送信後のメール通知

無事動作確認ができたら設定完了です!!

あとがき

Google フォームを利用してリアクションボタンを作成する方法をご紹介しました。たまたま別件で Google フォームのラジオボタンをいじっていたときにひらめいたカスタマイズだったのですが、四苦八苦しながらも形にできてよかったです。

Blogger 標準のリアクションウィジェットがなくなって困っていた方や、記事へのリアクションが欲しい方の参考になれば幸いです。ここまで読んでいただきありがとうございました!

    編集
    ホーム