Googleフォームを外部からAjaxで非同期通信しようとした話（個人開発）

##環境
- MySQL5.7
- PHP7.3.16
- jQuery 3.5.1
- レンタルサーバー(ComposerやSSHは非対応)

##おことわり
自社サービスと書いていますが個人開発です。
URLはこちら：https://vjct.jp/

##作ろうとした理由
外部サイトで提供されているとあるGoogleフォーム（以下「Googleフォーム」）の利用者が多く、
そのサービスの二次利用を行うことで自社サービスの利用者を増やす目的で実装。

##やりたかったこと
1. 自社サービスのFormにデータを入力してもらい、送信する
2. 自社サービスの送信完了のページで自動的にGoogleフォームにデータを送信
3. Googleフォームに送信完了後に画面遷移させずポップアップで成功可否を通知

##参考にした記事
- https://qiita.com/taichikanaya_1989/items/5d26179013c57e866312
- https://qiita.com/checche/items/3218ea26359214b51d73
- https://qiita.com/samuraibrass/items/d6afda6bd8f3306cee4f

##実装した内容（完成品）
下記のJavaScriptは送信完了ページに実装

```JavaScript:JavaScript
$(function(event) {
        var checkVal = "下記の内容で送信します。よろしいですか？";

        var draftResponse  = '[[[null,426573786,["' + $("#gfsd01").val() + '"],0]';
                           + ',[null,1261006949,["' + $("#gfsd09").val() + '"],0]';
                           + ',[null,450203369,["' + $("#gfsd06").val() + "-" + $("#gfsd07").val() + "-" + $("#gfsd08").val() + '"],0]';
                           + ',[null,1010494053,["' + $("#gfsd02").val() + ":" + $("#gfsd03").val() + '"],0]';
                           + ',[null,203043324,["' + $("#gfsd04").val() + ":" + $("#gfsd05").val() + '"],0]';
                           + ',[null,1540217995,[""],0],[null,701384676,[""],0],[null,2064647146,[""],0],[null,1285455202,[""],0],[null,586354013,[""],0]],null,"-7493555121856808308"]';

        var entryData = 'entry.1285455202=&entry.1540217995=' + $("#gfsd10").val()
                      + '&entry.2064647146=&entry.586354013=' + $("#gfsd99").val()
                      + '&entry.701384676=' + $("#gfsd11").val()
                      + '&draftResponse=' + draftResponse
                      + "&pageHistory=0,1&fbzx=-7493555121856808308";
        var serializeData = encodeURI(entryData);

        if (confirm(checkVal)) {
            $.ajax({
                url: "https://docs.google.com/forms/u/0/d/e/***/formResponse",
                data: serializeData,
                type: "POST",
                dataType: "xml",
                statusCode: {
                    0: function() {
                        alert("送信が完了しました。");
                    },
                    200: function() {
                        alert("送信に失敗しました。");
                    }
                }
            });
            event.preventDefault();
        }
    } else {
        return false;
    }
});
```

#####補足
- ```draftResponse```に入れるデータは1ページ目の内容で、多次元配列になっている。
- 2ページ目のデータ部分は外だしのため空白のままで大丈夫。
- 2ページ目のデータはそのまま```entry.番号=データ```で問題ない。
- ```pageHistory```は複数ページの場合は必須っぽい。
- ```fbzx```の用途は不明だが、```draftResponse```の最後のデータと合わせる。

##躓いたところ①
まず、前述の参考にした記事は「送信ボタンが押されたとき」の実装で、
```event.preventDefault();```の```event```が、```submit```だったり```click```のfunctionから取っており
自動送信の場合はどこから```event```判定を取れば良いのか分からなかった。
###解決内容
最初のfunctionでイベントがキャンセル出来ることが確認できたので、```$(function(event) {});```で問題なさそう。

***
##躓いたところ②
データのシリアライズについて、参考記事は```form.serialize()```や直接```data: {}```などをしており、
実際にどのようなデータを送れば受け取ってくれるか不明瞭だった。
###解決内容
実際の送信内容はGoogle Chromeのデバッグ機能で確認したところパーセントエンコーディングされたURIだったので、
必要なデータを```encodeURI()```でエンコードしてあげれば問題なかった。

***
##躓いたところ③
そのGoogleフォームは2ページに分かれており、参考にした記事はすべて1ページで完結していた。
そのため、記事の内容だけを鵜呑みに実装したところ、2ページ分のデータを送信しているにもかかわらず、
Googleフォーム側で1ページ目のみのデータが受け取られ2ページ目のデータは切り捨てられていた。
###解決内容
二番目の参考記事で

>ちなみに以下の内容はリクエストに含まなくても良い

>fvv: 1
>draftResponse: [null,null,"90993149820\*\*\*\*\*\*\*\*"]
>pageHistory: 0
>fbzx: 90993149820\*\*\*\*\*\*\*\*

と書かれていた内容を鵜吞みにしてしまっていたため解決に時間がかかったが、
実際には```pageHistory=0,1```をデータ内に含めることで2ページ目の内容も受け取ってもらえた。
おそらく```pageHistory=0```の```0```はページ番号で、```pageHistory```が無い場合は```pageHistory=0```と見做されるのではないかと思われます。
```fbzx```については用途不明ですが念のため送っています。

***

##まとめ
実装自体は思ったほど難しくないが、コンソールにエラーが吐き出されるので若干心配になる（データ自体は送れている）。
先人の知恵はたくさんあるが、鵜呑みにはしすぎないよう気を付けた方がいいと実感した。