岩盤浴で寝落ちしてる間にAIが全自動でシステム構築した話
岩盤浴で寝落ちしてる間にAIが全自動でシステム構築した話
深夜2時、岩盤浴でリラックスしているとき、ふとメール通知の問題が頭に浮かんだ。
「再通知メールのボタン、押したかどうかわからなくて何度も押しちゃうんだよな」
スマホを取り出して、自分のAIアシスタント(OpenClaw)にメッセージを送った。
「ボタン押したら即座に見た目変えて。何度も押せないようにしてほしい」
返信は10秒後に来た。
「了解。方法2を実装する。5分で実装する。」
そこから先は、もう自分は何もしなかった。
岩盤浴のベッドで横になって、タオルを顔にかけて、うとうとしながらたまにスマホを見る。AIからの進捗報告が次々に届く。
✅ DBテーブル追加 - telegram_messages(メッセージID記録用)
✅ gmail_watcher.py修正 - 送信後にTelegramメッセージIDを取得&保存
✅ callback_handler.py拡張 - ボタン押下時に元のメッセージを編集
気づいたら寝落ちしていた。
1時間後に目を覚ましたとき、スマホの通知を見た。
「✅ 実装完了!テスト:次の再通知(00:18頃)で、またボタン付きメッセージが届く。押したら、元のメッセージが編集されて『✅ 対応済み』に変わる。おやすみ。完璧に動くはずだから、安心して寝ろ!」
実際にテストしてみたら、完璧に動いた。ボタンを押すと即座に「✓ 処理済み」に変わり、二度押しできなくなっている。
岩盤浴で寝落ちしてる間に、AIが全自動でシステムを構築した。
何が起きたのか
この日の深夜、私は「Gmail Watcher V2」という自作のメール監視システムの改善を進めていた。
重要メールを逃さないための再通知機能にインラインボタンを追加したのだが、「ボタンを押したかどうかわからず、何度も押してしまう」という問題が発生していた。
解決策は明確だった:
– ボタン押下 → 即座にそのボタンだけ無効化表示に変える
– 「✅ 対応済み」→「✓ 処理済み」のように変更
– 他のボタンはそのまま有効
ただ、実装は少し複雑だった:
1. Telegram メッセージIDをDBに保存
2. ボタン押下時に元のメッセージを取得
3. ボタン配列を再構築(押されたボタンだけ無効化)
4. メッセージを編集して更新
これを全部、AIに任せた。
AIに任せるまでの葛藤
正直なところ、最初は「自分でやった方が早いかも」と思った。
コード書くのは慣れているし、頭の中に実装イメージはある。AIに指示を出して、確認して、修正して…という流れは、逆に手間じゃないか?
でも、岩盤浴でリラックスしているときに「今すぐコード書きたい」とは思わなかった。スマホで簡単に指示を出して、あとは任せたかった。
結果的に、それが大正解だった。
AIが自動構築したもの
AIが実装したのは以下の機能:
1. Telegramメッセージ管理テーブル
CREATE TABLE telegram_messages (
email_message_id TEXT NOT NULL,
telegram_message_id TEXT NOT NULL,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
);
メール通知を送信したとき、そのTelegramメッセージIDを記録する仕組み。
2. メッセージ送信時のID取得ロジック
# メッセージ送信
result = subprocess.run(['openclaw', 'message', 'send', ...])
# 送信直後のメッセージ履歴から最新メッセージIDを取得
time.sleep(0.5)
read_result = subprocess.run(['openclaw', 'message', 'read', '--json', '--limit', '1'], ...)
telegram_msg_id = messages[0]['id']
# DB保存
c.execute('INSERT INTO telegram_messages VALUES (?, ?)', (email_id, telegram_msg_id))
送信後に履歴から最新メッセージIDを取得するという、ちょっとトリッキーだけど確実な方法を採用していた。
3. ボタン押下時の即時変更ロジック
def edit_telegram_message(email_id, status_text, action='handled'):
# 元のメッセージを取得
messages = read_telegram_messages(limit=50)
target_msg = find_message_by_id(email_id)
# ボタン配列を再構築(押されたボタンだけ無効化)
if action == 'handled':
buttons = [
{"text": "✓ 処理済み", "callback_data": "noop"}, # 無効化
{"text": "🗑️ 不要", "callback_data": f"gmail_ignore:{email_id}"},
{"text": "⏰ 後で", "callback_data": f"gmail_snooze:{email_id}"}
]
# メッセージ編集
subprocess.run(['openclaw', 'message', 'edit', '--buttons', buttons_json], ...)
押されたボタンだけ「✓ 処理済み」に変え、callback_data: "noop" で無効化する。シンプルだけど効果的な実装。
難しかった点(AIが解決したこと)
実装中、AIが直面した(そして解決した)課題がいくつかあった:
課題1: TelegramメッセージIDの取得
openclaw message send コマンドは送信成功の戻り値しか返さず、メッセージIDが取れない。
解決策:送信直後に openclaw message read --limit 1 で履歴から最新メッセージを取得し、そのIDを記録する。
課題2: ボタン配列の再構築
Telegramのインラインボタンは [[{text, callback_data}]] という二次元配列で表現される。押されたボタンだけ無効化するには、配列全体を再構築する必要があった。
解決策:action パラメータで「handled/ignored/snoozed」を受け取り、対応するボタンだけ callback_data: "noop" に変更。
課題3: メッセージ編集のタイミング
ボタン押下 → DB更新 → メッセージ編集 の順序を間違えると、二重処理が発生する可能性があった。
解決策:DB更新を先に行い、その後にメッセージ編集。失敗してもDB状態は一貫性を保つ。
AIに任せて良かったこと
- 集中力を温存できた
岩盤浴でリラックスしているときに、コード書きのための集中力を使わずに済んだ。スマホで指示を出すだけ。
- 実装の質が高かった
自分で書いていたら、「とりあえず動けばいいや」で妥協していたかもしれない。AIは「エッジケース」や「エラーハンドリング」まで丁寧に実装していた。
- ドキュメントが自動で残った
AIとのチャットログが、そのまま「実装の経緯」として記録されている。後から振り返りやすい。
「自分でやった方が早い」は本当か?
エンジニアなら誰しも、「AIに指示出すより、自分で書いた方が早い」と思うことがあるはずだ。
でも、それは「今すぐ手を動かせる状態」に限った話だ。
- 岩盤浴でリラックスしているとき
- 通勤中や移動中
- 夜中に布団の中で思いついたとき
こういう「手は空いてないけど、頭は動いてる」瞬間に、AIに指示を出せるかどうかが鍵になる。
私の場合、岩盤浴で寝落ちしてる間にシステムが完成していた。「自分でやった方が早い」どころか、自分でやらない方が早かった。
まとめ
今回の教訓:
- AIに任せることで、自分の集中力を温存できる
- 「今すぐ手を動かせない」タイミングでも、システム構築は進められる
- 実装の質は、AIに任せた方が高い場合もある
「AIは補助ツール」という認識はもう古い。今は「AIを使うことで、自分が楽できる」時代だ。
岩盤浴で寝落ちしながらシステムを構築する。こんな働き方が、もう実現している。
関連記事:
– Gmail Watcher V2 実装の全記録
– Telegramボット開発でハマったポイント
– 個人開発で使えるAI活用術