GoogleフォームのデータをSlackに転送する

# 目的

とある団体のSNSを運用するにあたり、いままではSNS担当の人に個人で連絡を取っていたが、面倒くさいのでフォームを作ってそこに回答してもらうことにした。

- フォームはGoogleフォームで作りたい(楽)
- フォームに回答されたかリアルタイムでわかると嬉しい
- 回答の内容も分かるとなお嬉しい
- Slackを使っているのでSlackの専用チャンネルに通知が行くようにしよう！

# 検討

Googleフォームに回答があったときにスプリクトのトリガーを起動させたいので、GAS一択。
フォームの回答内容を取得するのは簡単。
あとはSlackにメッセージをPOSTできればOKで、余裕があれば見やすさ使いやすさも重視したい。

## フォームの内容

とりあえず以下の項目をフォームで回答してもらう。

- 名前
- SNSの種類：複数のSNSを運用しているので、どのSNSで投稿するか。
- 投稿内容：投稿する内容。
- [任意]画像：投稿する画像。複数枚選択できるようにした。
- [任意]投稿日時：投稿を希望する日時。

※ファイルのアップロードの機能を使用しているので、フォームの回答にはGoogleへのログインが必須となる。

## Slackでの表示

Slackで回答内容を表示するときに、以下の要件を満たしたい。

- Slackを長押しして出てくる「テキストをコピー」で投稿内容だけをコピーする。
- どの種類のSNSか分かりやすいようにする。
- 画像の入ったフォルダ(Googleドライブ)へとぶリンクを貼る。

# 実装

SlackのAPIを使用しているが、APIの使い方については省略する。

## GAS

SlackのToken(後述)は、GASの「ファイル＞プロジェクトのプロパティ＞スクリプトのプロパティ」に、プロパティを`SLACK_TOKEN`として設定している。

``` autosend.js
function autosend() {
 //後の処理で使うため、変数を設定。（フォームと名称を一致させる必要あり）  
   const item_timestamp = 'タイムスタンプ';
   const item_kind = 'SNSの種類';
   const item_text = '投稿内容';
   const item_time = '[任意]投稿日時';
   const item_pic = '[任意]画像(最大10枚まで)';
   
 //Slackに投稿する内容
   const slackToken = PropertiesService.getScriptProperties().getProperty('SLACK_TOKEN');
   const channel = encodeURIComponent("/チャンネルID or チャンネル名/");
   var header = ""; //その他情報
   var body = ""; //投稿内容
   var color = "#4286F2"; //投稿色(default:青)
   
  
 //spreadsheetからデータを取得
   var sheet = SpreadsheetApp.getActiveSheet();
   var row = sheet.getLastRow();
   var column = sheet.getLastColumn();
   var range = sheet.getDataRange();
    
   for (var i=1;i<=column;i++) {
     var item = range.getCell(1, i).getValue(); //1行目
     var value = range.getCell(row, i).getValue();  //2行目以降
     if(item == item_text){ //投稿内容ならbodyへ
       body += value;
     }else if(item != item_timestamp){ //それ以外はheaderへ
       if(item == item_pic){ //画像の項目の処理(画像はドライブへのリンクが返ってくる)
         var pic_list = value.split(","); //複数選択時は「,」で区切られて出力されるので、1枚ごと改行する
         if(pic_list != ""){
           var pic_num = pic_list.length;
           value = "画像枚数："+pic_num+"枚";
           for(var j=0;j<pic_num;j++){
             value += "\n"+(j+1)+". "+pic_list[j];
           }
         }
       }
       if(item == item_time){ //投稿時間の処理
         if(value != ""){
           value = "`"+value+"`"; //目立つようにSlackの装飾(枠)で囲む
         }
       }
       if(item == item_kind){ //SNSの種類の処理
         if(value.indexOf("Twitter") > -1){ //Twitterの場合(複数のアカウントがある)
           if(value.indexOf("aaa") > -1){ //aaaがフォームの回答と部分一致
             color = "#4286F2"; //色を変えることで見やすく
             value = "<https://twitter.com/aaa|"+value+">"; //リンクにする
           }else if(value.indexOf("bbb") > -1){
             color = "#52C300";
             value = "<https://twitter.com/bbb|"+value+">";
           }
         }else if(value.indexOf("Instagram") > -1){ //Instagramの場合
           color = "#E95172";
           value = "<https://www.instagram.com/ccc|"+value+">";
         }
       }
       
       header += ""+item+"： "+value+"\n"; 
     }
   }
   
 //Slackに投げるよ
  body = encodeURIComponent(body);
  header = encodeURIComponent("[{'color': '"+color+"', 'text': '"+header+"'}]");
  var slackUrl = 'https://slack.com/api/';
  var textPostUrl = slackUrl + 'chat.postMessage?token='+slackToken+'&channel='+channel+'&text='+body+'&attachments='+header;
  var response = UrlFetchApp.fetch(textPostUrl);
  Logger.log(JSON.parse(response.getContentText()));
}
```

### 注意点

- 日本語をURLで送る場合は、エンコード処理が必要→ `encodeURIComponent`
- 投稿するチャンネルの指定は、チャンネル名でも可能であるが、任意に変えられるのでチャンネルIDが無難。チャンネルIDの取得方法→https://qiita.com/unsoluble_sugar/items/603e51106d9632f3ea4f
- attachmentsの部分は変えたら見やすくなる→https://qiita.com/daikiojm/items/759ea40c00f9b539a4c8

## Slack API

https://api.slack.com/apps
ここからAppを作る。

とりあえず、`Permission`でScopesを設定する。

(BotTokenScopesとUserTokenScopesが分かれていて？となりました。)

UserでScopesを設定すると、投稿するのがBotではなくUserになりダサいです。(chat.postMessage のパラメータで指定できるかなと思ったけど無理だった)

なので、BotでScopesを設定します。投稿するだけ(chat.postMessage)なので、`chat.write`を設定します。(以前は、`chat.write.bot`だったような気がします。おそらくBotとUserでScopesの設定画面が分かれたので、変わったのでしょう。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430946/97fe1a25-b1d4-3f54-cc91-d8f2376f9456.png)

次にインストールしようと思ったけど、うまくできない。どうやら実行できるBotがないとのこと。

悩みに悩んだ結果、`Bots`で「App Display Name」を設定したらできました。
なお、default Name は日本語NGなので注意が必要です。

## Googleフォーム

トリガーを回答されたときにしておくだけ。

# 気づいた点
- attachmentsの部分は「テキストをコピー」でコピーされない ← 作ってるときに気づいた。初めて知った。

# 改善
- 画像をSlackのメッセージに添付させればめっちゃ便利 → `file.upload`を使えばなんとかなりそう？

# まとめ
便利になった。特にコピペが楽！！！