

### 実現したいこと

HTMLで作成されているフォームから受け取ったPOSTデータをPHPファイルに送り、そのPHPファイルでユーザーにPOST内容の確認メールを送信した後、データをGASに送りgoogleスプレットシートにも出力される仕組みを作りたい。

### 前提

表題の通りです。ただし会社のサーバーの関係上、composerを使用したりgoogle cloud platformを使用することができません。  
HTMLフォーム → ユーザーへメールを送る機能を実装したPHPファイル → googleスプレットにPOSTデータの内容を出力（GAS言語）  
の流れでデータを送りたい所存です。

ユーザーへPOSTデータを使用した確認メールを送る機能はすでにPHPファイルに実装されています。

### 発生している問題・エラーメッセージ

コードは一通り実装したが、googleスプレットシートに出力がこない。

### 該当のソースコード

HTMLフォーム

[code]

    <form action="./mail.php" method="post" enctype="multipart/form-data" id="myform">
                    <div class="l-main-form__bg">
                        <table class="p-main-form--survey">
                            <tbody class="p-main-form__tbody">
                                <tr class="p-main-form__tr--survey">
                                    <th class="p-main-form__th--survey"><span class="--blue">必須</span>お名前</th>
                                    <td class="p-main-form__td--survey">
                                        <input type="text" name="お名前" class="--input" placeholder="例：鈴木太郎" autocomplete="name">
                                    </td>
                                </tr>
                                <tr class="p-main-form__tr--survey">
                                    <th class="p-main-form__th--survey --sp-block"><span class="--blue">必須</span>生年月日</th>
                                    <td class="p-main-form__td--survey">
                                        <input type="text" name="生年月日" class="--input js-retype" placeholder="例：19921201 ※1992/12/1生まれの場合" autocomplete="tel">
                                        <p id="previous_input2" class="c-previous_alert js-retype-alert"></p>
                                    </td>
                                </tr>
                               　〜〜〜〜〜〜〜〜　一部省略　〜〜〜〜〜〜〜〜
                                <!-- 選択エリア１ -->
                               
                                <!-- 選択エリア2 -->
                                <tr class="p-main-form__tr--survey">
                                    <th class="p-main-form__th--survey --adjust"><span class="--blue">必須</span>下記項目の中で特に興味があるものを2つお選びください。</th>
                                    <td class="p-main-form__td--survey">
                                        <input type="checkbox" name="Q2" id="c-select-about1" class="c-previous-radio js-count2-checkbox" onclick="limitCheckboxSelection(this)" value="ホワイトニング材・照射器の漂白効果の実証体験">
                                        <label for="c-select-about1">ホワイトニング材・照射器の漂白効果の実証体験</label><br><br>
                                        <input type="checkbox" name="Q2" id="c-select-about2" class="c-previous-radio js-count2-checkbox" onclick="limitCheckboxSelection(this)" value="ホワイトニングで予防歯科強化">
                                        <label for="c-select-about2">ホワイトニングで予防歯科強化</label><br><br>
                                        <input type="checkbox" name="Q2" id="c-select-about3" class="c-previous-radio js-count2-checkbox" onclick="limitCheckboxSelection(this)" value="ホワイトニングで自費増収">
                                        <label for="c-select-about3">ホワイトニングで自費増収</label><br><br>
                                        <input type="checkbox" name="Q2" id="c-select-about4" class="c-previous-radio js-count2-checkbox" onclick="limitCheckboxSelection(this)" value="オフィスとホームホワイトニングの使い分け知識">
                                        <label for="c-select-about4">オフィスとホームホワイトニングの使い分け知識</label><br><br>
                                        <input type="checkbox" name="Q2" id="c-select-about5" class="c-previous-radio js-count2-checkbox" onclick="limitCheckboxSelection(this)" value="難症例の術式選択や処置方法、知覚過敏を抑制する診断のコツ">
                                        <label for="c-select-about5">難症例の術式選択や処置方法、知覚過敏を抑制する診断のコツ</label>
                                    </td>
                                </tr>
                                <!-- //選択エリア2 -->
    　                         〜〜〜〜〜〜〜〜　一部省略　〜〜〜〜〜〜〜〜
                                <!-- 入力エリア-->
                                <tr class="p-main-form__tr--survey">
                                    <th class="p-main-form__th--survey --adjust">
                                        <span class="--blue">必須</span>
                                        <p class="c-form-survey--text">
                                            セミナーの参加目的をできる限り詳細に教えてください。<br class="u-db">
                                            （当日の講義内容の参考にさせていただきます。）<span class="--white --adjust">50文字以上</span>
                                        </p>
                                    </th>
                                    <td class="p-main-form__td--survey">
                                        <textarea name="input_area" rows="4" cols="50" class="c-form-survey--textarea js-textarea" placeholder="〇〇〇〇〇〇〇〇〇●〇〇〇〇〇〇〇〇〇●〇〇〇〇〇〇〇〇〇●〇〇〇〇〇〇〇〇〇●〇〇〇〇〇〇〇〇〇●"></textarea>
                                        <p id="previous_input_textarea" class="c-previous_alert js-retype-alert"></p>
                                    </td>
                                </tr>
                                <!-- //入力エリア-->
                            </tbody>
                        </table>
                    </div>
                    <div class="privacy-box__parent--wrap">
                        <div class="privacy-box__parent">
                            <p class="c-previous-text">回答のコピーが指定したアドレスにメールで送信されます。</p>
                        </div>
                        <p id="previous_alert" class="c-previous_alert"></p>
                        <div class="submit_box-wrap">
                            <input type="submit" value="送信する" class="c-previous-submit" onclick="checkForm(event)">
                        </div>
                    </div>
                </form>
    
[/code]

mail.php

[code]

    <?php
    メールを送る関数（）
    setSheet();
    function setSheet(){
      // GASのURLにPOSTデータを送信
      $postData = array('input_data' => json_encode($_POST));
      $content = http_build_query($postData, '', '&');
      
      $options = array(
        'http' => array(
          'header' => 'Content-type: application/x-www-form-urlencoded',
          'method' => 'POST',
          'content' => $content
        )
      );
    
      $context = stream_context_create($options);
      $result = file_get_contents("GASをデプロイした後に発行されるURLを指定", false, $context);
    }
    ?>
    
[/code]

GAS

[code]

    function doPost(e) {
        var inputJSON = e.parameter.input_data;
        var inputData = JSON.parse(inputJSON);
    
        // データの利用例
        var tmp1 = inputData['お名前'];
        var tmp2 = inputData['生年月日'];
        var tmp3 = inputData['電話番号'];
        var tmp4 = inputData['Email'];
        var tmp5 = inputData['勤務区分'];
        var tmp6 = inputData['1回目セミナー'];
        var tmp7 = inputData['Q1'];
        var tmp8 = inputData['Q2'];
        var tmp9 = inputData['Q3'];
        var tmp10 = inputData['Q4'];
        var tmp11 = inputData['Q5'];
        var tmp12 = inputData['input_area'];
    
        // スプレッドシートへのデータ出力処理
        var spreadsheet = SpreadsheetApp.openByUrl("スプレットーシートのURLを指定");
        var sheet = spreadsheet.getSheetByName("該当シートの名前");
        var row = sheet.getLastRow() + 1;
        sheet.appendRow([
            tmp1,
            tmp2,
            tmp3,
            tmp4,
            tmp5,
            tmp6,
            tmp7,
            tmp8,
            tmp9,
            tmp10,
            tmp11,
            tmp12
        ]);
    }
    
[/code]

### 試したこと

PHPまでの処理まうまくいっており、ユーザーへ確認メールも届いています。  
しかしスプレットシート側に出力がきません。  
お恥ずかしながらGASのデバック方法がよくわからずdoPost()をテストする方法を  
<https://prtn-life.com/blog/gas-log-gcp>  
を参考にしながらやろうとしたのですが、テスト関数にどのような内容を入れて良いかわからず手が止まってしましました。

### 補足情報（FW/ツールのバージョンなど）

GASのデプロイは「ウェブアプリ」として実行。

GASへの理想の出力としてはフォームで入力された各10種類のname属性の値がスプレットシートの１フィールドに1個ずつ入ることです。そして、type="checkbox"などのフォームで複数選択されていた場合はその全ての値が1フィールドの中に出力される状態が最終目標です。

おそらくですが現在のコードではPHP側からGASへPOSTデータが渡っていない気がします。GAS側で  
MailApp.sendEmail("sample@gmail.com", "GASテスト","GASでメールします。");  
の 一行を追加し、HTMLでフォームを送信したところPHPのメールは送られてきたのですが、GAS側からはメールが来なかったためです。

冗長になってしまいわかりにくい所あるかと思われますがどうかアドバイスいただけますと幸いです。


CC BY-SA 4.0
2023-07-03T02:31:59.823
95448
2023-07-04T08:09:29.247
2023-07-03T03:38:28.740
3060
58950
question
php html google-apps-script
HTMLフォームのPOSTデータをPHP→GASの順番で利用したい。


自己解決いたしました。

PHP側で正しくPOSTの値をエンコードし、GAS側でJSON.parse(e.postData.getDataAsString());で正しくパースすることで反映しました。  
JSONエンコードに関する問題でした。

PHPのコード

[code]

    function setSheet() {
        
      // POSTデータをそのまま使用する
      $postData = $_POST;
    
      // POSTデータをJSONエンコード
      $postData = json_encode($postData, JSON_UNESCAPED_UNICODE);
    
      $options = array(
        'http' => array(
          'header' => 'Content-type: application/json', // Content-typeをapplication/jsonに変更
          'method' => 'POST',
          'content' => $postData
        )
      );
      
        $context = stream_context_create($options);
      
        ile_get_contents("GASのデプロイURLを指定", false, $context);
    }
    
[/code]

GASのコード

[code]

    function doPost(e) {
      var postData = JSON.parse(e.postData.getDataAsString());
      
      // スプレッドシートのIDとシート名を設定してください
      var spreadsheetId = "スプレットシートID";
      var sheetName = "シートの名前";
      
      // スプレッドシートのオブジェクトを取得
      var sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
      
      // データの書き込み先の行を取得
      var lastRow = sheet.getLastRow() + 1;
      
      // POSTデータをスプレッドシートに出力する
      var rowData = [];
      for (var key in postData) {
        var values = postData[key];
        if (Array.isArray(values)) {
          // 配列の場合は値をカンマ区切りの文字列に変換
          values = values.join(", ");
        }
        rowData.push(values);
      }
      
      sheet.getRange(lastRow, 1, 1, rowData.length).setValues([rowData]);
    
[/code]


CC BY-SA 4.0
2023-07-04T06:34:05.767
95458
2023-07-04T08:09:29.247
2023-07-04T08:09:29.247
3060
58950
95448
answer