目的
とある団体の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
として設定している。
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の設定画面が分かれたので、変わったのでしょう。)
次にインストールしようと思ったけど、うまくできない。どうやら実行できるBotがないとのこと。
悩みに悩んだ結果、Bots
で「App Display Name」を設定したらできました。
なお、default Name は日本語NGなので注意が必要です。
Googleフォーム
トリガーを回答されたときにしておくだけ。
気づいた点
- attachmentsの部分は「テキストをコピー」でコピーされない ← 作ってるときに気づいた。初めて知った。
改善
- 画像をSlackのメッセージに添付させればめっちゃ便利 →
file.upload
を使えばなんとかなりそう?
まとめ
便利になった。特にコピペが楽!!!