Link rewriting for affiliate codes

I saw this and was thrilled:

Then I installed it, and realized that it still only works for Amazon. Would it be hard to add support for ShareASale? Maybe even a “generic” rewrite where you regex an URL and do a replacement?

2 Me gusta

Sé que esto es de 2016, pero no puedo encontrar una respuesta a esto y estoy buscando algo similar. ¿Existe algún plugin que permita una reescritura ‘genérica’ de una URL enviada por miembros de la comunidad, es decir, agregar una etiqueta de afiliado o cambiar el enlace de uno enviado por un usuario a uno de afiliado?

No que yo sepa, pero me interesa saber si ha habido novedades al respecto :slight_smile:

Esto debería ser posible en un componente de tema en la actualidad, dependiendo de cómo deban verse los enlaces.

¿Podrías publicar un ejemplo del enlace base y otro de cómo se vería como enlace de afiliado?

2 Me gusta

Esta discusión ha terminado prematuramente. Es posible que necesite repensar la monetización de nuestra comunidad.

En mi caso, necesitaría agregar un prefijo a una URL.

http://merchantxyz.com/....

y tendría que convertirlo en…

https://tracker.adagency123.com/t/t?a=12345678&as=87654321&t=2&tk=1&url=https://merchantxyz.com/...

Hay varios temas que abordan este problema, pero ¿había realmente una solución lista para producción?

2 Me gusta

Lamentablemente, no lo creo. Probablemente este sería un excelente candidato para un trabajo en Marketplace.

2 Me gusta

¿Sería posible implementarlo como personalización del tema? Estoy considerando modificar este JSFiddle, pero ¿cuál sería la forma correcta de implementarlo en una instancia de Discourse, si es posible?

// Cambia "my-affiliate-id" a continuación por tu ID de afiliado real
const aid = 'my-affiliate-id';

// Añade una barra diagonal con el ID de afiliado, solo si aún no se encuentra en el enlace
const goglinks = document.querySelectorAll('a[href*="gog.com"]');
goglinks.forEach(function(el) {
  if(!el.href.includes('pp=')) {
    el.href = el.href.replace(/\?.*$/, '') + '?pp=' + aid
  }
})
1 me gusta

Sí, es posible. Empecemos con algo sencillo. Primero, añade esto a la pestaña de encabezado de un nuevo componente de tema.

<script type="text/discourse-plugin" version="0.8.42">

</script>

¿Qué hace esto? Es un tipo especial de etiqueta script que es manejada por Discourse. ¿Cuál es la ventaja? Te permite acceder a los métodos de la API de plugins.

Quieres agregar un código de afiliado a algunos enlaces. Eso significa que deseas modificar el contenido de las publicaciones. Si revisas la API de plugins, verás que existe un método para ello.

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/lib/plugin-api.js#L224-L262

Se usa de la siguiente manera.

api.decorateCookedElement(
  element => {
    // realiza tu trabajo aquí.
    // el elemento pasado aquí es el nodo HTML de la publicación procesada
  },
  {
    // las opciones van aquí
  }
);

Este es el contenedor que necesitas para envolver tu código y que se ejecute cuando se renderiza una publicación. Así que intentémoslo.

Tomamos tu código y lo añadimos tal cual.

api.decorateCookedElement(
  element => {
++  // Cambia "my-affiliate-id" a continuación por tu ID de afiliado real
++  const aid = "my-affiliate-id";
++
++  // Agrega la barra con el ID de afiliado, solo si aún no se encuentra un ID de afiliado en el enlace
++  const goglinks = document.querySelectorAll('a[href*="gog.com"]');
++  goglinks.forEach(function (el) {
++    if (!el.href.includes("pp=")) {
++      el.href = el.href.replace(/\?.*$/, "") + "?pp=" + aid;
++    }
++  });
  },
  {
    // las opciones van aquí
  }
);

¿Esto funciona? Sí, pero también realiza trabajo redundante ya que estamos consultando el document para obtener los enlaces en lugar del elemento de la publicación. Entonces, ¿cómo lo solucionamos?

¿Recuerdas el argumento element que pasamos en el método? Bueno, aquí es cuando resulta útil.

En lugar de consultar el documento, consultamos el elemento que queremos dirigir. Así que cambiamos esto.

const goglinks = document.querySelectorAll('a[href*="gog.com"]');

por esto

const goglinks = element.querySelectorAll('a[href*="gog.com"]');

y esto es lo que obtenemos al final.

api.decorateCookedElement(
  element => {
    // Cambia "my-affiliate-id" a continuación por tu ID de afiliado real
    const aid = "my-affiliate-id";

    // Agrega la barra con el ID de afiliado, solo si aún no se encuentra un ID de afiliado en el enlace
--  const goglinks = document.querySelectorAll('a[href*="gog.com"]');
++  const goglinks = element.querySelectorAll('a[href*="gog.com"]');
    goglinks.forEach(function (el) {
      if (!el.href.includes("pp=")) {
        el.href = el.href.replace(/\?.*$/, "") + "?pp=" + aid;
      }
    });
  },
  {
    // las opciones van aquí
  }
);

Ahora funciona muy bien, pero aún podemos mejorarlo un poco. Como solo estás agregando un ID de afiliado a los enlaces, no necesitas que esto se ejecute cuando estás en el editor. Ahí es donde entran las opciones del método.

Una de las opciones que puedes pasar al método es onlyStream.

¿Qué hace? Le indica al método que solo deseas que este código se ejecute cuando la publicación se renderiza dentro de un tema. Agreguemos esa opción.

api.decorateCookedElement(
  element => {
    // Cambia "my-affiliate-id" a continuación por tu ID de afiliado real
    const aid = "my-affiliate-id";

    // Agrega la barra con el ID de afiliado, solo si aún no se encuentra un ID de afiliado en el enlace
    const goglinks = element.querySelectorAll('a[href*="gog.com"]');
    goglinks.forEach(function (el) {
      if (!el.href.includes("pp=")) {
        el.href = el.href.replace(/\?.*$/, "") + "?pp=" + aid;
      }
    });
  },
  {
++  onlyStream: true
  }
);

Así que ahora lo único que queda por hacer es colocar este código en la etiqueta script especial de la que hablamos antes.

<script type="text/discourse-plugin" version="0.8.42">
api.decorateCookedElement(
  element => {
    // Cambia "my-affiliate-id" a continuación por tu ID de afiliado real
    const aid = "my-affiliate-id";

    // Agrega la barra con el ID de afiliado, solo si aún no se encuentra un ID de afiliado en el enlace
    const goglinks = element.querySelectorAll('a[href*="gog.com"]');
    goglinks.forEach(function (el) {
      if (!el.href.includes("pp=")) {
        el.href = el.href.replace(/\?.*$/, "") + "?pp=" + aid;
      }
    });
  },
  {
    onlyStream: true
  }
);
</script>

Luego, agrégalo a la pestaña de encabezado de tu componente y ya estarás listo. Usé GOG en este ejemplo porque eso es lo que preguntaste, pero este patrón puede usarse para cualquier programa de afiliados siempre que conozcas la estructura de la URL.

11 Me gusta

¡Vaya, qué tutorial tan fantástico y educativo!

El JSFiddle fue solo un ejemplo que encontré. Este nuevo posible socio nuestro utiliza un prefijo https://, en lugar de un ID de afiliado al final. Utilizan la plataforma adtraction.com.

Publico aquí mi versión modificada para que otros la aprovechen.


<script type="text/discourse-plugin" version="0.8.42">
api.decorateCookedElement(
  element => {
        const affiliate = 'https://their-ad-network.com/...';
        const affiliate_links = element.querySelectorAll('a[href*="potentialparterwebsite.com"]');

        affiliate_links.forEach(function(el) {
            if (!el.href.startsWith(affiliate)) {
                el.href = affiliate +  encodeURIComponent(el.href);
            }
        });
    },
  {
    onlyStream: true
  }
);
</script>

Así, el código ahora añade primero la URL de la red publicitaria, que rastrea los clics, y luego la complementa con el enlace del socio.

3 Me gusta

Aunque esto funciona elegantemente para los enlaces creados manualmente, al vincular una palabra a https://website, no parece detectar los enlaces generados automáticamente por el analizador de Discourse. En otras palabras:

Esto funciona: Google
Pero esto no: Google.com

¿Se puede mejorar el script para que también detecte los enlaces generados automáticamente?