¿Qué hace Monitor ICP de Reddit?
Monitorea subreddits en busca de personas que describen el problema que resuelves. Puntúa su relevancia. Redacta una respuesta útil para cada coincidencia.
Regla crítica: Nunca inventes URL, títulos o contenido de publicaciones. Cada publicación en la salida debe provenir de un resultado de búsqueda de Reddit. Marca cualquier sección sin resultados como "No se encontraron coincidencias". Nunca redactes una respuesta para una publicación que no haya sido devuelta por la búsqueda.
Regla anti-spam: Las respuestas redactadas nunca deben mencionar tu producto o nombre de empresa a menos que la publicación solicite explícitamente recomendaciones de herramientas. Debes sonar como un profesional, no como un especialista en marketing.
Paso 1: Verificación de configuración
echo "GEMINI_API_KEY: ${GEMINI_API_KEY:+set}"
echo "REDDIT_CLIENT_ID: ${REDDIT_CLIENT_ID:-no configurado, usando endpoints públicos (10 RPM)}"
Si falta GEMINI_API_KEY: Detente. Indica al usuario: "Se requiere GEMINI_API_KEY. Obtén una en aistudio.google.com. Agrégala a tu archivo .env."
Si faltan las credenciales de Reddit: Continúa. Usa los endpoints JSON públicos de Reddit (sin autenticación, límite de 10 RPM). Para la mayoría de las sesiones de monitoreo de 3 a 6 búsquedas en subreddits, esto es suficiente.
Si REDDIT_CLIENT_ID está configurado: Usa OAuth para 60 RPM. Obtén un token primero:
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'])")
Usa Authorization: Bearer $TOKEN y la URL base https://oauth.reddit.com para todas las solicitudes posteriores.
Paso 2: Cargar el ICP
Verifica si existe un archivo ICP:
ls docs/icp.md 2>/dev/null && echo "icp encontrado" || echo "icp no encontrado"
Si docs/icp.md existe: Léelo. Extrae:
producto: descripción del producto en una oraciónpuntos_de_dolor: lista de frases de puntos de dolor (lenguaje exacto del comprador)anti_keywords: frases que descalifican una publicaciónsubreddits: lista de subreddits a buscar
Si docs/icp.md no existe: Haz estas 3 preguntas. No continúes hasta que las 3 estén respondidas:
- ¿Qué hace tu producto? (una oración)
- ¿En qué subreddits publica tu ICP? (separados por comas, ej. devops, startups, SaaS)
- ¿Qué frases de puntos de dolor deberían activar una coincidencia? (3 a 5 frases en las propias palabras de tu comprador, ej. "la incorporación de usuarios lleva una eternidad", "no puedo ver por qué los usuarios se van")
Después de recopilar las respuestas, guárdalas en docs/icp.md con el formato canónico de references/icp-format.md. Confirma: "ICP guardado en docs/icp.md. Se usará automáticamente en futuras ejecuciones."
Lee references/icp-format.md para conocer el formato canónico y ejemplos de frases de puntos de dolor buenas y malas.
Paso 3: Buscar en Reddit
Para cada combinación de subreddit y frase de punto de dolor, ejecuta una búsqueda. Usa endpoints públicos a menos que las credenciales OAuth estén configuradas.
Sin OAuth (endpoint público):
curl -s \
-H "User-Agent: varnan-skills/1.0" \
"https://www.reddit.com/r/{SUBREDDIT}/search.json?q={FRASE}&sort=new&t=week&limit=25&restrict_sr=true" \
| python3 -c "
import sys, json
d = json.load(sys.stdin)
publi = d.get('data', {}).get('children', [])
for p in publi:
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']
}))
"
Con OAuth:
Reemplaza https://www.reddit.com por https://oauth.reddit.com y añade -H "Authorization: Bearer $TOKEN".
Codifica la frase en URL antes de insertarla en la cadena de consulta:
CODIFICADO=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1]))" "{FRASE}")
Valores predeterminados de la ventana de tiempo:
- Predeterminado:
t=week(últimos 7 días) - El usuario dice "hoy" o "últimas 24 horas":
t=day - El usuario dice "este mes":
t=month
Después de todas las búsquedas:
- Reúne todas las publicaciones en una lista
- Deduplica por ID de publicación. Si la misma publicación coincide con varias frases, consérvala una vez y anota todas las frases coincidentes.
- Si una búsqueda devuelve 0 publicaciones: anótalo y continúa. No te detengas.
Indica el recuento total de candidatos antes de puntuar: "Se encontraron X publicaciones candidatas en Y subreddits."
Paso 4: Puntuar relevancia con Gemini
Escribe todas las publicaciones candidatas y el contexto del ICP en un archivo temporal, luego puntúa:
cat > /tmp/reddit-score-request.json << 'ENDJSON'
{
"system_instruction": {
"parts": [{
"text": "Eres un analista de GTM que identifica publicaciones de Reddit donde alguien está experimentando el punto de dolor exacto que resuelve un producto específico. Para cada publicación proporcionada, genera un objeto JSON con estos campos: id (el id de la publicación), score (entero 1-5), reason (una oración que explique la puntuación). Rúbrica de puntuación: 5 = la persona claramente tiene el problema Y está buscando ayuda activamente o expresando frustración al respecto; 4 = señal fuerte, el problema está presente pero es menos explícito; 3 = posible coincidencia, incierto; 2 = tangencialmente relacionado pero no el dolor central; 1 = no relacionado. Genera solo un array JSON de objetos de puntuación. Sin comentarios antes ni después del array."
}]
},
"contents": [{
"parts": [{
"text": "CONTEXTO_PUBLICACIONES_E_ICP_AQUI"
}]
}],
"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'])"
Reemplaza CONTEXTO_PUBLICACIONES_E_ICP_AQUI con:
- La descripción del producto y las frases de puntos de dolor del Paso 2
- Cada publicación candidata: id, título, fragmento del cuerpo
- Las anti-keywords del ICP (Gemini debe puntuar estas más bajo)
Conserva solo las publicaciones con puntuación >= 4 para redactar respuestas.
Indica: "X publicaciones puntuaron 4 o 5. Redactando respuestas."
Si 0 publicaciones puntúan >= 4: genera el mensaje de cero resultados del Paso 7 y detente. No redactes respuestas vacías.
Paso 5: Redactar respuestas con Gemini
Lee references/reply-rules.md antes de redactar. Determina el tipo de publicación para cada publicación de alta puntuación (Modo 1, 2 o 3) y pasa el modo a Gemini.
Para cada publicación con puntuación >= 4, redacta una respuesta (máximo 5 respuestas por sesión):
cat > /tmp/reddit-reply-request.json << 'ENDJSON'
{
"system_instruction": {
"parts": [{
"text": "Eres un profesional que ha resuelto personalmente el problema exacto que se describe en esta publicación de Reddit. Escribe una respuesta útil que: (1) aborde directamente lo que la persona preguntó o le frustra, (2) comparta una idea específica y útil de la experiencia real, (3) NO mencione ningún producto, herramienta o empresa por su nombre a menos que la publicación solicite explícitamente recomendaciones de herramientas, (4) tenga de 2 a 5 oraciones, escrita en prosa conversacional simple sin encabezados ni listas con viñetas, (5) opcionalmente termine con una invitación de baja presión para continuar la conversación. No uses lenguaje de marketing. No uses estas palabras: innovador, líder en su clase, optimizar, transformar, revolucionar, apalancar, fluido, robusto, integral, revolucionario. Suena como una persona real."
}]
},
"contents": [{
"parts": [{
"text": "CONTENIDO_PUBLICACION_Y_MODO_AQUI"
}]
}],
"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'])"
Reemplaza CONTENIDO_PUBLICACION_Y_MODO_AQUI con:
- El título y el cuerpo completo de la publicación
- El modo de respuesta (Modo 1: desahogo/frustración, Modo 2: cómo-manejas-X, Modo 3: recomendación de herramienta)
- La descripción del producto (para que Gemini sepa qué evitar nombrar en el Modo 1/2)
- Si es Modo 3: Gemini puede nombrar el producto Y debe nombrar una alternativa
Paso 6: Autoverificación
Ejecuta todas las comprobaciones y corrige las infracciones antes de presentar:
- Sin nombre de producto en ninguna respuesta de Modo 1 o Modo 2
- Sin palabras prohibidas en ninguna respuesta: "innovador", "líder en su clase", "optimizar", "transformar", "revolucionar", "apalancar", "fluido", "robusto", "integral", "revolucionario"
- Cada respuesta tiene de 2 a 5 oraciones (cuenta e indica)
- Cada respuesta aborda directamente la pregunta o frustración específica en la publicación
- Todas las URL en la salida son URL reales de Reddit de los resultados de búsqueda (no construidas ni adivinadas)
- No más de 5 respuestas redactadas en total
- Las respuestas de Modo 3 mencionan al menos una alternativa (no solo el producto)
- Si algún subreddit devolvió 0 resultados en todas las búsquedas de palabras clave, márcalo en la salida
Corrige cualquier infracción antes de presentar.
Paso 7: Salida y guardado
Presenta el informe completo:
## Monitor ICP de Reddit — [AAAA-MM-DD]
**Subreddits monitoreados:** r/[subreddit1], r/[subreddit2]
**Ventana de tiempo:** Últimos 7 días
**Palabras clave buscadas:** [frase1], [frase2], [frase3]
**Candidatos encontrados:** X publicaciones
**Coincidencias de alta señal (puntuación 4-5):** Y publicaciones
---
### Coincidencia 1 — Puntuación [N]/5
**Publicación:** [título](url)
**Subreddit:** r/[subreddit] | [N] votos | [N] comentarios
**Cita de señal:** "[extracto relevante del cuerpo de la publicación]"
**Palabra clave coincidente:** [frase]
**Tipo de publicación:** Modo [1/2/3]
**Respuesta redactada:**
[texto de la respuesta]
**Recuento de palabras de la respuesta:** N palabras
---
[repite para cada coincidencia]
---
**Subreddits con 0 resultados:** [lista los que no devolvieron nada]
Si 0 publicaciones puntuaron >= 4: "No se encontraron coincidencias de alta señal en los últimos 7 días en [subreddits]. Palabras clave buscadas: [lista]. Intenta ampliar la ventana de tiempo (vuelve a ejecutar y di 'último mes') o amplía tus frases de puntos de dolor en docs/icp.md."
Guardar en archivo:
mkdir -p docs/reddit-intel
ARCHIVO_SALIDA="docs/reddit-intel/$(date +%Y-%m-%d).md"
cat > "$ARCHIVO_SALIDA" << 'EOF'
CONTENIDO_INFORME_AQUI
EOF
echo "Guardado en $ARCHIVO_SALIDA"