Googleフォームに回答してくれた人のメーリングリスト的なものを作る

# はじめに
 イベントごとにGoogleフォームで参加者を募集し、回答してくれた人にだけ追加のメールを送りたい（＝イベントごとにメーリングリスト的なものが作りたい）ときに使える仕組みを作りました。

# 参考ページ
 連絡先取得～連絡先登録・更新部分はほどんど「officeの社」さんのソースを使用させていただいています。  
 
 https://note.com/officeforest/n/na556700879bb
 
 https://officeforest.org/wp/2023/02/03/google-apps-script%e3%81%a7contact%e3%82%92people-api%e3%81%a7%e5%bc%84%e3%82%8b/#appsscriptjson

# 使用するサービス
1. Googleフォーム
1. GooGle Apps Script(GAS)
1. Google連絡先
1. Gmail

# 手順
1. イベント募集用のGoogleフォームを作成する
1. GoogleフォームにGAS・トリガーを設定する
1. Gmailの宛先にラベルを指定

# 前提
- Googleアカウントが作成済みであること
- PCで作業すること

# 1.イベント募集用のGoogleフォームを作成する
1. Googleフォームにアクセス（https://www.google.com/intl/ja_jp/forms/about/）
  「ログイン」ボタンをクリックし、画面の案内に従ってログインしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/255913b9-bf24-36c8-5f35-b707a5646243.png)


1. Googleフォームのトップページで「空白のフォーム」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/dacf22cf-a982-72dc-fea7-ae772860697a.png)


1. 回答を自動返信するように設定（任意） 
  「設定」タブをクリック
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/20827d68-1a73-ffd7-98b7-ea17ffc82afa.png)
  「回答」項目の横のボタンをクリックし内容を展開 
  メールアドレスを収集する：確認済み
  回答のコピーを回答者に送信：常に表示
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/9317b10e-0395-9529-2a36-a9d92274153b.png)


1. フォームのタイトル、質問項目を作設定
  タイトル：後ほど使用する連絡先のグループ名になります。
  メールアドレス、氏名を記述式・必須入力で設定します。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/edc5a683-ed36-eea7-a4a0-92d3726429b0.png)
  他の質問項目は今回の処理には特に関係ないので自由に設定してください。

# 2.GoogleフォームにGAS・トリガーを設定する
1. 画面右上の三点マークをクリックし、「スクリプト エディタ」をクリック
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/e8e25f6a-13f1-4b86-301e-99dae28cd459.png)

1. プロジェクトの設定
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/702d36d4-18e5-6aa2-a885-71401fe7771d.png)

1. 「appsscript.json」マニフェスト ファイルをエディタで表示する　のチェックボックスをONにする
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/32ea9da1-71a4-ba04-b582-51620123d2e7.png)

1. コードをクリック
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/0dd0e0e3-74f7-6eb6-ef4f-f1e3766bdab7.png)

1. 「appsscript.json」をクリックし、以下をコピペ
    ```
      {
          "timeZone": "Asia/Tokyo",
          "dependencies": {
              "enabledAdvancedServices": [
                  {
                  "userSymbol": "People",
                  "version": "v1",
                  "serviceId": "peopleapi"
                  }
              ]
          },
          "exceptionLogging": "STACKDRIVER",
          "runtimeVersion": "V8",
          "oauthScopes": [
              "https://www.googleapis.com/auth/contacts",
              "https://www.googleapis.com/auth/forms",
              "https://www.googleapis.com/auth/userinfo.profile"
          ]
      }
    ```

 1. コード.gsに以下をコピペ
      ```
    function onFormSubmit(e) {
      try{
      // フォームの回答からメールアドレスを取得
        var itemResponses = e.response.getItemResponses();
        var userEmail = itemResponses[0].getResponse();  //1つ目の質問の回答
        var userName = itemResponses[1].getResponse();  // 2つ目の質問の回答
        var labelFromTitle = e.source.getTitle();  // フォームのタイトルを取得

        //現在の連絡先一覧を一括取得
        let array = personskun();

        //追加フラグを用意
        let addflg = true;

        //array(連絡先一覧)でループし、フォームに登録されたメアドが既に連絡先にあれば更新、なければ新規追加
        for(let j = 0; j<array.length; j++){
          //レコードを一個取り出す
          let recs = array[j];

          //メールアドレスを取得
          let tempmail = recs[0];

          //フォームに登録されたメアドが既に連絡先にあれば更新
          if(tempmail == userEmail){
            console.log("連絡先更新")
            //etagを取得
            let person = recs[1];
            // ラベルアップデート
            modifyContact(person, labelFromTitle)
            //追加フラグを変更
              addflg = false;
            }
          }
          //フォームに登録されたメアドと連絡先に一致するものがなければ新規追加
          if(addflg == true){
            //ラベル指定で連絡先を新規追加
            console.log("連絡先新規追加")
            var contactResourceName = createContact(userName, userEmail);
            modifyContact(contactResourceName, labelFromTitle)
          }
      }catch(e){
        console.log(e.message);
      }
    }


    //連絡先を作成する
    function createContact(username, mail) {
      //usernameを半角スペースで分解する
      let userman = username.split(" ");
      if (userman.length < 2){
        userman.push("")
      }
 
      //作成するリソースの中身
      var contactResource = {
        "names": [{
          "displayNameLastFirst": username,
          "givenName": userman[1],
          "familyName": userman[0],
        }],
        "emailAddresses": [{
          'value': mail
        }]
      }
      var contactResourceName = People.People.createContact(contactResource)["resourceName"];
      console.log("連絡先を新規作成しました。")
     
      return contactResourceName; 
    }


    // 連絡先を更新 コンタクトグループ（ラベル）を作成、設定
    function modifyContact(person, label) { 
      console.log("コンタクトグループ（ラベル）を作成、設定します。")
      var groupName = label;
      var groups = People.ContactGroups.list()["contactGroups"];
      var target_group = groups.find(group => group["name"] === groupName);
      //グループ名が無い場合には作成する
      if (!target_group ) {
        var groupResource = {
          contactGroup: {
            name: groupName
          }
        }
        group = People.ContactGroups.create(groupResource);
      }else{
        group = target_group
      }
      var groupResourceName = group["resourceName"];
    
      if (person != ""){
          const { etag, memberships } = People.People.get(person, { personFields: "memberships" });
          return People.People.updateContact({
            "resourceName": person,
            "etag": etag,
            "memberships": [
              ...memberships, // Here, the existing labels are included.
              { "contactGroupMembership": { "contactGroupResourceName": groupResourceName } }
            ]
          },
            person,
            { updatePersonFields: "memberships" });
      }
    }
    

    //連絡帳の一覧を取得する
    function personskun(){
      //pageTokenの変数
      let pageToken = null
     
      //一覧用の配列
      let array = [];
     
      do{
        //一覧を取得
        let people = People.People.Connections.list('people/me', {
            personFields: 'emailAddresses',
            pageSize: 500,
            pageToken: pageToken
        });
     
        //リストを取得する
        let target = people.connections;
 
        //連絡先が0件の場合
        if(target == undefined){
          return array;
        }
     
        //ターゲットデータを処理する
        for(var i = 0;i<target.length;i++){
          //レコードを取り出す
          let rec = target[i];
     
          //一時配列を用意
          let temparr = [];
     
          //emailAddressesが無い場合はスルーする
          let mailaddress = ""
          try{
            mailaddress = rec.emailAddresses[0].value
          }catch(e){
            mailaddress = ""
          }
     
          //一覧から必要な項目を取得する
          temparr.push(mailaddress);
          temparr.push(rec.resourceName);
          temparr.push(rec.etag);
     
 
          //一覧用配列に追加
          array.push(temparr);
        }
 
        //nextPageTokenを取得する
        pageToken = people.nextPageToken
 
      }while(pageToken !== undefined);
 
      //一覧データを返す
      return array
    }
    ```

 1. トリガーを設定
  ナビゲーションで「トリガー」をクリックし、右下の「トリガーを追加」をクリック
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/02f4d738-897f-51d0-2f51-61c9b95c042e.png)
  基本デフォルトで、以下を設定して保存
  イベントの種類を選択：フォーム送信時
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/975a826e-0b7a-9962-ab15-b582a5c2b6f7.png)
  サブウィンドウが表示されるので、自分のGoogleアカウントをクリック
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/9190382c-52a4-336f-0f73-737398abd16a.png)
  警告画面が表示されるので、左下の「Advanced」をクリック  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/70915393-daab-99b3-61a7-53436caa8006.png)
  さらに表示される「Go to 無題のプロジェクト（unsafe）」をクリック
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/7189f89d-cee8-6424-7368-1bbe18a1ab7f.png)
  「Continue」をクリック
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/b26290c6-5187-54d2-c78c-a84164ebc1f9.png)
    「Allow」をクリック
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/288c0d58-87ea-2c36-dd0c-7a91eac47c6e.png)
    トリガーが追加されます。
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/2ed9aef8-bfde-3451-a006-3ac70bf6376e.png)

1. Googleフォームに回答
  アンケート画面に戻り、画面右上の「送信」をクリック
  URLを共有したい場合はリンクをコピー
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/495a4a65-2517-0193-307b-5213468180f5.png)

# 3.Gmailの宛先にラベルを指定
  Gmailでメール新規作成
  宛先（CC・BCC）にラベル名を入力するとサジェストしてくれる
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/0adad7cd-69ee-40a9-22d6-78c3e1efc2b5.png)
  ラベル名をクリックすると、宛先にメンバーが追加されます！

# おまけ  
 ラベルはGoogle連絡先に保存されます。（ここからメール作成することも可能です。）  
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324338/bb89f9bb-1462-f888-7a75-0018b6f6ed0e.png)


# おわりに
  スマホのGmailからラベルが直接選択できれば便利なのですが、どうやら2024年1月現在そのような使いかたはできないみたいです。  
 
  Google Formでは回答がスプレッドシートに自動的に保存されていくため、それをコピペして宛先に貼り付ければいいだけですが、勉強がてら作成しました。