Detección de spam

El spam se lee como una frase normal. Lo delata la forma

Un mensaje que es casi todo enlaces, una dirección acortada, una invitación a un chat, un dominio con espacios alrededor del punto, el mismo texto llegando por cuadragésima vez en una hora. ToxicFilter lee esas formas en cada comentario y cada formulario, sin modelo, y te dice cuál ha encontrado.

Cómo funciona

  1. Se lee cada enlace

    Direcciones con http, dominios sueltos y también los acortadores e invitaciones que se escriben sin nada delante, como bit.ly/abc o discord.gg/abc. Cuenta cada uno, y cuenta dónde está.

  2. Se puntúa la forma

    Cuánto del mensaje son enlaces, si empieza por uno, si el destino está oculto o es una invitación a un chat, si el dominio lleva espacios para colarse. Cada cosa es un hallazgo aparte con su propia puntuación.

  3. Se cuentan las repeticiones

    El mismo texto que vuelve a llegar a tu cuenta, en el mismo proyecto, se cuenta durante los últimos quince minutos, y también las copias retocadas con una palabra o un enlace distintos.

  4. Tu línea decide

    Cada hallazgo va a spam o a evasion, y la línea de tu política convierte la puntuación en allow, review o block. Nada de esto necesita el modelo: se resuelve en torno a un milisegundo y cuesta un crédito.

Míralo en acción

  1. 01 Tres enlaces acortados
  2. 02 Un mensaje que empieza por un enlace
  3. 03 Un dominio escrito con espacios
  4. 04 Teclas aporreadas
  5. 05 Un comentario con un enlace útil

Tres enlaces acortados POST /v1/text

¡Seguidores gratis! bit.ly/seg1 tinyurl.com/seg2 bit.ly/seg3

block 11 ms
  • 3 links in about 11 words: mostly links, barely a message.
  • Uses a link shortener, which hides where the link goes.

Tres enlaces en once palabras y todos escondiendo adónde llevan: 0,75 en spam. La plantilla de formulario de contacto rechaza desde 0,65; con las líneas por defecto quedaría retenido para revisión, porque bloquean el spam desde 0,80.

La respuesta, resumida
{
  "decision": "block",
  "flagged": [
    "spam"
  ],
  "scores": {
    "spam": 0.75
  },
  "signals": [
    {
      "category": "spam",
      "score": 0.75,
      "reason": "3 links in about 11 words: mostly links, barely a message.",
      "evidence": [
        "bit.ly/seg1",
        "tinyurl.com/seg2",
        "bit.ly/seg3"
      ]
    },
    {
      "category": "spam",
      "score": 0.7,
      "reason": "Uses a link shortener, which hides where the link goes.",
      "evidence": [
        "bit.ly/seg1",
        "tinyurl.com/seg2",
        "bit.ly/seg3"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 11
}

Un mensaje que empieza por un enlace POST /v1/text

https://seguidores-baratos.example.com los mejores precios, pide hoy y crece rápido

block 7 ms
  • Opens with a link. People answering a question write first and link after.

Quien responde a una pregunta escribe primero y enlaza después. Quien deja un enlace para posicionar empieza por él, y lo que viene detrás es relleno.

La respuesta, resumida
{
  "decision": "block",
  "flagged": [
    "spam"
  ],
  "scores": {
    "spam": 0.75
  },
  "signals": [
    {
      "category": "spam",
      "score": 0.75,
      "reason": "Opens with a link. People answering a question write first and link after.",
      "evidence": [
        "https://seguidores-baratos.example.com los mejores precios, pide hoy y crece ráp"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 7
}

Un dominio escrito con espacios POST /v1/text

Seguidores reales, crecimiento real. Entra en crecerya . xyz y pide el pack de bienvenida.

review 8 ms
  • Domain written with spaces around the dot, which only makes sense to dodge a filter.

Nadie pone espacios alrededor de un punto salvo para esquivar un filtro, así que va a evasion y no a spam. Queda retenido para una persona, no se rechaza.

La respuesta, resumida
{
  "decision": "review",
  "flagged": [
    "evasion"
  ],
  "scores": {
    "evasion": 0.65
  },
  "signals": [
    {
      "category": "evasion",
      "score": 0.65,
      "reason": "Domain written with spaces around the dot, which only makes sense to dodge a filter.",
      "evidence": [
        "crecerya . xyz"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 8
}

Teclas aporreadas POST /v1/text

asdkjfh qwrtzplmnbvcx sdfghjklqwrtz xcvbnmplkjh gfdsaqwrt

review 1 ms
  • Does not read as language: vowels are 4% of the letters, a run of 13 consonants ("qwrtzplmnbvcx"), a run of adjacent keys on the keyboard.

Casi sin vocales y con una ristra de consonantes que ningún idioma aguanta. Lo que no se lee como lenguaje se retiene y nunca se rechaza: una frase rara no justifica perder un mensaje de verdad.

La respuesta, resumida
{
  "decision": "review",
  "flagged": [
    "gibberish"
  ],
  "scores": {
    "gibberish": 0.85
  },
  "signals": [
    {
      "category": "gibberish",
      "score": 0.85,
      "reason": "Does not read as language: vowels are 4% of the letters, a run of 13 consonants (\"qwrtzplmnbvcx\"), a run of adjacent keys on the keyboard.",
      "evidence": [
        "asdkjfh qwrtzplmnbvcx sdfghjklqwrtz xcvbnmplkjh gfdsaqwrt"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 1
}

Un comentario con un enlace útil POST /v1/text

Buena pregunta. La documentación de colas explica bien los reintentos: https://laravel.com/docs/queues

allow 8 ms

Un enlace detrás de una frase es como la gente responde a las preguntas. Su forma no tiene nada de spam, y pasa.

La respuesta, resumida
{
  "decision": "allow",
  "flagged": [],
  "signals": [],
  "model": {
    "read": false
  },
  "took_ms": 8
}

Míralo en acción

Tres enlaces acortados POST /v1/text

¡Seguidores gratis! bit.ly/seg1 tinyurl.com/seg2 bit.ly/seg3

block 11 ms
  • 3 links in about 11 words: mostly links, barely a message.
  • Uses a link shortener, which hides where the link goes.

Tres enlaces en once palabras y todos escondiendo adónde llevan: 0,75 en spam. La plantilla de formulario de contacto rechaza desde 0,65; con las líneas por defecto quedaría retenido para revisión, porque bloquean el spam desde 0,80.

La respuesta, resumida
{
  "decision": "block",
  "flagged": [
    "spam"
  ],
  "scores": {
    "spam": 0.75
  },
  "signals": [
    {
      "category": "spam",
      "score": 0.75,
      "reason": "3 links in about 11 words: mostly links, barely a message.",
      "evidence": [
        "bit.ly/seg1",
        "tinyurl.com/seg2",
        "bit.ly/seg3"
      ]
    },
    {
      "category": "spam",
      "score": 0.7,
      "reason": "Uses a link shortener, which hides where the link goes.",
      "evidence": [
        "bit.ly/seg1",
        "tinyurl.com/seg2",
        "bit.ly/seg3"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 11
}

Un mensaje que empieza por un enlace POST /v1/text

https://seguidores-baratos.example.com los mejores precios, pide hoy y crece rápido

block 7 ms
  • Opens with a link. People answering a question write first and link after.

Quien responde a una pregunta escribe primero y enlaza después. Quien deja un enlace para posicionar empieza por él, y lo que viene detrás es relleno.

La respuesta, resumida
{
  "decision": "block",
  "flagged": [
    "spam"
  ],
  "scores": {
    "spam": 0.75
  },
  "signals": [
    {
      "category": "spam",
      "score": 0.75,
      "reason": "Opens with a link. People answering a question write first and link after.",
      "evidence": [
        "https://seguidores-baratos.example.com los mejores precios, pide hoy y crece ráp"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 7
}

Un dominio escrito con espacios POST /v1/text

Seguidores reales, crecimiento real. Entra en crecerya . xyz y pide el pack de bienvenida.

review 8 ms
  • Domain written with spaces around the dot, which only makes sense to dodge a filter.

Nadie pone espacios alrededor de un punto salvo para esquivar un filtro, así que va a evasion y no a spam. Queda retenido para una persona, no se rechaza.

La respuesta, resumida
{
  "decision": "review",
  "flagged": [
    "evasion"
  ],
  "scores": {
    "evasion": 0.65
  },
  "signals": [
    {
      "category": "evasion",
      "score": 0.65,
      "reason": "Domain written with spaces around the dot, which only makes sense to dodge a filter.",
      "evidence": [
        "crecerya . xyz"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 8
}

Teclas aporreadas POST /v1/text

asdkjfh qwrtzplmnbvcx sdfghjklqwrtz xcvbnmplkjh gfdsaqwrt

review 1 ms
  • Does not read as language: vowels are 4% of the letters, a run of 13 consonants ("qwrtzplmnbvcx"), a run of adjacent keys on the keyboard.

Casi sin vocales y con una ristra de consonantes que ningún idioma aguanta. Lo que no se lee como lenguaje se retiene y nunca se rechaza: una frase rara no justifica perder un mensaje de verdad.

La respuesta, resumida
{
  "decision": "review",
  "flagged": [
    "gibberish"
  ],
  "scores": {
    "gibberish": 0.85
  },
  "signals": [
    {
      "category": "gibberish",
      "score": 0.85,
      "reason": "Does not read as language: vowels are 4% of the letters, a run of 13 consonants (\"qwrtzplmnbvcx\"), a run of adjacent keys on the keyboard.",
      "evidence": [
        "asdkjfh qwrtzplmnbvcx sdfghjklqwrtz xcvbnmplkjh gfdsaqwrt"
      ]
    }
  ],
  "model": {
    "read": false
  },
  "took_ms": 1
}

Un comentario con un enlace útil POST /v1/text

Buena pregunta. La documentación de colas explica bien los reintentos: https://laravel.com/docs/queues

allow 8 ms

Un enlace detrás de una frase es como la gente responde a las preguntas. Su forma no tiene nada de spam, y pasa.

La respuesta, resumida
{
  "decision": "allow",
  "flagged": [],
  "signals": [],
  "model": {
    "read": false
  },
  "took_ms": 8
}

Cómo detectar spam

Qué delata un mensaje de spam, cómo se cuentan las repeticiones y cómo fijar las líneas.

Qué convierte un mensaje en spam

Casi todo el spam se lee como una frase normal. "Seguidores gratis, toca el enlace" es correcto, educado y no tiene ni una palabra que merezca estar en una lista. Lo que lo delata es la forma: un mensaje que es casi todo enlaces, una dirección que oculta adónde lleva, un enlace al principio y relleno detrás, y el mismo texto llegando decenas de veces. ToxicFilter puntúa cada una de esas cosas como un hallazgo aparte, con el motivo escrito, para que veas cuál ha decidido y actúes sobre las que le importan a tu web.

Cómo detectar el spam de enlaces

Contar enlaces no sirve por sí solo, porque un enlace es como la gente responde a las preguntas. Por eso cada llamada lee todos los enlaces, incluidos los dominios sueltos y los acortadores e invitaciones que se escriben sin http (bit.ly/abc, t.me/abc, discord.gg/abc), y puntúa lo que encuentra. Varios enlaces con menos de veinticinco palabras por enlace empiezan en 0,65 con dos y llegan a 0,75 con tres. Un mensaje que empieza por un enlace da 0,75. Un acortador, 0,70. Una invitación a un chat o una página gratuita de enlaces, 0,55. Un dominio con espacios alrededor del punto (crecerya . xyz) va a evasion con 0,65, porque dice algo de la intención sea cual sea el enlace.

Cómo frenar los mensajes repetidos y las campañas de spam

Ningún clasificador que lea un solo mensaje puede ver una campaña, porque la campaña no está en el mensaje: es el mismo mensaje llegando cuarenta veces. ToxicFilter compara cada texto con las llamadas recientes de la misma cuenta y el mismo proyecto durante los últimos quince minutos, y solo en textos de unos cuarenta caracteres o más, para que doscientas personas escribiendo "¡gracias!" sigan siendo un foro. Una huella de cada texto detecta las copias retocadas con otro enlace o dos palabras cambiadas. Estos recuentos salen de llamadas anteriores, así que un ejemplo suelto en una página no puede enseñarlos; aparecen en la respuesta en cuanto llega la segunda copia.

Mensajes de relleno y texto sin sentido

Un mensaje que repite la misma palabra una y otra vez, una tecla mantenida o un muro de emojis puntúa en spam. El texto que no se lee como lenguaje, casi sin vocales y con ristras de consonantes, puntúa en gibberish, que retiene para revisión y nunca rechaza. Solo se juzga en texto con alfabeto latino, porque contar vocales no significa nada en chino o en árabe.

Lo que cuesta una repetición

Una campaña de spam es el mismo mensaje cientos de veces, y las copias se responden desde una caché de veredictos que se guarda por cuenta y por proyecto. El número de copias forma parte de lo que la caché consulta, por tramos, así que una copia solo se vuelve a juzgar cuando el recuento ha crecido lo bastante como para cambiar la respuesta. Una llamada servida desde la caché se cobra un crédito, lo que cuesta una comprobación, aunque la primera costase más. Ninguna de las comprobaciones de esta página usa el modelo: son detectores gratuitos que resuelven un comentario en torno a un milisegundo.

Cómo elegir los umbrales de spam

Las líneas por defecto retienen el spam desde 0,50 y lo bloquean desde 0,80, así que un enlace acortado, un mensaje que empieza por un enlace o tres enlaces cortos se quedan esperando a una persona en vez de rechazarse. La plantilla de formulario de contacto baja las líneas a 0,35 y 0,65, y esos mismos mensajes se rechazan. Empieza por la que encaje con lo que te cuesta un falso positivo en tu web, y luego pon una segunda política en paralelo sobre tu propio tráfico para ver en qué discreparían antes de cambiar.

Cómo se reparte el trabajo

Las comprobaciones instantáneas resuelven los casos claros en torno a un milisegundo, el modelo lee lo que depende del contexto, y tus reglas y tu equipo tienen la última palabra.

  • Se lee, nunca se abre

    Lee la forma de un enlace y nunca lo abre: un destino oculto, un enlace al principio, una invitación a un chat. Una comprobación cuesta en torno a un milisegundo, y nada de lo que publican tus usuarios se visita desde aquí.

  • Campañas, contadas por proyecto

    Las copias se cuentan por cuenta y por proyecto en los últimos quince minutos, también las reescritas, a partir de unos cuarenta caracteres. Doscientas personas escribiendo gracias siguen siendo un foro, y tu tráfico nunca influye en las respuestas de otro cliente.

  • Tus reglas deciden

    Con las líneas por defecto, la mayoría de estas formas quedan retenidas para una persona, porque el spam se rechaza desde 0,80; la plantilla de formulario de contacto rechaza desde 0,65. Elige la línea que le va a tu web y pruébala antes en modo sombra.

Preguntas frecuentes

¿Cómo se detecta el spam de enlaces en los comentarios?

Por la forma de los enlaces, no por cuántos hay. Un enlace detrás de una frase es una respuesta. Varios enlaces con apenas texto alrededor, un mensaje que empieza por un enlace, un acortador que oculta el destino y una invitación a un chat o a una página de enlaces en la bio puntúan cada uno por separado, así que tu política puede actuar sobre cualquiera de ellos.

¿Detecta los enlaces acortados escritos sin http?

Sí. bit.ly/abc, tinyurl.com/abc, t.me/abc y discord.gg/abc cuentan como enlaces aunque no lleven nada delante, porque sus terminaciones no están en ninguna lista de dominios y el spam aprendió hace tiempo a quitar el http. Un dominio solo se toma por acortador cuando es exactamente ese dominio, así que una dirección normal que contenga t.co no se señala.

¿Cómo evito que se publique el mismo mensaje una y otra vez?

Cada llamada se compara con las llamadas recientes de la misma cuenta y el mismo proyecto. Tres copias en quince minutos dan 0,40 en spam, cinco 0,55, diez 0,72 y veinte 0,85. Una huella de cada texto detecta además las copias retocadas con otro enlace o una palabra cambiada, que es en lo que se convierte una campaña en cuanto empiezan a cazarle las copias idénticas.

¿Enviar el mismo texto dos veces cuesta el doble?

Normalmente la repetición se responde desde una caché de veredictos que se guarda por cuenta y por proyecto, y se cobra un crédito, lo que cuesta una comprobación, aunque la primera respuesta costase más. Cada llamada sigue teniendo su propio id y su propio registro.

¿Bloqueará un comentario normal con un enlace?

No. Un solo enlace detrás de una frase no genera ningún hallazgo de spam. Lo que puntúa es un enlace que oculta adónde va, un mensaje que empieza por uno o un mensaje que es casi todo enlaces.

¿Qué umbrales debo usar para el spam?

Las líneas por defecto retienen el spam desde 0,50 y lo rechazan desde 0,80, así que un enlace acortado suelto se queda en review. La plantilla de formulario de contacto retiene desde 0,35 y rechaza desde 0,65, de modo que un enlace acortado o un mensaje que empieza por un enlace se rechaza, algo que tiene sentido en un formulario donde nadie necesita mandar uno. Prueba cualquier cambio como segunda política en paralelo antes de aplicarlo.

Sigue leyendo

Pruébalo con tu tráfico real

2.000 créditos al mes en el plan gratuito, sin tarjeta. Suficiente para pasarle una semana de tu propio contenido y ver qué opina de él.