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
→ シリーズの続きはフォローして待ってください。毎日更新中。
