reddit-icp-monitor について
reddit-icp-monitorは、顧客候補の課題を述べたReddit投稿を探し、関連度を評価して返信案を作るスキルです。ICPファイルに基づいて検索し、投稿の捏造や求められていない宣伝を防ぎます。
主な機能
- 01課題フレーズでサブレディットを検索
- 02ICPファイルに基づく投稿の照合
- 03Geminiによる候補投稿の評価
- 04最大5件の返信案を作成・確認
- 05日付入りの監視レポートを保存
活用シーン
- 01顧客の課題に関する最近の投稿を探す
- 02選択したコミュニティの関連投稿を絞り込む
- 03有望な投稿への非宣伝的な返信を準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ varnan-tech/ opendirectory --skill reddit-icp-monitorインストール後、Claude Code で/reddit-icp-monitorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.env.exampleREADME.mdevals/evals.jsonreferences/icp-format.mdreply-rules.md詳細
Reddit ICP モニター
解決する課題について投稿している人をサブレディットで見つけます。関連性を評価し、一致した投稿ごとに役立つ返信の下書きを作成します。
重要なルール: 投稿の URL、タイトル、内容を決して捏造しないでください。出力する投稿はすべて Reddit の検索結果に含まれている必要があります。結果がないセクションには「一致する投稿は見つかりませんでした」と記載してください。検索結果に含まれていない投稿への返信は、決して作成しないでください。
スパム対策ルール: 投稿でツールのおすすめを明示的に求めている場合を除き、作成する返信で自社の製品名や会社名に言及してはいけません。マーケターではなく、実務者らしい口調にしてください。
ステップ 1:セットアップの確認
echo "GEMINI_API_KEY: ${GEMINI_API_KEY:+set}"
echo "REDDIT_CLIENT_ID: ${REDDIT_CLIENT_ID:-not set, using public endpoints (10 RPM)}"
GEMINI_API_KEY が設定されていない場合: 停止します。ユーザーに次のように伝えてください:「GEMINI_API_KEY が必要です。aistudio.google.com で取得してください。.env ファイルに追加してください。」
Reddit の認証情報がない場合: 続行します。Reddit の公開 JSON エンドポイントを使用します(認証不要、10 RPM 制限)。サブレディットを 3~6 件検索する一般的なモニタリングでは、これで十分です。
REDDIT_CLIENT_ID が設定されている場合: 60 RPM の OAuth を使用します。最初にトークンを取得してください:
TOKEN=$(curl -s -X POST \
-d "grant_type=password&username=$REDDIT_USERNAME&password=$REDDIT_PASSWORD" \
--user "$REDDIT_CLIENT_ID:$REDDIT_CLIENT_SECRET" \
-H "User-Agent: varnan-skills/1.0" \
https://www.reddit.com/api/v1/access_token \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
以降のすべてのリクエストで Authorization: Bearer $TOKEN と https://oauth.reddit.com のベース URL を使用してください。
ステップ 2:ICP を読み込む
既存の ICP ファイルがあるか確認します:
ls docs/icp.md 2>/dev/null && echo "icp found" || echo "icp missing"
docs/icp.md が存在する場合: 読み込み、以下を抽出します:
product:製品を一文で説明したものpain_points:課題を表すフレーズのリスト(購入者が実際に使う表現)anti_keywords:投稿を対象外とするフレーズsubreddits:検索するサブレディットのリスト
docs/icp.md が存在しない場合: 次の 3 つの質問をします。3 つすべてに回答があるまで先に進まないでください:
- 製品は何をしますか?(一文)
- ICP はどのサブレディットに投稿しますか?(カンマ区切り。例:devops、startups、SaaS)
- どのような課題を表すフレーズを一致条件にしますか?(購入者自身が使う言葉で 3~5 個。例:「オンボーディングに時間がかかりすぎる」「ユーザーがなぜ解約するのか分からない」)
回答がそろったら、references/icp-format.md の標準形式で docs/icp.md に保存します。次のように確認してください:「ICP を docs/icp.md に保存しました。今後の実行では自動的に使用されます。」
標準形式と、良い課題表現・悪い課題表現の例については references/icp-format.md を読んでください。
ステップ 3:Reddit を検索する
サブレディットと課題を表すフレーズの組み合わせごとに、検索を 1 回実行します。OAuth の認証情報が設定されていない場合は公開エンドポイントを使用してください。
OAuth なし(公開エンドポイント):
curl -s \
-H "User-Agent: varnan-skills/1.0" \
"https://www.reddit.com/r/{SUBREDDIT}/search.json?q={PHRASE}&sort=new&t=week&limit=25&restrict_sr=true" \
| python3 -c "
import sys, json
d = json.load(sys.stdin)
posts = d.get('data', {}).get('children', [])
for p in posts:
data = p['data']
print(json.dumps({
'id': data['id'],
'title': data['title'],
'body': data.get('selftext', '')[:600],
'url': 'https://reddit.com' + data['permalink'],
'score': data['score'],
'comments': data['num_comments'],
'subreddit': data['subreddit'],
'created_utc': data['created_utc']
}))
"
OAuth ありの場合:
https://www.reddit.com を https://oauth.reddit.com に置き換え、-H "Authorization: Bearer $TOKEN" を追加します。
クエリ文字列に挿入する前に、フレーズを URL エンコードします:
ENCODED=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" "{PHRASE}")
期間のデフォルト設定:
- デフォルト:
t=week(過去 7 日間) - ユーザーが「今日」または「過去 24 時間」と指定した場合:
t=day - ユーザーが「今月」と指定した場合:
t=month
すべての検索が終わったら:
- すべての投稿を 1 つのリストにまとめます
- 投稿 ID で重複を除外します。同じ投稿が複数のフレーズに一致する場合は 1 件だけ残し、一致したフレーズをすべて記載します。
- 検索結果が 0 件の場合は、その旨を記録して続行します。停止しないでください。
スコア付けの前に、候補の総数を次の形式で伝えます:「Y 件のサブレディットから X 件の候補投稿が見つかりました。」
ステップ 4:Gemini で関連性を評価する
すべての候補投稿と ICP のコンテキストを一時ファイルに書き込み、スコアを付けます:
cat > /tmp/reddit-score-request.json << 'ENDJSON'
{
"system_instruction": {
"parts": [{
"text": "You are a GTM analyst identifying Reddit posts where someone is experiencing the exact pain point that a specific product solves. For each post provided, output a JSON object with these fields: id (the post id), score (integer 1-5), reason (one sentence explaining the score). Scoring rubric: 5 = person clearly has the problem AND is actively seeking help or venting frustration about it; 4 = strong signal, problem is present but less explicit; 3 = possible match, uncertain; 2 = tangentially related but not the core pain; 1 = unrelated. Output only a JSON array of score objects. No commentary before or after the array."
}]
},
"contents": [{
"parts": [{
"text": "POSTS_AND_ICP_CONTEXT_HERE"
}]
}],
"generationConfig": {
"temperature": 0.2,
"maxOutputTokens": 2048
}
}
ENDJSON
curl -s -X POST \
"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d @/tmp/reddit-score-request.json \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d['candidates'][0]['content']['parts'][0]['text'])"
POSTS_AND_ICP_CONTEXT_HERE を以下の内容に置き換えます:
- ステップ 2 の製品説明と課題を表すフレーズ
- 各候補投稿の ID、タイトル、本文の抜粋
- ICP の対象外キーワード(Gemini がこれらの投稿に低いスコアを付けるようにします)
返信の下書き作成には、スコアが 4 以上の投稿のみを残します。
次のように伝えます:「スコアが 4 または 5 の投稿は X 件です。返信を作成します。」
スコアが 4 以上の投稿が 0 件の場合は、ステップ 7 の結果なしメッセージを出力して停止します。空の返信を作成しないでください。
ステップ 5:Gemini で返信を作成する
返信を作成する前に、references/reply-rules.md を読んでください。スコアの高い投稿ごとに投稿タイプ(モード 1、2、または 3)を判定し、そのモードを Gemini に渡します。
スコアが 4 以上の投稿ごとに返信を作成します(1 セッションあたり最大 5 件の返信):
cat > /tmp/reddit-reply-request.json << 'ENDJSON'
{
"system_instruction": {
"parts": [{
"text": "You are a practitioner who has personally solved the exact problem being described in this Reddit post. Write a helpful reply that: (1) directly addresses what the person asked or is frustrated about, (2) shares a specific, useful insight from real experience, (3) does NOT mention any product, tool, or company by name unless the post explicitly asks for tool recommendations, (4) is 2-5 sentences, written in plain conversational prose with no headers or bullet lists, (5) optionally ends with a low-pressure invitation to continue the conversation. Do not use marketing language. Do not use these words: game-changer, best-in-class, streamline, transform, revolutionize, leverage, seamless, robust, comprehensive, innovative. Sound like a real person."
}]
},
"contents": [{
"parts": [{
"text": "POST_CONTENT_AND_MODE_HERE"
}]
}],
"generationConfig": {
"temperature": 0.7,
"maxOutputTokens": 512
}
}
ENDJSON
curl -s -X POST \
"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d @/tmp/reddit-reply-request.json \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d['candidates'][0]['content']['parts'][0]['text'])"
POST_CONTENT_AND_MODE_HERE を次の内容に置き換えます。
- 投稿のタイトルと本文全体
- 返信モード(モード 1:愚痴・不満、モード 2:X をどう扱っていますか、モード 3:ツールの推奨)
- 製品の説明(モード 1/2 では Gemini が製品名を挙げないようにするため)
- モード 3 の場合:Gemini は製品名を挙げてもかまいませんが、代替案を 1 つ挙げる必要があります
ステップ 6:セルフ QA
すべてのチェックを実行し、違反があれば提示前に修正します。
- モード 1 またはモード 2 の返信に製品名が含まれていない
- 返信に禁止語が含まれていない:「game-changer」、「best-in-class」、「streamline」、「transform」、「revolutionize」、「leverage」、「seamless」、「robust」、「innovative」
- 各返信が 2〜5 文である(文数を数えて明記する)
- 各返信が投稿内の具体的な質問や不満に直接答えている
- 出力内の URL はすべて検索結果にある実在の Reddit URL である(作成または推測したものではない)
- 作成した返信が合計 5 件を超えていない
- モード 3 の返信では、製品だけでなく代替案も少なくとも 1 つ挙げている
- いずれかのサブレディットで、すべてのキーワード検索を通じて検索結果が 0 件だった場合は、出力内でその旨を明記する
提示前に違反を修正します。
ステップ 7:出力して保存する
レポート全体を提示します。
## Reddit ICP Monitor — [YYYY-MM-DD]
**Subreddits monitored:** r/[subreddit1], r/[subreddit2]
**Time window:** Last 7 days
**Keywords searched:** [phrase1], [phrase2], [phrase3]
**Candidates found:** X posts
**High-signal matches (score 4-5):** Y posts
---
### Match 1 — Score [N]/5
**Post:** [title](url)
**Subreddit:** r/[subreddit] | [N] upvotes | [N] comments
**Signal quote:** "[relevant excerpt from post body]"
**Matched keyword:** [phrase]
**Post type:** Mode [1/2/3]
**Drafted reply:**
[reply text]
**Reply word count:** N words
---
[repeat for each match]
---
**Subreddits with 0 results:** [list any that returned nothing]
スコアが 4 以上の投稿が 0 件の場合: 「過去 7 日間、[subreddits] で有力な一致は見つかりませんでした。検索したキーワード:[list]。期間を広げる(再実行して『last month』と指定する)か、docs/icp.md の課題を表すフレーズをより広い表現にしてみてください。」
ファイルに保存:
mkdir -p docs/reddit-intel
OUTFILE="docs/reddit-intel/$(date +%Y-%m-%d).md"
cat > "$OUTFILE" << 'EOF'
REPORT_CONTENT_HERE
EOF
echo "Saved to $OUTFILE"