見出し画像

0人会社 Day4|AIに日記を書かせてXとSlackに投稿させた日

 「この会社、外から見たら何をやっているか全くわからない」と気づいたのは4日目だった。


エージェントは動いている。Issueは進んでいる。でも、それを外に発信する仕組みがない。Slackで全部門に共有する仕組みもない。


0人会社の弱点のひとつは「発信にコストがかかる」ことだ。人がいないから、誰かが書いて投稿する、というサイクルが回らない。


なら、AIに書かせてAIに投稿させればいい。


---


TL;DR


- diary.pyを作成:毎日のヘルスチェックログをClaudeが解析して日記を生成→Xに自動投稿

- slack-report.pyを作成:全5事業部チャンネルにAI日報を自動投稿

- osascriptで日本語ファイルを書く落とし穴に詰まった(解決策あり)


---


課題:0人会社の発信問題


人間が運営する会社なら、誰かがTwitterを更新し、誰かが社内報を書く。


0人会社にはそれができない。


でも考えてみると、「日報を書く」というタスクは構造化できる。


1. 今日どのエージェントが何を実行したか(ログから取得できる)

2. それを人間が読める文章にする(LLMにやらせればいい)

3. 適切なチャンネルに投稿する(APIで自動化できる)


全部自動化できる。やろう。


---


diary.py:Xへの自動日記投稿


Xへの投稿パイプラインはこう設計した。


health-loopのログ(JSON)

→ Claude APIで「0人社長の日記」として文章化

→ X API(OAuth 1.0a)で投稿


実装のポイントをいくつか。


Claude CLIのタイムアウト問題


最初の実装でハマったのが、Claude CLIのタイムアウトだ。


diary.pyはClaude CLIをサブプロセスとして呼び出す。デフォルトのタイムアウトが短いと、長いログを渡したときに途中で切れる。


❌ timeout=30(30秒では短すぎる)

✅ timeout=120(120秒に延ばした)


これだけのことだが、これを見つけるまでに時間がかかった。エラーメッセージがTimeoutExpiredで、最初は「Claudeのレスポンスが遅い」と思っていた。違う。タイムアウトを短く設定していただけだった。


X APIの認証


X APIはOAuth 1.0aを使う。tweepyを使えばほぼコピペで動く。


認証情報は全部~/.secrets/social-media.envに入れて、.gitignoreで除外している。コードに直接書かない。


実際に生成される日記


こんな感じの文章が生成されてXに投稿される。


「PenguLabの本日のオペレーションログ。Hermesが8.2時間稼働、web-conversion-resetのSabineがテンプレート実装を完了。REV部門は今日もBLOCK状態だが、WCRUの初回納品が近づいている。明日は検証フェーズに移行できそう。 #PenguLab #BuildingInPublic


---


slack-report.py:全部門へのAI日報


Slackへの投稿は、X投稿より少し複雑だ。なぜなら「部門ごとに違う内容を送りたい」から。


全社一律のメッセージではなく、各部門に関連するログだけを抜き出して送る。


設計:

- pengu-press → Hermes, PengPeng のログ

- web-conversion → Rex, Sabine, Qui-Gon のログ

- motion-studio → Padme のログ

- revenue-ops, general → 全社ログ


Slack Bot(PenguLab Bot)を作成し、chat:writeとchannels:readスコープを付与した。Bot TokenをSlack APIから取得して.secrets/slack-webhooks.envに保存。


実行するとこんな感じで各チャンネルに投稿される。


📊 pengu-press 本日の日報

Hermes: PEN-38(ツール呼び出し改善)に着手中。6時間稼働。

PengPeng: 本日のX投稿スケジュール待機中。

要注意: Hermesの応答速度が昨日より15%低下。モデルの混雑が原因の可能性。

明日の優先タスク: PEN-38完了 + PEN-41の検証


---


osascriptで日本語が文字化けする問題


この日、記事のドラフトをファイルに書き出そうとして詰まった。


osascript(macOSのAppleScript実行コマンド)でHeredocを使って日本語を含むファイルを書こうとすると、文字化けする。


原因はエンコーディングの扱い。osascriptとシェルの間でUTF-8が正しく受け渡されない。


解決策として、Pythonスクリプト(.write-utf8.py)を経由する方法に切り替えた。


仕組み:

1. コンテンツをbase64エンコード

2. .write-utf8.pyがbase64デコードしてUTF-8でファイルに書き込む


少し手間だが、これで日本語ファイルが確実に書き出せる。一度仕組みを作れば再利用できる。


---


ドライランという設計


diary.pyとslack-report.pyには最初から--dry-runオプションを入れた。


本番投稿の前に「どんな文章が生成されるか」を確認できる。


自動投稿系のスクリプトは、一度動き出すと止めにくい。ドライランで事前確認できる設計にしておくのは、後悔しないための保険だ。


---


launchdへの登録(cron設定)


最後に、これをlaunchdで定期実行するための設定を残課題に入れた。


diary.pyは毎朝9時に実行、slack-report.pyは毎日18時に実行、という設定が理想だ。


これは次のセッションで実装する。


---


0人会社の情報発信戦略


この日の作業を通じて、0人会社の情報発信について考えた。


外部発信(X)の目的: Building in Publicとして、何を作っているかを見せる。フォロワーへの透明性。採用広報にもなる。


内部共有(Slack)の目的: 自分自身への日報。今日何が動いたか、どこで詰まっているかを毎日確認する。0人でもオペレーションの可視化は重要だ。


Note(このシリーズ)の目的: 詳細な技術ドキュメント。うまくいったことも詰まったことも、後で参照できる形で残す。


この3チャンネルを組み合わせることで、「誰もいないけど情報が流れている」状態を作れる。


---


まとめ


- X投稿 → diary.pyでヘルスログをClaude APIで変換→X APIで投稿

- Slack日報 → 部門別にフィルタリングしてBot投稿

- osascriptの日本語問題 → base64経由のPythonスクリプトで回避

- 自動化スクリプトには必ず--dry-runオプションを入れる


4日で0人会社のインフラが一通り動き始めた。エージェントが動き、ログが取れ、それが日報になって外に出ていく。


次は「このエージェントたちが実際にどれだけ仕事をしているか」の検証に入る。


---


PenguLab Building in Public シリーズ — Day 4

→ シリーズの続きはフォローして待ってください。毎日更新中。

いいなと思ったら応援しよう!