動機
- アプリにアンケート機能をつけたかった
- なるべくお金のかからない形で実装したかった
- アプリ内で完結させたかった(ブラウザに飛ばさない
↑がやりたくて、アプリ内からGoogleフォームに回答を送れるかを検証。
ブラウザに飛ばす形でもいいかなと思ったんですが、アンケート送信完了のタイミングでお礼の処理を走らせたかったので、アプリ内で完結させることに
GoogleFormのPostについて
サンプルのフォームを用意しました
適当に送信
ChromeのDeveloperツールで、回答を送信したときのhttp通信のヘッダーを確認
右クリック→検証→Network→Headers→FormData
入力した内容を見つけた
フィールドの名前がentry.~~~~~~で値が回答の内容
選択形式の質問は選択肢のIDをポストしてるかと思ったんですが、文字列をそのまま送ってるんですね。
Post先で指定すべきURLはHeadersの上の方に載ってるみたい
General Request URL: https://docs.google.com/forms/d/e/(作成したフォームのID)/formResponse
ContentTypeも載ってる
RequestHeaders content-type: application/x-www-form-urlencoded
この通信をアプリからPostで送れば良さそう
UnityからformData付きの通信を送る
UnityWebRequestでformData付きのポストが送れます。
formDataを付与する際に使える型は - WWWForm - string - Dictionnary<string,string> といくつかあります
今回はWWWFormを使います
var formData = new WWWForm(); // Chrome上で確認したentry.~~~のIDをそれぞれ入れる。 formData.AddField("entry.1818833279","とても元気ですよ"); formData.AddField("entry.818922897","オプション1"); using (UnityWebRequest request = UnityWebRequest.Post(url, formData)) { // ContentTypeも設定 request.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"); yield return request.SendWebRequest(); if (request.isNetworkError || request.isHttpError) { Debug.Log(request.error); } else { Debug.Log("[api]success"); } }
こんなコードになります。
実行してみると...
無事に回答が送れました\(^o^)/
注意点
注意したほうがよさそうな挙動もあったのでメモ
1項目でもバリデーションに引っかかると送信に失敗する
回答する項目にバリデーションを付けられます。
数値のみ、文字列、長さチェック、正規表現などなど
本来のフォームから送るときだけでなく、別クライアントから送るときもフィールドのバリデーションは通る必要があるみたいです。
全ての質問のうち一つでも正しくない項目があると通信にBadRequestが返って来て失敗するみたいです。
選択形式(ラジオボタン)の質問の回答は、完全に一致しないとだめ
例えばこんな質問があったとします
この回答をPostで送るときの値は、選択肢のどれかの文字列と完全に一致しないとだめみたいです。
この質問でいうと、「オプション 1」じゃなくて「オプション1」(オプションと1の間の半角スペースが無い)とかで送っても、認識してくれないです。
大体こんな感じでしょうか。
とりあえず作りたかったアンケート機能は作れそう。
フォームのURLを叩くだけで質問一覧を取得できて、送信もスムーズにできる機能を作ろうとしてるので、できたら公開したいです。