Skip to content

返却期限アラート ​

鍵の返却期限は 18:30 JST固定 です(internal/keymanager/alerts.go)。

仕組み ​

  1. 鍵取りが記録される(ボタン//key//backdate)たびに setAlertTrigger が呼ばれ、その日の18:30をトリガー時刻として計算します
  2. トリガー時刻が未来なら、SQLiteの pending_alerts テーブルに1行追加してから time.AfterFunc でインプロセスのタイマーを仕込みます
  3. トリガー時刻がすでに過去(例: 18:30以降に鍵を取った、または /backdate で過去の時刻を遡って登録した)の場合は、即座に警告を投稿します
  4. タイマー発火時、現在の貸出状況を再取得し、同じユーザーがまだ借りたままであれば ログチャンネルに警告を投稿します。すでに返却済みなら何もしません
  5. 発火の成否によらず、該当行はSQLiteから削除されます

なぜSQLiteに永続化しているのか ​

このBotは単一の長時間稼働プロセスとして動作します(VPS上で常駐)。time.AfterFunc によるインプロセスのタイマーだけでは、再デプロイやクラッシュでプロセスが再起動すると予定していたアラートが消えてしまいます。そこで pending_alerts テーブルに「誰の・いつの分のアラートか」を先に永続化しておき、NewService 起動時に recoverPendingAlerts が未処理分をすべて読み出して再スケジュール(またはすでに期限超過なら即時発火)します。

テーブル定義 ​

sql
CREATE TABLE IF NOT EXISTS pending_alerts (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id     TEXT NOT NULL,
    username    TEXT NOT NULL,
    trigger_at  TIMESTAMP NOT NULL
);

過去のスキーマからの移行

以前は limit_hours(NOT NULL)カラムを持つスキーマでしたが、返却期限が18:30固定になったタイミングで廃止されました。既存デプロイでこのカラムが残っていると、limit_hours を指定しないINSERTが NOT NULL 制約違反で静かに失敗し、アラートが一切スケジュールされなくなる不具合があったため、起動時に dropLegacyLimitHoursColumn が旧カラムを検知してテーブルを再作成する自己修復ロジックが入っています(pending_alerts はあくまで進行中のタイマー予定のみを保持するテーブルなので、テーブルの作り直しで消えても実害はありません)。

アラート文面 ​

状況メッセージ
通常の期限超過(タイマー発火時)⚠️ 【警告】 <@user> さん (username)、返却期限の18:30を過ぎても鍵が返却されていません。速やかに返却するか、状況を報告してください!
遡り登録の時点ですでに期限超過⚠️ 【即時警告】 <@user> さん (username)、遡り登録された鍵取り時刻の時点で、すでに返却期限の18:30を過ぎています!速やかに返却するか、状況を報告してください。

どちらもログチャンネル(LOG_CHANNEL_ID)に投稿されます。