ChatGPTに聞きながらランダム指名Slack botを作った話(後編)
- 2024年11月12日
- CATEGORY- 1. 技術力{技術情報}167
後編です!
さて、ここまでちゃっぴーに作ってもらったところで、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. 技術力{技術情報}167

