Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Visualizações dos Conteúdos na Semana #1677

Closed
wants to merge 1 commit into from
Closed

Conversation

aprendendofelipe
Copy link
Collaborator

Mudanças realizadas

Adiciona uma versão beta da API que devolve a contagem de visualizações dos conteúdos:

  • GET /api/v1/contents/[username]/[slug]/visits

Implementei buscando dados de Analytics da Cloudflare usando a API GraphQL.

Por limitações do método de busca dos dados, por enquanto só serão contabilizadas as visitas da semana. Ou seja, independentemente da data de publicação dos conteúdos, o que será mostrado é a somatória de visitas que aquele conteúdo teve nos últimos 7 dias. E a Cloudflare já remove visitas duplicadas do mesmo dispositivo.

Nesse primeiro momento deixei o endpoint com um cache SWR de 5 minutos.

Próximos passos

É apenas o início da solução para a issue #1115.

Do principal, fica faltando a alteração da UI para mostrar os dados em cada página de conteúdos (e talvez nas listas de conteúdos).

Um ponto importante é informar na UI que as visualizações são só da última semana.

Testes

Também falta pensar em uma forma interessante de testar a funcionalidade.

Como é necessário um token da Cloudflare, além do fato de ser contabilizado apenas o tráfego que passa por ela, nem mesmo em homologação conseguimos testar direito.

Então criei um token específico para homologação, mas ele busca os dados de produção, então não terá nenhuma relação com /[username]/[slug] existentes em homologação, mas sim da versão de produção.

Ou seja, nessa versão de homologação já é possível consultar dados reais das visualizações de qualquer publicação do TabNews. 😉

Tipo de mudança

  • Nova funcionalidade

Checklist:

  • As modificações não geram novos logs de erro ou aviso (warning).
  • Eu adicionei testes que provam que a correção ou novo recurso funciona conforme esperado.
  • Os antigos testes estão passando localmente.

Copy link

vercel bot commented Apr 19, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
tabnews ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 15, 2024 1:05am

@aprendendofelipe
Copy link
Collaborator Author

Usando como exemplo a primeira publicação do Filipe:

https://tabnews-git-weekviewers-tabnews.vercel.app/api/v1/contents/filipedeschamps/tentando-construir-um-pedaco-de-internet-mais-massa/visits

Devolve:

{
  "week_viewers": 101
}

Para comparação, estes são os dados do mesmo conteúdo no Analytics da Vercel (filtrando também pelos últimos 7 dias):

{
  "visitors": 109,
  "page views": 123
}

A Vercel considera como um único visitor os acessos pelo mesmo dispositivo dentro de 24 horas. A Cloudflare não detalha isso, mas pelo número menor de visitantes, não deve se restringir a 24 horas.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Apr 20, 2024

Eu tentei simular uma nova visita consultando a API /visits e demorei até conseguir um resultado onde o week_viewers aumentasse. Para quem for testar pelo navegador, recomendo verificar o cabeçalho x-vercel-cache da resposta. Se estiver STALE, use Ctrl+F5 ao invés de apenas F5.

Além disso, aqui só contaram visitas com a extensão uBlock Origin desligada, o que faz sentido, visto que o uBlock Origin bloqueia a requisição feita para https://static.cloudflareinsights.com/beacon.min.js/.... @aprendendofelipe você enxerga uma forma de ter uma solução interna futuramente, de forma que esse tipo de extensão não atrapalhe na contagem de visitas?

Não sei se a Vercel consegue contar visitas com o uBlock Origin e similares ativos. Isso poderia explicar a diferença na contagem, mas achei a diferença pequena para ser isso (101 vs 109 no seu exemplo).

Também falta pensar em uma forma interessante de testar a funcionalidade.

Podemos fazer testes com mock da API da Cloudflare, o que permitiria garantir que apenas usuários com a permissão receberão a resposta com week_viewers, mas não estaríamos testando a integração com a API.

É viável criar um token bem restrito (em relação às permissões) que pudesse ficar público para possibilitar qualquer pessoa rodar os testes? Ou, ao menos, definir o token no ambiente de CI? Assim poderíamos ter um teste que verifica se o valor retornado para determinada publicação está no formato { week_viewers: number } e que o week_viewers é um número >= 0, mesmo que não consigamos verificar que essa contagem aumenta com uma nova visita, e um outro teste para uma publicação que não existe.


Outra dúvida, onde você conferiu a documentação da API da Cloudflare? Procurei algumas coisas mas só encontrei a documentação de migração, que não é muito específica quanto às possibilidades e limitações.

@Rafatcb Rafatcb added back Envolve modificações no backend novo recurso Nova funcionalidade/recurso labels Apr 21, 2024
@aprendendofelipe
Copy link
Collaborator Author

Eu tentei simular uma nova visita consultando a API /visits e demorei até conseguir um resultado onde o week_viewers aumentasse. Para quem for testar pelo navegador, recomendo verificar o cabeçalho x-vercel-cache da resposta. Se estiver STALE, use Ctrl+F5 ao invés de apenas F5.

Temos alguns pontos que precisam ser considerados:

  • Endpoint: O GET /api/v1/contents/[username]/[slug]/visits está configurado com um cache SWR de 5 minutos. E mesmo após 5 minutos, só na segunda requisição o dado será o mais recente fornecido pela Cloudflare.
  • Analytics: Mesmo sem considerar nosso cache, a Cloudflare não atualiza a contagem em tempo real. Pelo dashboard deles, os dados dos últimos minutos sempre acompanham um aviso de que são dados parciais.
  • Visits: Isso eu ainda não tinha me atentado, mas a Cloudflare diz que só conta como uma nova visita para determinada página se o referer não for o próprio TabNews, ou seja, acessar a home e navegar para um conteúdo não estaria contando como uma visita para esse conteúdo, mas apenas para a home. 😖

Fiz alguns testes e parece que realmente é esse comportamento que acontece com visits, mas é estranho que a contagem sempre fica próxima dos dados da Vercel (em poucos casos fica até um pouco maior). Então isso exige uma investigação melhor.

Se realmente não ficar legal usando visits, ainda podemos usar pageViews.

Além disso, aqui só contaram visitas com a extensão uBlock Origin desligada, o que faz sentido, visto que o uBlock Origin bloqueia a requisição feita para https://static.cloudflareinsights.com/beacon.min.js/.... @aprendendofelipe você enxerga uma forma de ter uma solução interna futuramente, de forma que esse tipo de extensão não atrapalhe na contagem de visitas?

Com algumas configurações extras nós podemos fornecer o beacon.min.js através do nosso domínio. É para o futuro mesmo, pois só compensa lidar com isso se o resto já estiver funcionando bem. 🤝

Não sei se a Vercel consegue contar visitas com o uBlock Origin e similares ativos. Isso poderia explicar a diferença na contagem, mas achei a diferença pequena para ser isso (101 vs 109 no seu exemplo).

A Vercel consegue, pois o script é fornecido pela mesma origem:

  • https://www.tabnews.com.br/_vercel/insights/script.js

O problema é que a Vercel não oferece esses dados em uma API pública oficial, então não dá para criar um token só para isso. Além do token normal do usuário poder ser expirado quando eles quiserem, também podem mudar o funcionamento da API sem nenhuma aviso prévio, então só compensa pensar em alguma gambiarra para usar os dados da Vercel se ficar muito ruim com os dados da Cloudflare.

Podemos fazer testes com mock da API da Cloudflare, o que permitiria garantir que apenas usuários com a permissão receberão a resposta com week_viewers, mas não estaríamos testando a integração com a API.

Implementei como um endpoint público e com cache. Os endpoints com cache não podem ter diferenciação de acordo com permissões dos usuários. Então esse teste não seria necessário (nem possível).

É viável criar um token bem restrito (em relação às permissões) que pudesse ficar público para possibilitar qualquer pessoa rodar os testes?

O token da Cloudflare já está bem restrito, mas temos razões para não deixar público.

Ou, ao menos, definir o token no ambiente de CI? Assim poderíamos ter um teste que verifica se o valor retornado para determinada publicação está no formato { week_viewers: number } e que o week_viewers é um número >= 0

Isso dá para fazer, mas temos que pesar os prós e contras, pois uma indisponibilidade do serviço na Cloudflare iria barrar o CI e dificultar um deploy na Vercel.

Outra dúvida, onde você conferiu a documentação da API da Cloudflare? Procurei algumas coisas mas só encontrei a documentação de migração, que não é muito específica quanto às possibilidades e limitações.

A documentação é essa mesma, mas ela é bem incompleta. Fiz a introspecção do esquema usando GraphiQL e analisando as requisições que ocorrem na dashboard.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Apr 22, 2024

Se realmente não ficar legal usando visits, ainda podemos usar pageViews.

Não encontrei muitas informações sobre o assunto, mas vi que aqui sugeriram o uso de uniq com httpRequests1dGroups, e na documentação tem o httpRequests1mGroups. Eu tentei configurar o GraphiQL para ler a documentação e entender se o campo era útil, mas não tive sucesso.

Implementei como um endpoint público e com cache. Os endpoints com cache não podem ter diferenciação de acordo com permissões dos usuários. Então esse teste não seria necessário (nem possível).

Acabei me confundindo porque temos dois tipos de feature que estão juntas: uma que representa as permissões do usuário, e outra que é utilizada apenas para filtrar a saída, sem verificar se o usuário possui a feature em questão.

Isso dá para fazer, mas temos que pesar os prós e contras, pois uma indisponibilidade do serviço na Cloudflare iria barrar o CI e dificultar um deploy na Vercel.

Do jeito que está implementado agora, cairia no catch e retornaria week_viewers: 0, tanto num cenário de "sem conexão" quanto num cenário de interface retornada diferente do esperado (por exemplo, Uncaught TypeError: ... is undefined), então não seria um teste útil. Seria necessário diferenciar os tipos de erro, mas acredito que isso tem chances maiores de causar mais problemas do que detectá-los, então é mais fácil ver que as publicações estão retornando 0 em produção e então analisar os logs, sem testes.

Então, podemos ter um teste apenas para garantir que ninguém vai mudar o week_viewers para outro nome sem querer.

O mais importante me parece ser retornar um valor de visitas que faça sentido, porque não me parece útil exibir as "visitas diretas" na página da publicação (isso pode ser bem útil e interessante como estatística para o autor, pois significa visitas a partir de outros sites, mas não para quem está lendo a publicação e vendo que ela recebeu "X visitas diretas").

@aprendendofelipe
Copy link
Collaborator Author

...vi que aqui sugeriram o uso de uniq com httpRequests1dGroups, e na documentação tem o httpRequests1mGroups.

Essa sugestão serve se quisermos contar a quantidade de diferentes IPs que acessaram, então é uma terceira opção. 👍

Eu tentei configurar o GraphiQL para ler a documentação e entender se o campo era útil, mas não tive sucesso.

Coloquei no ar um projeto com GraphiQL para facilitar se você quiser testar as consultas. Basta se logar com o GitHub. @filipedeschamps, seu usuário também está liberado:

graphql-cloudflare-analytics.bohr.io

Fiz o deploy na bohr.io, pois na Vercel dava erro na consulta que busca o esquema completo da API, já que passa do limite de 4.5MB.

Para quem se interessar, o código está aqui:

aprendendofelipe/GraphQL-Cloudflare-Analytics


Então, podemos ter um teste apenas para garantir que ninguém vai mudar o week_viewers para outro nome sem querer.

👍

O mais importante me parece ser retornar um valor de visitas que faça sentido, porque não me parece útil exibir as "visitas diretas" na página da publicação (isso pode ser bem útil e interessante como estatística para o autor, pois significa visitas a partir de outros sites, mas não para quem está lendo a publicação e vendo que ela recebeu "X visitas diretas").

É verdade, mas o visits ainda pode ser a melhor opção. Eu desconfio que a Cloudflare só não esteja querendo dar dicas de como computa realmente as visitas (para evitar manipulação), mas no fundo deve acabar contando as navegações via SPA, pois os números que analisei eram muito próximos dos números do Analytics da Vercel.

@Rafatcb
Copy link
Collaborator

Rafatcb commented Apr 25, 2024

Coloquei no ar um projeto com GraphiQL para facilitar se você quiser testar as consultas.

Ficou ótimo! Obrigado.

Essa sugestão serve se quisermos contar a quantidade de diferentes IPs que acessaram, então é uma terceira opção. 👍

Fui testar aqui apenas para comparar, mas parece que ele não tem filtro para uma página específica.

Eu desconfio que a Cloudflare só não esteja querendo dar dicas de como computa realmente as visitas (para evitar manipulação)

Eu tentei realizar alguns testes, cada testes com duas publicações, uma visitando pelo TabNews e outra por outro site ou diretamente pelo link. Só em um teste eu consegui aumentar a quantidade de visitas, que se não me engano eu estava na página do Google e alterei a URL para a publicação, mas mesmo fazendo isso em outras publicações, não aumentou. Fui testando tanto diretamente pela API da Cloudflare quanto pela do TabNews em homologação. Realmente eles não querem facilitar manipulações 🙃

Edit: Parece que só consegui fazer contar visitas dando F5 com Referer, mas mesmo indo de um resultado direto pelo Google, sem atualizar a página, não contou.

@Rafatcb
Copy link
Collaborator

Rafatcb commented May 11, 2024

Fiz alguns testes ao longo dessas semanas. Além da Cloudflare só contar visitas sem o bloqueio de rastreios, parece que:

  • Conta uma visita ao ir pelo Google (ou outro site, mas eu testei pelo Google).
  • Conta uma visita ao atualizar a página (F5).
  • Se atualizar várias vezes seguidas, conta como várias visitas.

Apesar disso, não consegui ter resultados "consistentes", tanto pelo GraphiQL quanto pelo endpoint da API em homologação.

Considerando os pontos da lista acima, acham interessante exibir no TabNews ou acham que isso pode ser "danoso" por ser algo manipulável / inconsistente / não sabermos exatamente como funciona?

Eu fico em dúvida, mas não vejo problemas em testarmos. Acho que seria interessante ter uma publicação avisando como funciona e que, a princípio, é uma implementação temporária até termos a contagem sem limite de tempo. Pode ser ao mesmo tempo uma boa publicação falando sobre o problema e a API da Cloudflare e também um anúncio da funcionalidade.

@aprendendofelipe
Copy link
Collaborator Author

Estou fechando o PR porque, das diversas métricas que a Cloudflare disponibiliza via GraphQL, a única que permite filtrar por conteúdo é essa contagem de visitas que não contabiliza navegações internas, então não é o que precisamos.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
back Envolve modificações no backend novo recurso Nova funcionalidade/recurso
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants