Executando verificação de segurança...
11

Pitch: 🖥️ Criei um Desklet do TabNews para Linux Mint (e como bypassar o Cloudflare)

Fala pessoal! Recentemente decidi trazer o conteúdo do TabNews direto para o meu desktop no Linux Mint (Cinnamon). Queria algo nativo, sem ter que ficar com o navegador aberto o tempo todo.

O resultado foi o TabNews Reader, e queria compartilhar os desafios técnicos que encontrei — principalmente como contornei o bloqueio da API — e pedir um feedback da comunidade sobre algumas implementações.

🚀 O Projeto

A ideia era simples: um widget na área de trabalho que lista os posts Relevantes e Recentes.
O Cinnamon usa GJS (Gnome JavaScript), então a estrutura é basicamente JS, CSS e JSON.

A estrutura ficou assim:

  • desklet.js: A lógica que puxa os dados e monta a UI.
  • stylesheet.css: O visual "Dark Mode" inspirado no TabNews.
  • settings-schema.json: Onde criei a opção de Múltiplas Instâncias. Dá para ter um desklet só de "Relevantes" e outro de "Recentes" lado a lado, cada um com sua config.

Há opções para personalizar tudo.

🚧 O Problema: Erro 403 e Cloudflare

Aqui foi onde o filho chorou e a mãe não viu. Tentei usar a lib padrão Soup do Gnome para fazer o GET na API.
Resultado: 403 Forbidden.

O Cloudflare barra requisições que não têm a "impressão digital" (TLS fingerprint) de um navegador real. O User-Agent padrão do Cinnamon é bloqueado na hora.

🛠️ A Solução: curl-impersonate

Em vez de tentar reinventar a roda simulando headers na mão, fui para o brute force inteligente. Integrei o curl-impersonate no projeto.

Basicamente, o desklet não faz a requisição direta. Ele roda um subprocesso que chama esse binário modificado, que simula perfeitamente um Chrome:

// Trecho simplificado do desklet.js
let args = [
    'curl-impersonate-chrome', 
    '-s', '-L', 
    url_da_api
];
// O Desklet lê o JSON que volta no stdout

Funcionou liso. Agora o TabNews "acha" que é um Chrome acessando.

🛠️ Instalação

Tem dois jeitos de instalar: o rápido (script que faz tudo) e o manual (pra quem gosta de saber o que tá rodando).

Opção 1: Automática (Recomendado)

Só rodar esse comando no terminal. Ele já baixa a dependência (curl-impersonate) e instala o desklet na pasta certa.

bash <(curl -s https://raw.githubusercontent.com/MrJc01/crom-desklets/main/install.sh)

🔮 O que vem por aí (Ajuda?)

O projeto está funcional, mas estou travado em uma feature: Sempre no Topo.
O Cinnamon desenha os desklets na camada do fundo (desktop). Tentei usar z-index e raise_top(), mas ele só fica acima de outros desklets, não de janelas.

Se alguém manjar de GJS/Cinnamon e souber como injetar o ator na camada chromeGroup (overlay), aceito PRs!

O código está aberto aqui: github.com/MrJc01/crom-desklets


☕ Apoie o Desenvolvimento open-source do seu país(Não falo só de mim aqui)

Manter o desenvolvimento de ferramentas open-source exige tempo, dedicação e, claro, muito ☕ para alguns, e muito 🍀 para outros. Se você gostou desse projeto, achou a ferramenta útil ou simplesmente quer incentivar a continuidade do projeto, qualquer apoio é bem-vindo.

Estou trabalhando em um módulo de doações dedicado na Crom (a organização por trás do projeto), mas enquanto ele não fica pronto, estou aceitando apoios via PIX:

Chave:
[email protected]

⚠️ Importante:
Se você fizer uma doação, por favor, envie o comprovante com uma mensagem (pode ser só seu usuário do GitHub ou TabNews) para o e-mail: [email protected]

Assim que eu finalizar e lançar a implementação oficial de donate/invest da Crom, farei questão de migrar e disponibilizar esses apoios lá como créditos, badges de apoiadores, ou minimamente agradecimentos pelo valor investido.

Muito obrigado pela sua atenção! 🗿🍷

Carregando publicação patrocinada...
2
0
2

mandei uma issue, e pediram pra eu mandar email. o conteudo esta abaixo, para exemplificar, acho que é igual ou muito parecido com sua situação

######################################################################################

Pessoal, já fiz mais de 5 testes, em 5 servidores diferentes.
Para acessar api, sempre consigo, mas para acessar a rota para pegar uma nova session, não funciona no servidor, dá um erro e me joga no cloudlfare.

Estou fazendo algo parecido com isso,

curl -X POST https://www.tabnews.com.br/api/v1/sessions
-H "Content-Type: application/json"
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
-H "Accept: application/json"
-H "Origin: https://www.tabnews.com.br"
-H "Referer: https://www.tabnews.com.br/"
-H "Accept-Language: pt-BR,pt;q=0.9"
-d '{"email":"[email protected]","password":""}'

Mas retorna um erro no cloudlfare, contudo. Local funciona.

Será que todos os nossos servidores da empresa, que estão em data centers diferentes, tem problemas de bloqueios no cloudflare?

Vcs podem criar um esquema de Ip WhiteList?

Como resolver isso? acredito que não sou primeiro.

####################################################################################

Complementado, não estou criando uma automação

Tenho um dominio https://programadorraiz.com.br que o conteudo é lido através da api do tabnews, do usuário programadorraiz

Contudo, a pagina /autor, quero ler o perfil do meu usuário o programador raiz de dentro do tabnews.

Para ler isso, preciso estar autenticado, e por isso o questionamento acima.

Informações do cloudflare "Cloudflare Ray ID: 9b3c228e8f2da29a • Your IP: Click to reveal 2607:5300:205:200::18ef • Performance & security by Cloudflare"

Isso também era o inicio de projeto de um "tabnewplus" onde eu pretendia criar uma interface pra implementar coisas, que sinto falta no tabnews, mas que provalvelmente não conseguiria implementar lá, por não trabalhar com as tecnologias em questão.

Por exemplo, eu gostaria de ter uma lista para favoritar artigos, e criar listas de determinados assuntos, para poder revistar depois.

Criar tags nos conteúdos iniciais para criar uma categorização de assuntos, pois tem assunto que não me interessam, e sair rolando o feed de "recentes" às vezes não é tão assertivo.

Enfim, pra tudo isso, preciso ter um login com tabsnews na minha mente.

Do contrario, vou implementar um "login" com google e pegar apenas o conteudo publico, e seguir mais separado da autenticação do tabnews mesmo.