誕生日を祝ってくれるSlackBotを作った

とあるワークスペースで誕生日大公開キャンペーンがあったのでSlackBotに祝わせます。

システム概要

GoogleFormに誕生日と名前 + αを入力してもらうと、SlackBotが期日に「○○君、おめでとう!」と投稿します。主にGoogleAppScriptを使っています。

f:id:sho0126hiro:20190707231828j:plain

Step1.Google Formで入力部を作成

GoogleFormを作って、簡単な入力フォームを作ります。

f:id:sho0126hiro:20190707231934p:plain

入力する日付は( format x/y )と固定にしました。(処理が簡単なので)

Step2.フォームの入力を指定のシートに入力

本来自動でスプレッドシートの作成 + 入力をしてくれます。特定のスプレッドシートの特定箇所に入力させたい場合は次のような処理が必要です。

注:今回の場合は設計時にGoogleFormの使用は考えていなかったので、ユーザ入力部(GoogleForm)はSlackBotへの投稿プログラムの作成後に取り掛かりました。

フォームの右上の︙ボタンをクリック → スクリプトエディタをクリック

次のようにコードを入力します。

function onSubmitForm(e) {
  FormApp.getActiveForm();
  var res = e.response.getItemResponses();
  var name = res[0].getResponse(); // 質問の1番目の入力結果 => 名前
  var date = res[1].getResponse(); // 質問の2番目の入力結果 => 誕生日
  var opt  = res[2].getResponse(); // 質問の3番目の入力結果 => 追加メッセージ
  // input to specific sheet
  var ss_id = "<ss_id>";
  var sh_name = "<sheet_name>";
  var sh = SpreadsheetApp.openById(ss_id).getSheetByName(sh_name);
  var last_row = sh.getLastRow(); // シートの最終行を取得
  // sh.getRange(row,column).setValue(value);
  sh.getRange(last_row+1,1).setValue(name);
  sh.getRange(last_row+1,2).setValue(date);
  sh.getRange(last_row+1,3).setValue(opt);
}

ss_id はシートのURLに含まれています。sheet_nameはシート名です。

https://docs.google.com/spreadsheets/d/<ここ>/edit

Step.3 フォーム入力時に関数実行トリガの作成

スクリプトエディタ => 編集 => 現在のプロジェクトのトリガーを選択

G suit Developer Hubに飛ばされるので、右下のトリガーを追加からトリガーを追加します。

実行する関数 onSubmitForm
デプロイ HEAD
イベントのソース フォームから
イベントの種類 フォーム送信時

これで、フォームを入力すると、指定の行と列に入力項目が入ります。

Step.4 日付の確認とSlackへの送信

シートの形式

シートの形式は次のようになっています

name date option
一郎 1/1 追加メッセージ
二郎 7/13 追加メッセージ

日付の確認とSlackへの送信

シートは毎日実行されます。今日の日付がシートに含まれているかを確認し、Slackに送信します。

誕生日と名前が記入されるシートから、ツール => スクリプトエディタを選択

次のようなコードを書きます。

function main() {
  var sheet = SpreadsheetApp.getActiveSheet();
  // 今日の日付を取得 (format : MM/dd)
  var now = Utilities.formatDate(new Date(), 'JST' , "MM/dd");
  var index = 2;
  while(sheet.getRange('B'+ index).getValue() != ''){
    // シートから日付を取得 (format : MM/dd)
    sheet.getRange('B'+index ).getValue()
    var birthday = Utilities.formatDate(value, 'JST', 'MM/dd');
    if(now == birthday){
      var name = sheet.getRange('A'+index).getValue();
      var opt = sheet.getRange('C'+index).getValue();
      // slackへ送信
      postToSlack(now,name,opt);
    }
    index+=1;
  }
}

B列(2行目から)に誕生日が含まれています。

誕生日の入力がなくなるまでwhileループで日付を確認しています。

function postToSlack(date,name,opt){
  const SLACK_TOKEN = '<slack_token>';
  // message
  var msg = "今日は"+name+"の誕生日!おめでとう!"+opt;
  // url
  var url = "https://slack.com/api/chat.postMessage?token="+SLACK_TOKEN+
            "&channel=<channel_name>"+
            "&text="+msg +
            "&username=<user_name>BOT"+
            "&pretty=1";
  // post
  var res = UrlFetchApp.fetch(url);
}

Slackへの送信はGoogle App Script標準のUrlFetchApp.fetchメソッドを使います。

SlackAPIのchat.postMessageにリクエストを送信しています。

Step.5 日付確認プログラムを定期実行させる

Step.4で作ったプログラムにトリガを付けます。

スクリプトエディタ => 編集 => 現在のプロジェクトのトリガーを選択

G suit Developer Hubに飛ばされるので、右下のトリガーを追加からトリガーを追加します。

実行する関数を選択 main
イベントのソースを選択 時間主導型
時間ベースのトリガーのタイプを選択 日付ベースのタイマー
時刻を選択 <〇時~〇時>(お好み)

Google側が重くならないように「〇時〇分ぴったり」設定できないみたい。(するなら時間ベース・分ベースのタイマーにしよう)

8時ピッタリにとか、0時ピッタリに設定したい場合は、Step2で作ったプログラムの日付フォーマットをMM/dd/hhまで設定して比較しましょう。

トリガについて

指定したプロジェクトは全てG Suite Developer Hubでまとめて見れます。

どんなプロジェクトでいつトリガ設定していたっけ…?みたいな時、一括で見れるから便利そう。

f:id:sho0126hiro:20190707232120p:plain

動作

googleFormに誕生日を入力すると、SlackBotが祝ってくれます。太郎君おめでとう!

f:id:sho0126hiro:20190707232440j:plain