Detección de spam
La detección de spam de Discuse clasifica un texto como spam o no, con una puntuación de confianza. Envía el texto a POST https://api.discuse.com/api/v2/check con check_spam activado y lee el veredicto en results.spamfinder. Detecta spam promocional, estafas y ruido generado por bots que los filtros simples por palabras clave suelen pasar por alto.
¿Qué detecta la detección de spam?
El modelo está entrenado con patrones de alto volumen que evaden las listas de bloqueo:
- Spam promocional y publicidad no solicitada
- Mensajes de estafa y phishing
- Contenido generado por bots y copiado y pegado
Devuelve un único label (como spam o ham) junto con una puntuación de confidence, para que puedas decidir qué tan estricto quieres ser.
¿Cómo ejecuto una comprobación de spam?
curl -X POST https://api.discuse.com/api/v2/check \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"content": {
"text": "CONGRATULATIONS! You won $10,000! Click here to claim: bit.ly/fake"
},
"settings": {
"check_spam": true
}
}'
Formato de respuesta
{
"has_violations": true,
"cached": false,
"message": "Spam content detected",
"results": {
"hits": true,
"spamfinder": {
"text": "CONGRATULATIONS! You won $10,000! Click here to claim: bit.ly/fake",
"label": "spam",
"confidence": 0.97,
"is_spam": true,
"hit": true
}
},
"usage": {
"api_requests_used": 8,
"api_requests_limit": 5000,
"api_requests_remaining": 4992
}
}
¿Qué campos devuelve el resultado de spam?
| Campo | Tipo | Significado |
|---|---|---|
text |
string | El texto que se clasificó |
label |
string | Clasificación del modelo (p. ej., spam, ham) |
confidence |
number | Confianza del modelo en la etiqueta (0.0–1.0) |
is_spam |
bool | Veredicto bruto del modelo: label == spam, sin tener en cuenta el umbral |
hit |
bool | Decisión con umbral: is_spam Y confidence ≥ el umbral de spam de tu proyecto |
is_spam frente a hit
is_spam es el veredicto bruto: el modelo etiquetó el texto como spam independientemente de cuánta confianza tuviera. hit exige además que la confianza supere el umbral de spam configurado en tu proyecto. Basa las acciones de moderación en hit, no en is_spam, para que una etiqueta de spam con baja confianza no penalice un mensaje dudoso.
¿Cómo interpreto la puntuación de confianza?
confidence refleja qué tan seguro está el modelo de su label:
- 0.0 – 0.3: muy baja — probablemente legítimo.
- 0.3 – 0.5: baja — caso límite.
- 0.5 – 0.7: moderada — sospechoso.
- 0.7 – 0.9: alta — muy probablemente spam.
- 0.9 – 1.0: muy alta — casi con certeza spam.
Umbrales recomendados
Configura el umbral de spam de tu proyecto según la tolerancia de tu plataforma:
const SPAM_THRESHOLDS = {
strict: 0.5, // professional platforms, financial services
standard: 0.7, // social media, forums
permissive: 0.85 // creative platforms, open communities
};
Casos de uso
Secciones de comentarios
async function moderateComment(comment) {
const result = await checkSpam(comment.text);
const spam = result.results.spamfinder;
if (spam.hit) {
if (spam.confidence > 0.9) {
return { action: 'reject', reason: 'spam_detected' };
}
return { action: 'review', reason: 'possible_spam' };
}
return { action: 'approve' };
}
Registro de usuarios
def validate_registration(user_data):
bio = user_data.get('bio')
if bio:
result = check_spam(bio)
if result['results']['spamfinder']['hit']:
return {'approved': False, 'reason': 'Spam content detected in profile'}
return {'approved': True}
Plataformas de mensajería
async function filterMessage(message, sender) {
const result = await checkSpam(message.text);
const spam = result.results.spamfinder;
if (spam.hit) {
await incrementSpamCount(sender.id);
const spamCount = await getSpamCount(sender.id);
if (spamCount > 3) {
await banUser(sender.id, 'repeated_spam');
}
return { delivered: false, reason: 'Message filtered as spam' };
}
return { delivered: true };
}
Combinar con otras comprobaciones
Ejecuta la comprobación de spam junto con sentimiento e idioma en una sola solicitud:
{
"content": {
"text": "Check out this amazing deal! Click here: example.com/offer"
},
"settings": {
"check_spam": true,
"check_sentiment": true,
"check_language": true
}
}
La respuesta incluirá results.spamfinder, results.sentiment y results.language juntos.
Buenas prácticas
Usa respuestas graduadas
En lugar de bloquear/permitir de forma binaria, ramifica según la confianza:
function handleSpamResult(spam) {
if (!spam.hit) return 'allow';
if (spam.confidence > 0.95) return 'silent_delete';
if (spam.confidence > 0.8) return 'block_notify';
if (spam.confidence > 0.6) return 'flag_for_review';
return 'apply_friction';
}
Haz seguimiento de infractores reincidentes
async function assessUser(userId, spam) {
if (spam.hit) {
await incrementUserSpamScore(userId, spam.confidence);
}
const userScore = await getUserSpamScore(userId);
if (userScore > 10.0) await autoSuspendUser(userId);
else if (userScore > 5.0) await flagForManualReview(userId);
}
Incluye usuarios de confianza en una lista blanca
Omite la comprobación de spam para cuentas verificadas o de alta confianza a fin de reducir falsos positivos y ahorrar cuota:
function shouldCheckSpam(user) {
if (user.isVerified) return false;
if (user.trustScore > 0.9) return false;
return true;
}
Límites de uso
La detección de spam consume tu cuota de análisis de sentimiento:
| Plan | Análisis mensuales | Notas |
|---|---|---|
| Basic | 1,000 | Incluye spam + sentimiento |
| Gold | 5,000 | Incluye spam + sentimiento |
| Platinum | 15,000 | Incluye spam + sentimiento |
| Ultimate | 30,000 | Incluye spam + sentimiento |
Las respuestas en caché no cuentan contra tu cuota.
Ejemplos de integración
Middleware de Express.js
const spamFilter = async (req, res, next) => {
if (req.body.text) {
const result = await checkSpam(req.body.text);
if (result.results.spamfinder.hit) {
return res.status(400).json({
error: 'spam_detected',
message: 'Your message was flagged as spam'
});
}
}
next();
};
app.post('/api/comments', spamFilter, createComment);
Python Flask
from functools import wraps
from flask import request, jsonify
def spam_filter(f):
@wraps(f)
def decorated(*args, **kwargs):
text = request.json.get('text')
if text:
result = check_spam(text)
if result['results']['spamfinder']['hit']:
return jsonify({
'error': 'spam_detected',
'message': 'Your message was flagged as spam'
}), 400
return f(*args, **kwargs)
return decorated
@app.route('/api/comments', methods=['POST'])
@spam_filter
def create_comment():
pass
Próximos pasos
- Análisis de texto - combina spam con puntuación de sentimiento
- Detección de idioma - detecta y aplica el idioma del contenido
- Guía de inicio rápido - consigue tu primera clave de API