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 curtidas

Sei que isso é de 2016, mas não consigo encontrar uma resposta para isso e estou procurando algo semelhante. Existe algum plugin que permita uma reescrita ‘genérica’ de uma URL enviada por membros da comunidade, ou seja, adicionar uma tag de afiliado ou alterar o link de um enviado por um usuário para um de afiliado?

Não que eu saiba, mas tenho interesse em saber se houve desenvolvimentos a esse respeito :slight_smile:

Isso deve ser possível em um componente de tema hoje em dia, dependendo de como os links devem aparecer.

Você pode postar um exemplo do link base e um exemplo de como ele ficaria como um link de afiliado?

2 curtidas

Esta discussão encerrou-se prematuramente. Talvez eu precise repensar a monetização da nossa comunidade.

No meu caso, eu precisaria adicionar um prefixo a uma URL.

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

e eu precisaria convertê-la em…

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

Existem vários tópicos que abordam essa questão, mas havia realmente uma solução pronta para produção?

2 curtidas

Infelizmente, não acho que seja. Provavelmente, isso seria um ótimo candidato para uma vaga de Marketplace.

2 curtidas

Seria possível implementar isso como personalização de tema? Estou analisando a modificação deste JSFiddle, mas qual seria a maneira correta de implementar isso em uma instância do Discourse — se for possível?

// Altere "my-affiliate-id" abaixo para o seu ID de afiliado real
const aid = 'my-affiliate-id';

// Adicione uma barra com o ID de afiliado, apenas se um ID de afiliado ainda não for encontrado no link
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 curtida

Sim, é possível. Vamos começar com algo simples. Primeiro, adicione o seguinte na aba de cabeçalho de um novo componente de tema.

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

</script>

O que isso faz? São tags de script especiais que são tratadas pelo Discourse. Qual é a vantagem? Isso permite que você acesse os métodos da API de plugins.

Você deseja adicionar um código de afiliado a alguns links. Isso significa que você quer modificar o conteúdo das postagens. Se você verificar a API de plugins, verá que existe de fato um método para isso.

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

Você o usa da seguinte maneira.

api.decorateCookedElement(
  element => {
    // faça seu trabalho aqui. 
    // o elemento passado aqui é o nó HTML da postagem processada
  },
  {
    // as opções vão aqui
  }
);

Este é o wrapper que você precisa envolver seu código para que ele seja executado quando uma postagem for renderizada. Então, vamos tentar isso.

Temos seu código e o adicionamos como está.

api.decorateCookedElement(
  element => {
++  // Altere "my-affiliate-id" abaixo para o seu ID de afiliado real
++  const aid = "my-affiliate-id";
++
++  // Adicione uma barra com o ID de afiliado, apenas se um ID de afiliado ainda não for encontrado no link
++  const goglinks = document.querySelectorAll('a[href*="gog.com"]');
++  goglinks.forEach(function (el) {
++    if (!el.href.includes("pp=")) {
++      el.href = el.href.replace(/\?.*$/, "") + "?pp=" + aid;
++    }
++  });
  },
  {
    // as opções vão aqui
  }
);

Isso funciona? Sim, mas também está fazendo algum trabalho redundante, já que estamos consultando o document para os links em vez do elemento da postagem. Então, como corrigir isso?

Lembre-se do argumento element que passamos no método? Bem, é aqui que ele se torna útil.

Em vez de consultar o documento, consultamos o elemento que queremos atingir. Então, mudamos isso.

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

para isso

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

e aqui está o que chegamos ao final.

api.decorateCookedElement(
  element => {
    // Altere "my-affiliate-id" abaixo para o seu ID de afiliado real
    const aid = "my-affiliate-id";

    // Adicione uma barra com o ID de afiliado, apenas se um ID de afiliado ainda não for encontrado no link
--  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;
      }
    });
  },
  {
    // as opções vão aqui
  }
);

Isso funciona muito bem agora, mas ainda podemos melhorá-lo um pouco. Como você só está adicionando um ID de afiliado aos links, não é necessário que isso seja executado quando você estiver no compositor. É aí que as opções do método se tornam úteis.

Uma das opções que você pode passar para o método é onlyStream.

O que ela faz? Ela diz ao método que você só quer que esse código seja executado quando a postagem for renderizada dentro de um tópico. Vamos adicionar essa opção.

api.decorateCookedElement(
  element => {
    // Altere "my-affiliate-id" abaixo para o seu ID de afiliado real
    const aid = "my-affiliate-id";

    // Adicione uma barra com o ID de afiliado, apenas se um ID de afiliado ainda não for encontrado no link
    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
  }
);

Então, agora a única coisa que resta fazer é colocar esse código na tag de script especial que mencionamos anteriormente.

<script type="text/discourse-plugin" version="0.8.42">
api.decorateCookedElement(
  element => {
    // Altere "my-affiliate-id" abaixo para o seu ID de afiliado real
    const aid = "my-affiliate-id";

    // Adicione uma barra com o ID de afiliado, apenas se um ID de afiliado ainda não for encontrado no link
    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>

Em seguida, adicione-o à aba de cabeçalho do seu componente e você estará pronto. Usei o GOG neste exemplo porque foi isso que você perguntou, mas esse padrão pode ser usado para qualquer programa de afiliado, desde que você conheça a estrutura da URL.

11 curtidas

Uau, que tutorial fantástico e educativo!

O JSFiddle foi apenas um exemplo que encontrei. Este novo parceiro em potencial nosso usa um prefixo https://, em vez de um ID de afiliado no final. Eles utilizam a plataforma adtraction.com.

Postando aqui minha versão modificada para que outros possam aproveitar.


<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>

Agora o código adiciona primeiro a URL da rede de anúncios, que rastreia os cliques, e depois anexa o link do parceiro.

3 curtidas

Embora isso funcione elegantemente para links criados manualmente, ao vincular uma palavra a https://website, parece não capturar links gerados automaticamente pelo parser do Discourse. Em outras palavras:

Isso funciona: Google
Mas isso não funciona: Google.com

O script pode ser melhorado para também capturar os links gerados automaticamente?