Verificação de Links Quebrados

Este recurso verifica a saúde de URLs presentes em textos, substituindo links quebrados por um marcador configurável e retornando um relatório com o status de cada link.

Caso de uso: sanitizar conteúdos ricos (MDX, mensagens, blocos de conhecimento) antes de publicação para evitar experiências negativas com 404/timeout.


Como funciona

  • Extração de URLs a partir de um text.
  • Validação paralela via HTTP HEAD/GET com timeout e limite de concorrência.
  • Detecção de tipo (imagem, documento, etc.) por Content-Type.
  • Cache opcional para acelerar revalidações.
  • Substituição de links quebrados no texto com um rótulo configurável.

Endpoint

POST /api/utils/validateLinksInText

Autenticação: Authorization: Bearer <Tolky Domain Token>

Corpo da requisição

CampoTipoObrigatórioDescrição
textstringsimTexto contendo URLs a serem validadas
options.replaceLabelstringnãoTexto usado no lugar de links quebrados (ex.: "[link indisponível]")
options.cacheTtlSecondsintegernãoTTL do cache em segundos
options.timeoutMsintegernãoTimeout por requisição em ms
options.concurrencyintegernãoParalelismo de validação

Exemplo de requisição

curl -X POST "$BASE_URL/api/utils/validateLinksInText" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOLKY_DOMAIN_TOKEN" \
  -d '{
    "text": "Veja o PDF https://example.com/arquivo.pdf e a imagem https://example.com/img-404.png",
    "options": {
      "replaceLabel": "[link indisponível]",
      "timeoutMs": 5000,
      "concurrency": 8
    }
  }'

Exemplo de resposta

{
  "text": "Veja o PDF https://example.com/arquivo.pdf e a imagem [link indisponível]",
  "links": [
    { "url": "https://example.com/arquivo.pdf", "ok": true, "status": 200, "mimeType": "application/pdf", "type": "document" },
    { "url": "https://example.com/img-404.png", "ok": false, "status": 404, "mimeType": "image/png", "type": "image" }
  ]
}

Códigos de erro

  • 400: text ausente ou inválido
  • 401: credenciais inválidas
  • 500: erro interno

Implementação (Resumo Técnico)

O controlador responsável aplica autenticação de domínio, valida o corpo, instancia MediaLinkHealthChecker e executa validateLinksInText com opções de cache, timeout e concorrência.

const { Response, Log } = require('node-api-rest-framework');
const MediaLinkHealthChecker = require('@/utils/MediaLinkHealthChecker');
const { tolkyAuthMiddleware } = require('@/core/tolkyAuthMiddleware');
const TolkyError = require('@/app/ErrorClass');

module.exports = class ValidateLinksInTextController {
  async post(req, res) {
    try {
      const { data: auth } = await tolkyAuthMiddleware(req);
      if (!auth?.pass) throw TolkyError.forbiddenError('Invalid credentials');

      const { text, options = {} } = req.body || {};
      if (typeof text !== 'string') {
        return Response.json(res, 400, 'Parâmetro "text" é obrigatório e deve ser string');
      }

      const checker = new MediaLinkHealthChecker({
        cacheTtlSeconds: options.cacheTtlSeconds,
        timeoutMs: options.timeoutMs,
        concurrency: options.concurrency,
      });

      const result = await checker.validateLinksInText(text, { replaceLabel: options.replaceLabel });
      return Response.success(res, result);
    } catch (e) {
      if (e instanceof TolkyError) {
        return Response.json(res, e.code, e.message, e.toJSON());
      }
      Log.error(`validateLinksInText controller error: ${e?.message}`);
      return Response.error(res, e);
    }
  }
};

Boas práticas de qualidade

  • Use replaceLabel para evitar URLs quebradas em conteúdos publicados.
  • Habilite cacheTtlSeconds em rotas de pré-publicação para reduzir latência.
  • Defina timeoutMs e concurrency conforme o perfil da sua infraestrutura.
  • Monitore taxas de ok=false para identificar fontes externas instáveis.