ChatGPTに聞きながらランダム指名Slack botを作った話(後編)
- 2024年11月12日
- CATEGORY- 1. 技術力{技術情報}
後編です!
さて、ここまでちゃっぴーに作ってもらったところで、GASのトリガーについて考えていきます。
今回作ってもらって、定期的に動かしたい関数は3つ。
- notifyRandomEmployee:Slackにメッセージを投下するメインの関数
- createTrigger:notifyRandomEmployee関数のトリガーを作成する関数(chatGPTは、「初回実行時に手動で設定する必要あり」とコメントしていますね。)
- importJapaneseHolidays:祝日をスプレッドシートにインポートする関数
気をつけたいことは、GASのトリガーって、毎日9:30 という設定ができないんですよね。
GASのGUIから確認しても、日付ベース(毎日)のトリガーだと一時間ごとにしか選択できません。これだと、「9時〜10時の間のどこか」で「指名されるかもしれない…」というナゾのドキドキ感を味わうことになります。
ちゃっぴーが書いてきた以下のコードも、実は9:30前後(おそらく前後15分?)に実行されるっていう引っ掛けコードです。(nearMinuteと言っています。。)
function createTrigger() { ScriptApp.newTrigger('notifyRandomEmployee') .timeBased() .atHour(9) .nearMinute(30) .everyDays(1) .create(); }
9:30ぴったりに実行したかったので、このコードを変更することにします。
ググったら結構みんな同じことで悩んでいるようで、毎日「特定の日時」に実行されるトリガーを作成する、という方法でハックしてるみたいです。先人たちにならい、以下のようにcreateTrigger関数を変更しました。
// トリガーのセットアップ(毎日決まった時間に実行) function createTrigger() { var allTriggers = ScriptApp.getProjectTriggers(); var existingTrigger = null; // すでに存在するnotifyRandomEmployeeトリガーを探す for (var i = 0; i < allTriggers.length; i++) { if (allTriggers[i].getHandlerFunction() === 'notifyRandomEmployee') { existingTrigger = allTriggers[i]; break; } } // すでに存在するトリガーがあれば削除 if (existingTrigger !== null) { ScriptApp.deleteTrigger(existingTrigger); } var triggerDay = new Date(); triggerDay.setDate(triggerDay.getDate() + 1); triggerDay.setHours(9); triggerDay.setMinutes(30); triggerDay.setSeconds(0); ScriptApp.newTrigger('notifyRandomEmployee') .timeBased() .at(triggerDay) .create(); }
この関数は、毎日10時〜11時のどこかで実行するようにセットしました。
notifyRandomEmployeeを翌日9:30にセットしてくれます。かつ、実行済みの古いnotifyRandomEmployeeのトリガーがあれば削除してくれます。
これで3つのうちの2つの関数はトリガーが定まりました。
残すはimportJapaneseHolidaysですが、これは正直いつでもいい。年一でもいいので、手動で実行するでも全然いい。でも、せっかくだしな〜ということで、ちゃっぴーに以下のお願いをしてコードを書き換えてもらいました。
毎月1日の0時に定期実行するようにするから、当月の祝日リスト取得に直して
できたものはこちら
function importJapaneseHolidays() { const calendarId = 'ja.japanese.official#holiday@group.v.calendar.google.com'; // 日本の祝日カレンダーID const today = new Date(); // 当月の1日 const startOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); // 翌月の1日 const startOfNextMonth = new Date(today.getFullYear(), today.getMonth() + 1, 1); // 当月の祝日を取得 const events = CalendarApp.getCalendarById(calendarId).getEvents(startOfMonth, startOfNextMonth); const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(HOLIDAY_SHEET_NAME); if (!sheet) { throw new Error('祝日シートが見つかりません'); } // シートをクリアして、新しいデータを追加 sheet.clear(); sheet.getRange(1, 1).setValue('祝日'); // 祝日を1列目に書き込む(日本時間に変換) events.forEach((event, index) => { const startTime = event.getStartTime(); // タイムゾーンを日本時間に変更して日付を取得 const dateInJapan = Utilities.formatDate(startTime, Session.getScriptTimeZone(), 'yyyy-MM-dd'); sheet.getRange(index + 2, 1).setValue(dateInJapan); }); }
いいね!
というわけで、importJapaneseHolidaysは毎月1日の0〜1時の間に動いています。
メッセージやアイコンを自分好みに直したら、完成です!
こまかい話ですが、最初にちゃっぴーに書いてもらったnotifyRandomEmployee内ではJSTの考慮がなされていないので、つい先日の祝日は誤って実行されてしまいました。ごめんよ、指名されてしまった人。現在は修正したので祝日には実行されないです。
まとめ
Slackリマインダー、便利なんですが、+αなにかしたい、というときに良いツールがほしいなと思ってたんですよね。
今回GASに触れたことで、大分ハードルが下がりました。ちゃっぴーのサポートも手厚いですし、積極的に使っていきたいと思います。
Enjoyプロンプトライフ!
- 2024年11月12日
- CATEGORY- 1. 技術力{技術情報}