背景
ちょっとした広報などの担当者を決める際に、
「前回**さん(優しい方)がやってたから**さんにお願いしよう!」
といった負のサイクルが起きていた。
これを打破すべく平等に担当者を割り振るbotが欲しい。。。
どんな感じにするか
とは言いつつも使われなければ意味がないので以下の要件で検討した
- 平日朝に定期的に実行できる
- 担当者リストが容易に変更できる状態である
- (絶対に!)運用負荷がほぼない
- 自分の手から離れても他の方が見て修正できる
- 様々な担当者の割り振りができる拡張性
これらを考えた結果
「spread sheetに担当者とか書いて、gasで送るでいいんじゃない?」
に落ち着いた
実際のコードなど
spread sheet
ここはアプリでいうデータベースの部分になるので、
以下の情報を記載しておく必要がある
- なんの担当者か
- 本文(担当内容の説明)
- 通知先はどこか(slack incomming webhook url)
- 担当者リスト(slackのユーザー名)
- 前回誰が担当者だったか
それらをまとめた結果以下のようなテーブル構造になった。
何の担当者? | 本文 | slack incomming url デフォルトチャンネルに投げます |
担当者リスト | 担当者番号 |
---|---|---|---|---|
広報 | 広報をお願いします!!!言葉遣いに注意!! | https://hooks.slack.com/services/******* | ore,boku,anata | 0 |
Gas
main関数
- SSから情報を取ってくる
- 行数だけ以下操作をループで回す
- slack関数に情報を渡す
- 担当者番号を一つ進める
main.gs
var spreadsheet = SpreadsheetApp.openById('スプレッドシートのID(URL内の文字列)');
var settings_sheet = SpreadsheetApp.getActive().getSheetByName('SSタブ名');
/**
* メインの関数
* @return {None}
*/
function onRunQuery() {
var lastRow = settings_sheet.getLastRow()
for (var i=2; i <= lastRow; i++) {
var responsible = settings_sheet.getRange(i,1).getValue();
var bodyText = settings_sheet.getRange(i,2).getValue();
var slackIncommingUrl = settings_sheet.getRange(i,3).getValue();
var personList = settings_sheet.getRange(i,4).getValue().split(',');
var personNum = personList.length;
var indexNum = settings_sheet.getRange(i,5).getValue();
var nextIndexNum = (indexNum+1) % personNum;
send_message_slack(personList[indexNum] , personList[nextIndexNum], responsible, bodyText, slackIncommingUrl)
settings_sheet.getRange(i,5).setValue(nextIndexNum);
}
}
slack関数
内容を整形してslackにpost
slack.gs
/**
* slackにattachmentを送信する関数
*
* @param {string} slackMention 担当者
* @param {string} subSlackMention サブ担当者
* @param {string} responsible 担当名
* @param {string} bodyText 本文
* @param {string} slackIncommingUrl slack_url
* @return {None}
*/
function send_message_slack(slackMention , subSlackMention, responsible, bodyText, slackIncommingUrl) {
var slack_message_json =
{
"username" : responsible,
"icon_emoji": ":god1:",
"title" : "本日の*" + responsible + "*",
"text" : "<@" + slackMention + "> 本日の *" + responsible + "*",
"attachments" : [
{"fields": [
{
"title": "担当",
"value": slackMention,
"short": true
},
{
"title": "サブ",
"value": subSlackMention,
"short": true
},
{
"title": "本文",
"value": bodyText,
"short": false
}
],
"footer": "※以下spread sheetのGASから送信されたメールです\nhttps://docs.google.com/spreadsheets/**************"}
]
};
var payload = JSON.stringify(slack_message_json);
var options =
{
"method" : "post",
"contentType" : "application/json",
"payload" : payload
};
var res = UrlFetchApp.fetch(slackIncommingUrl, options);
Logger.log(res);
}
トリガー
Google Apps Script で毎日決まった時刻にスクリプトを実行するトリガー設定
などを参考にぽちぽち設定
結果
以下のように神からご指名が来るようになり平等な世界になりました。
レコードを追加して広報以外も割り振ってもらおうと思います!
やってみて
要件を満たす形でできたので概ね良かったと思います。
時間があれば以下の内容も詰め込みたかった。。
- slack postのリトライ処理
- 担当者が休みだった際に再び割り振りを手軽に行うボタン的な(gasにあったはず)