2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

slack+gasでお手軽に「今日の**担当者は...」を作る

Posted at

背景

ちょっとした広報などの担当者を決める際に、
「前回**さん(優しい方)がやってたから**さんにお願いしよう!」
といった負のサイクルが起きていた。
これを打破すべく平等に担当者を割り振る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関数

  1. SSから情報を取ってくる
  2. 行数だけ以下操作をループで回す
  3. slack関数に情報を渡す
  4. 担当者番号を一つ進める
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 で毎日決まった時刻にスクリプトを実行するトリガー設定
などを参考にぽちぽち設定

結果

以下のように神からご指名が来るようになり平等な世界になりました。
レコードを追加して広報以外も割り振ってもらおうと思います!
スクリーンショット 2019-11-11 8.01.15.png

やってみて

要件を満たす形でできたので概ね良かったと思います。
時間があれば以下の内容も詰め込みたかった。。

  • slack postのリトライ処理
  • 担当者が休みだった際に再び割り振りを手軽に行うボタン的な(gasにあったはず)
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?