Ao usar S3 ou Cloudflare R2 para uploads junto com uma URL de CDN personalizada, os uploads de emojis personalizados não respeitam a configuração do CDN e tentam carregar diretamente da URL bruta do bucket.
O problema
Quando um administrador faz upload de um emoji personalizado, o uploader cria um registro upload e salva a URL bruta do bucket no banco de dados (por exemplo, //my-bucket.s3.amazonaws.com/... ou //my-bucket.r2.cloudflarestorage.com/...) — este é o comportamento padrão do Discourse.
No entanto, quando app/models/emoji.rb gera o cache de emojis para /site.json, ele passa a upload.url diretamente para o objeto emoji:
e.url = emoji.upload&.url
Por pular o helper do CDN, o frontend recebe a URL bruta do bucket. Assim, dependendo de quão restritivas são as políticas de acesso do bucket, isso resulta em imagens quebradas ou força o Discourse a rotear os emojis através do avatar_proxy interno.
Solução
Abri um PR que envolve as atribuições de URL no Discourse.store.cdn_url(), o que faz com que o carregador de emojis personalizados esteja alinhado com a forma como as imagens de postagens padrão e os avatares são roteados.
Solução temporária
Enquanto aguardamos que o PR seja revisado e mesclado, criei um componente de tema leve que substitui a URL bruta do bucket pela URL correta do CDN logo antes que o emoji personalizado seja renderizado no DOM (funciona tanto para postagens quanto para chat).
Se você estiver enfrentando este bug no seu site, pode instalar este componente e configurar suas strings do S3 nas configurações do administrador do tema para corrigir qualquer emoji personalizado quebrado:
Nota: se você já fez upload de emojis personalizados que estão atualmente quebrados, executar discourse remap "//my-raw-bucket-url.com" "https://my-cdn.com" no container corrigirá os antigos no banco de dados, enquanto o componente de tema corrigirá qualquer um recém-upload até que a correção do PR seja mesclada no núcleo.
Pode ser que seja algo exclusivo do Cloudflare R2, então. Está falhando na minha instância. Parece que só falha com os novos que são enviados.
Sem a correção do componente do tema, tenho que executar o remapeamento toda vez que envio um novo. O PR pode precisar de alguns ajustes — não sou muito bom com o código dos emojis.
O Discourse utiliza uma configuração com dois CDNs: um para ativos (assets) e outro atuando como proxy para a aplicação.
Os emojis padrão usam um CDN, enquanto os emojis personalizados usam o outro, mas ambos ficam protegidos por um CDN em um site corretamente configurado com essa configuração de dois CDNs.
Já detalhei isso no primeiro tópico relacionado aqui:
Seu site tem ambos os CDNs configurados e funcionando?