Reddit ICP モニター は何をしますか?
サブレディットを監視して、あなたが解決する問題を説明している人々を見つけます。関連性をスコアリングし、各マッチに対して役立つ返信を下書きします。
重要なルール: 投稿URL、タイトル、または内容を決してでっち上げないでください。出力内のすべての投稿はRedditの検索結果から取得されたものでなければなりません。結果がないセクションは「一致するものは見つかりませんでした」とマークしてください。検索で返されなかった投稿に対して返信を下書きしないでください。
スパム防止ルール: 下書きされた返信では、投稿が明示的にツール推薦を求めていない限り、製品名や会社名を決して言及してはいけません。マーケターではなく、実務者のように見せてください。
ステップ 1: セットアップ確認
echo "GEMINI_API_KEY: ${GEMINI_API_KEY:+set}"
echo "REDDIT_CLIENT_ID: ${REDDIT_CLIENT_ID:-未設定、パブリックエンドポイントを使用 (10 RPM)}"
GEMINI_API_KEY がない場合: 停止してください。ユーザーに「GEMINI_API_KEY が必要です。aistudio.google.com から取得し、.env ファイルに追加してください。」と伝えてください。
Reddit認証情報がない場合: 続行してください。RedditのパブリックJSONエンドポイントを使用します(認証不要、10 RPM制限)。通常、3〜6のサブレディット検索の監視セッションではこれで十分です。
REDDIT_CLIENT_ID が設定されている場合: OAuthを使用して60 RPMで実行します。最初にトークンを取得してください:
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 が見つかりました" || echo "icp が見つかりません"
docs/icp.md が存在する場合: 読み込んで、以下を抽出します:
product: 1文の製品説明pain_points: ペインポイントフレーズのリスト(購入者の実際の言葉)anti_keywords: 投稿を無効にするフレーズsubreddits: 検索するサブレディットのリスト
docs/icp.md が存在しない場合: 以下の3つの質問をしてください。3つすべてに回答されるまで先に進まないでください。
- あなたの製品は何をしますか?(1文で)
- あなたの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件の場合:それをメモし、続行する。停止しない
スコアリング前に候補の総数を報告:「X 件の候補投稿が Y 個のサブレディットで見つかりました。」
ステップ 4: Gemini で関連性をスコアリング
すべての候補投稿とICPコンテキストを一時ファイルに書き込み、スコアリングします:
cat > /tmp/reddit-score-request.json << 'ENDJSON'
{
"system_instruction": {
"parts": [{
"text": "あなたは、特定の製品が解決するまさにそのペインポイントを誰かが経験しているReddit投稿を特定するGTMアナリストです。提供された各投稿に対して、以下のフィールドを持つJSONオブジェクトを出力してください:id(投稿ID)、score(整数1〜5)、reason(スコアを説明する1文)。スコアリング基準:5=その人が明らかに問題を抱えており、積極的に助けを求めているか、その問題について不満を述べている;4=強いシグナル、問題は存在するがそれほど明示的ではない;3=可能性あり、不確か;2=関連はあるが核心的な痛みではない;1=無関係。スコアオブジェクトのJSON配列のみを出力してください。配列の前後にコメントを付けないでください。"
}]
},
"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 の投稿のみを保持します。
「X 件の投稿がスコア4または5でした。返信を下書きしています。」と報告します。
0件の投稿がスコア >= 4 の場合:ステップ7の結果ゼロメッセージを出力し、停止します。空の返信を下書きしないでください。
ステップ 5: Gemini で返信を下書き
下書きの前に references/reply-rules.md を読んでください。各高スコア投稿の投稿タイプ(モード1、2、または3)を判定し、そのモードをGeminiに渡します。
スコア >= 4 の各投稿に対して、返信を下書きします(セッションあたり最大5件の返信):
cat > /tmp/reddit-reply-request.json << 'ENDJSON'
{
"system_instruction": {
"parts": [{
"text": "あなたはこのReddit投稿で説明されているまさにその問題を個人的に解決した実務者です。役立つ返信を書いてください。その返信は:(1) その人が尋ねたことや不満に思っていることに直接答える、(2) 実際の経験から得た具体的で有用な洞察を共有する、(3) 投稿が明示的にツール推薦を求めていない限り、製品、ツール、または会社名を名前で言及しない、(4) 2〜5文で、ヘッダーや箇条書きのない平易な会話調の散文で書く、(5) オプションで、会話を続けるためのプレッシャーの少ない招待で終わる。マーケティング用語を使用しないでください。次の言葉を使用しないでください:game-changer、best-in-class、streamline、transform、revolutionize、leverage、seamless、robust、comprehensive、innovative。本物の人のように振る舞ってください。"
}]
},
"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:どのように対処するか、モード3:ツール推薦)
- 製品説明(Geminiがモード1/2で名前を避けるために)
- モード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 モニター — [YYYY-MM-DD]
**監視したサブレディット:** r/[subreddit1], r/[subreddit2]
**時間枠:** 過去7日間
**検索したキーワード:** [phrase1], [phrase2], [phrase3]
**見つかった候補:** X 件の投稿
**高シグナルマッチ (スコア 4-5):** Y 件の投稿
---
### マッチ 1 — スコア [N]/5
**投稿:** [title](url)
**サブレディット:** r/[subreddit] | [N] アップボート | [N] コメント
**シグナル引用:** 「[投稿本文からの関連引用]」
**マッチしたキーワード:** [phrase]
**投稿タイプ:** モード [1/2/3]
**下書きした返信:**
[reply text]
**返信の単語数:** N ワード
---
[各マッチについて繰り返し]
---
**結果が0件のサブレディット:** [何も返さなかったものをリスト]
0件の投稿がスコア >= 4 の場合: 「過去7日間、[サブレディット] で高シグナルのマッチは見つかりませんでした。検索したキーワード:[リスト]。時間枠を広げるか(「先月」と言って再実行)、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 "$OUTFILE に保存しました"