こんにちは。GMOアドマーケティングのA.Yです。
目的
GoogleFormの提出があった時に、Slack通知が来るようにします。
背景
弊社では事業部からエンジニアへの問い合わせにSlackを利用し、気軽に質問を受け付けられるようにしています。
しかし、そのままではこのような課題がありました。
・担当者ごとに質問の仕方が異なり、エンジニアとの間で何回もやりとりが発生
(障害がおきても発生時刻がなかったり、いつまでに回答が必要か期日がなかったり)
・問い合わせの内容が流れてしまい、同じような質問がなんどもされてしまう
そこで、
・問い合わせフォームのフォーマット通りに記入してもらい、その内容がSlackに通知される
・フォームの内容は、GoogleFormの機能でGoogle Spread Sheetに蓄積される
ように自動化しました。
手順
ほぼ、こちらの手順を参考にスクリプトを作成します。
https://qiita.com/pchan52/items/574e930a3cc42cf7f8b9#%E7%9B%AE%E7%9A%84
ただし、今回は以下の特殊な要望があったので、それぞれ下記のように対応しました。
・ログインした社内ユーザのメールアドレスは取れるので、そこから氏名を取得して欲しい
→ メールアドレスと氏名のマッピングシートを用意して、ループを回して取得します
・投稿日時を整形して欲しい
→ 変換したいカラムまでループを回し、変換対象カラムのデータをみやすい日付に変換します
・デバッグしやすいように、エラーが発生した行をログ出力したい
→ 例外をキャッチしてログ出力します。社内ツールといえども、運用のことも考えてエラー処理はきっちりとログに出しましょう。
実装
以下にソースコードを示します。それぞれ参考としたリンクが書いてあるので、参考にしてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
/* スプレッドシートから行のデータを取得してSlack通知します。 前提:Googleフォームから受けた問い合わせがスプレッドシートに記録されること */ //作成方法:https://liapoc.com/new-google-form.html function fetchDataFromForm() { Logger.log('fetchDataFromForm() debug start'); // 通知先チャンネルの指定 var NOTIFY_CHANNEL = "#test_notification"; // 特殊処理カラム名の指定 var DUEDATE_COL_NAME = '回答期日'; var TIMESTAMP_COL_NAME = 'タイムスタンプ'; var OCCUR_DATE_COL_NAME = '発生日時'; var MAILADDR_COL_NAME = 'メールアドレス'; var ATTACHMENT_COL_NAME = '添付ファイル'; //収集したメアドを漢字氏名にするためのマッピング表。 var NAMELIST_SHEET_NAME = 'nameList'; try { var body = "\n@ssp-support\n■新しい問い合わせがありました。このSlackで返答してください。\n\n"; // スプレッドシートの取得 var sheet = SpreadsheetApp.getActiveSheet(); var rows = sheet.getLastRow(); var cols = sheet.getLastColumn(); var rg = sheet.getDataRange(); Logger.log("rows=" + rows + " cols=" + cols); for (var i = 1; i <= cols; i++) { var col_name = rg.getCell(1, i).getValue(); // カラム名 var col_value = rg.getCell(rows, i).getValue(); // 入力値 Logger.log("col_name=" + col_name + " col_value=" + col_value); if (col_name === DUEDATE_COL_NAME) { // 特殊処理(日付整形) body += "【" + col_name + "】"; body += Utilities.formatDate(col_value, "JST", "yyyy/MM/dd") + "\n"; } else if (col_name === TIMESTAMP_COL_NAME || col_name === OCCUR_DATE_COL_NAME) { // 特殊処理(日付整形) body += "【" + col_name + "】"; body += Utilities.formatDate(col_value, "JST", "yyyy/MM/dd HH:mm") + "\n"; } else if (col_name === MAILADDR_COL_NAME) { // 特殊処理(問合せ者アドレスを氏名に変換) // See also: https://tonari-it.com/gas-setformular1c1/ var nameSheet = SpreadsheetApp.getActive().getSheetByName(NAMELIST_SHEET_NAME); //名前シートを取得 var maxRow = nameSheet.getDataRange().getLastRow(); //シートの使用範囲のうち最終行を取得 var usr_name = col_value.match("(.*)(?=@)")[0]; // 収集したメアドの@以前を取得 /* 全ての行について繰り返し */ for (var j = 1; j <= maxRow; j++) { //2列目がヒットしたら漢字氏名(4列目)に詰め替え if (nameSheet.getRange(j, 2).getValue() === usr_name) { body += "【" + "問合せ者氏名" + "】"; body += nameSheet.getRange(j, 4).getValue() + "\n"; } } } else if (col_name === ATTACHMENT_COL_NAME && col_value === "") { // 添付なかったら出力しない continue; } else { // 通常処理 body += "【" + col_name + "】"; body += col_value + "\n"; } } sendToSlack(body, NOTIFY_CHANNEL); Logger.log('fetchDataFromForm() debug end'); } catch (e) { var error = e; Logger.log("message:" + error.message + "\nfileName:" + error.fileName + "\nlineNumber:" + error.lineNumber + "\nstack:" + error.stack); } } //作成方法:https://qiita.com/pchan52/items/574e930a3cc42cf7f8b9 function sendToSlack(body, channel) { Logger.log('sendToSlack() debug start'); var url = "<webhookのURL>"; var data = { "channel": channel, "username": "問い合せ受付Bot", "text": body, "icon_emoji": ":gmossp:", "link_names": 1 }; var payload = JSON.stringify(data); var options = { "method": "POST", "contentType": "application/json", "payload": payload }; var response = UrlFetchApp.fetch(url, options); Logger.log('sendToSlack() debug end'); } |
最後に
この取組によって、見落としがちな問い合わせをSlackで確認できるようになり、さらにエンジニアがSlackのスレッドに返信する形で対応できるようになり、
Slackの会話が錯綜してしまうことがなくなりました。こういった改善は地味ですが、積み重ねていくことでスケールする組織を築いていこうとおもいます。
地味にハマったこと
@でメンションを飛ばす場合は、 "link_names": 1という設定をしないと、ただの文字列として投稿されてしまい、メンションになりません。
マイブームは、ペーパードライバー卒業・天体観測・アマチュア無線・BCL受信・カセットテープデッキのメンテ修理・登山とか。
写真は飼っている文鳥のおつゆちゃん。