2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【APIキー不要】Claude Code + ShellScriptで、IT情報の収集・要約・Slack通知を「全自動化」した話

2
Posted at

はじめに

エンジニアの皆さん、日々の技術キャッチアップはどうしていますか?
Qiita、Zenn、X (Twitter)、TechCrunch... 巡回するサイトが多すぎて、「情報を追うだけで時間が溶ける」なんてことになっていないでしょうか。

今回は、Anthropicが提供するCLIツール 「Claude Code」 を活用して、以下のフローを全自動化する仕組みを作りました。

  1. 週3回、朝7時に自動起動(寝ている間に実行)
  2. ClaudeがWebを検索し、最新のITトレンド記事を収集
  3. 内容を要約し、重要度でフィルタリング
  4. Slack に通知(スマホでサクッと確認用)
  5. Obsidian に保存(ナレッジベース蓄積用)

APIキーの管理や複雑なPythonスクリプトは不要。Claude CodeのCLI機能とシェルスクリプトだけで実装した、"最強の自分専用ニュースフィード" の裏側を解説します。


成果物

📱 Slack通知

朝起きると、厳選された記事の要約が届いています。
URLのプレビュー崩れを防ぐため、専用のフォーマットで見やすく整形しています。

📘 Obsidian保存

ローカルのObsidianには、日付ごとのファイルとしてMarkdownが蓄積されます。
フロントマター付きなので、後からタグ検索やDataviewでの集計も可能です。


システム構成

「Claude Code」を単なるチャットツールとしてではなく、 「パイプラインの一部」 として組み込んでいるのが特徴です。

graph TD
Cron["cron (月水金 7:00)"] --> Script["weekly-it-news.sh"]

subgraph Pipeline ["Claude Code Pipeline"]
    Script -->|--print mode| ClaudeSearch["Claude (Web検索 & 整形)"]
    ClaudeSearch -->|WebSearch| Internet
    ClaudeSearch -->|stdout| RawOutput["整形済みテキスト"]
end

RawOutput -->|awk| Parser

subgraph Outputs
    Parser -->|Slack Section| ClaudeSlack["Claude (Slack投稿)"]
    ClaudeSlack -->|MCP| SlackApp["Slack #channel"]
    
    Parser -->|Obsidian Section| LocalFile["Obsidian (.md)"]
    Parser -->|URL Section| LogFile["重複チェック用ログ"]
end

技術スタック

技術 役割
Claude Code CLI 情報収集エンジン + Slack投稿エージェント
--print モード CLI出力をパイプラインで扱うためのモード
WebSearch Claude Code組み込みの検索ツール
Slack MCP slack_send_message による投稿
bash + awk 出力のパース・分割・制御
cron 定期実行トリガー

実装のポイント:Claude Codeの「2つのモード」使い分け

このシステムの肝は、Claude Codeを用途に合わせて2回呼び出している点です。

1回目:情報収集(--print モード)

claude --print --allowedTools 'WebSearch' << EOF > output.txt
(プロンプト:検索して、整形して出力して)
EOF

  • --print: 結果を標準出力 (stdout) に出すモード。これにより、出力をファイルに保存したり awk で加工したりできます。
  • --allowedTools 'WebSearch': 使えるツールを検索のみに制限し、余計な挙動(ファイル編集など)を防ぎます。
  • 注意点: このモードではMCPツール(Slack投稿など)は実行できません。あくまでテキスト生成用です。

2回目:Slack投稿(通常モード)

claude --allowedTools 'mcp__claude_ai_Slack__slack_send_message' --max-turns 3 << EOF
チャンネルID C0AEDCZAECB に投稿して
${SLACK_MESSAGE}
EOF

  • 通常モード: ここで初めてMCPツール(Slack)を実行させます。
  • --max-turns 3: 投稿→完了報告で終わるよう、無限ループを防止します。
  • チャンネルID指定: チャンネル名(#general等)だと解決に失敗することがあるため、ID(Cxxxx)を直接指定するのが安定のコツです。

プロンプトエンジニアリングの工夫

Claudeを「システムの一部」として安定動作させるために、プロンプトにはいくつかの魔術を仕込んでいます。

1. 「パイプラインの一部」であると宣言する

あなたはデータ収集パイプラインの一部です。人間と会話しているのではありません。
出力は必ず「---SLACK-FORMAT---」から開始してください。
挨拶、感想、まとめ、コメント等の余計なテキストは一切出力しないでください。

これを書かないと、CLAUDE.md で設定した性格(私の場合はギャル口調)が漏れ出し、収集結果の前に**「よっしゃ〜!いい記事見つけたで!」**のようなノイズが入ってパースに失敗します。

2. 年フィルターで「2026年問題」を防ぐ

単に「最新記事」と頼むと、SEOの強い数年前の記事を拾ってくることがあります。

- 投稿日: $(date +%Y) を基準に過去48時間以内のみ。
- 検索クエリに必ず「$(date +%Y)」を含めて、今年の記事に絞ること
- 重要な注意:$(date +%Y - 1)年以前の古い記事は絶対に含めない。

プロンプト内で date コマンドを展開し、年号を明示的に指定することで、情報の鮮度を担保しています。

3. セクション区切りで構造化する

1回の生成で3つの用途(Slack用、Obsidian用、ログ用)を出力させるため、独自の区切り文字を定義しています。

---SLACK-FORMAT---
(Slack用のmrkdwn)

---OBSIDIAN-FORMAT---
(Obsidian用のMarkdown)

---NEW-URLS---
(URL一覧)

これを awk で分割することで、APIコールを節約しつつ多目的な出力を得ています。


ハマりポイントと解決策

開発中にぶつかった壁とその乗り越え方です。

🤯 Slackの表示崩れ (mrkdwnの罠)

Slackの記法(mrkdwn)はMarkdownと微妙に異なります。
特にURLの扱いで、[タイトル](URL) 形式や、絵文字とURLを同じ行に書くと、Slackが勝手に <URL|タイトル> のように解釈しようとして表示が壊れることがありました。

👉 解決策
URLは必ず単独行に配置する。これだけでプレビューも綺麗に出るようになり、リンク切れも防げます。

📜 記事の質が低い

初期はQiitaのニッチな個人の備忘録ばかり拾ってしまうことがありました。

👉 解決策
「品質フィルター」をプロンプトに定義しました。

  • はてブ: 50以上
  • Qiita/Zenn: いいね10以上
  • X: いいね50以上
    ただし、「速報性が高い場合はこの限りではない」という注釈を入れることで、バズる前の最新ニュースも拾えるようにしています。

🛑 安全設計 (暴走防止)

自動実行スクリプトなので、安全性には気を使っています。

  • set -euo pipefail: エラーがあったら即停止。
  • Slack投稿失敗時: Slackへの投稿がコケても、Obsidianへの保存(ローカル処理)は続行するよう、エラーハンドリングを分離。
  • ツール制限: WebSearchSlack 以外のツール権限を剥奪し、意図しないファイル操作を防ぐ。

ソースコード全文

実際に使用しているシェルスクリプトです。パスなどは環境に合わせて書き換えてください。

weekly-it-news.sh (クリックして展開)
#!/bin/bash
set -euo pipefail

# ======================
# 設定エリア
# ======================
SLACK_CHANNEL_ID="C0AEDCZAECB" 
OBSIDIAN_DIR="$HOME/projects/IF-Vault/team/guchi/notes/IT-News"
LOG_FILE="$HOME/.claude-automation/processed-urls.log"

# Cron実行用PATH設定(which claudeの結果を含むように)
export PATH=$PATH:/usr/local/bin:/opt/homebrew/bin

mkdir -p "$OBSIDIAN_DIR" "$HOME/.claude-automation" "$HOME/logs"
touch "$LOG_FILE"

DATE=$(date +%Y-%m-%d)
CURRENT_YEAR=$(date +%Y)
LAST_YEAR=$((CURRENT_YEAR - 1))

# ======================
# プロンプト定義
# ======================
PROMPT=$(cat <<EOF
【役割】
あなたはIT情報収集パイプラインの一部です。余計な会話はせず、データのみを出力してください。

【タスク】
X(Twitter)、Qiita、Zenn、TechCrunchなどから最新のIT情報を検索してください。

【検索条件】
- 投稿日: ${DATE} を基準に過去48時間以内。
- キーワード: AI OR データベース OR クラウド OR IT OR "Claude Code" OR OpenClaw
- **重要**: 検索クエリに必ず「${CURRENT_YEAR}」を含めること。
- ${LAST_YEAR}年以前の記事は除外。

【除外URL】
$(tail -n 100 "$LOG_FILE")

【出力フォーマット】
以下のセクション区切りを使用し、3つのパートを出力してください。

---SLACK-FORMAT---
📰 *IT情報収集 - $(date +%Y/%m/%d)*
新着記事 5件
━━━━━━━━━━━━━━━━━━━━
*1. [タイトル]*
\`Category\` | Source | YYYY-MM-DD
• 要約ポイント1
• 要約ポイント2
URL

---OBSIDIAN-FORMAT---
### 1. タイトル
- **URL**: URL
- **ソース**: Source
- **カテゴリ**: Category
- **要約**: ...

---NEW-URLS---
URL1
URL2
...
EOF
)

# ======================
# 実行処理
# ======================
OUTPUT_FILE=$(mktemp)
trap 'rm -f "$OUTPUT_FILE"' EXIT

# 1. 情報収集 (--printモード)
claude --print --allowedTools 'WebSearch' "$PROMPT" > "$OUTPUT_FILE"

# 2. Slack投稿 (通常モード)
SLACK_CONTENT=$(awk '/---SLACK-FORMAT---/{flag=1;next}/---OBSIDIAN-FORMAT---/{flag=0}flag' "$OUTPUT_FILE")

if [ -n "$SLACK_CONTENT" ]; then
    claude --allowedTools 'mcp__claude_ai_Slack__slack_send_message' --max-turns 3 << SLACK_EOF > /dev/null 2>&1
以下の内容をSlackのチャンネルID ${SLACK_CHANNEL_ID} に投稿してください。
編集せずそのまま投稿すること。

${SLACK_CONTENT}
SLACK_EOF
fi

# 3. Obsidian保存 & ログ更新
# (省略: awkで抽出してファイル書き出し)
# ...


⚠️ 【重要】macOS Cron設定の落とし穴

ここが最大の難関です。macOS (Catalina以降) でCronを動かすには、以下の2つの設定が必須です。これをやらないと動きません。

1. 初回の手動実行と認証

スクリプトをCronに登録する前に、必ずターミナルで一度手動実行してください。

bash ~/scripts/weekly-it-news.sh

Claude CodeとSlack MCPの連携には、初回のみブラウザ経由での認証(OAuth)が必要です。これを済ませておかないと、Cronが認証画面を出せずにエラーになります。

2. フルディスクアクセスの許可

macOSのセキュリティ機能により、cron から Documents フォルダ(Obsidian)への書き込みがブロックされることがあります。

  1. 「システム設定」「プライバシーとセキュリティ」「フルディスクアクセス」 を開く。
  2. リストの下にある 「+」 ボタンを押す。
  3. Command + Shift + G を押し、/usr/sbin/cron と入力して移動。
  4. cron を選択して追加し、スイッチを ON にする。

3. Cronの設定

crontab -e で設定しますが、PATH を明示的に通すのが安全です。

# 月水金の朝7時に実行
0 7 * * 1,3,5 export PATH=$PATH:/usr/local/bin:/opt/homebrew/bin; /bin/bash $HOME/scripts/weekly-it-news.sh >> $HOME/logs/it-news-$(date +\%Y-\%m).log 2>&1


まとめ

Claude Codeを使うことで、従来の「Pythonでスクレイピングして、APIを叩いて…」という面倒な実装が、 「自然言語で指示して、パイプで繋ぐ」 というシンプルな形に昇華されました。

コスト:

  • Claude Code CLI (Pro/Teamプラン内)
  • Slack MCP (無料)
  • サーバー代 (ローカルMac + cronなので無料)

「週3回、勝手に情報が集まってくる」体験は、一度味わうと戻れません。
ぜひ皆さんも、自分専用の全自動情報収集エージェントを作ってみてください!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?