API de Proxy de Mídia (chat-storage)
Esta funcionalidade disponibiliza URLs públicas temporárias para acessar mídias (ex.: imagens de produtos da Sankhya), sem expor credenciais da origem e sem persistir/copiar o arquivo no storage. O chat-storage atua como um proxy de streaming, gerando um token assinado/criptografado com expiração e realizando o repasse do conteúdo diretamente da origem para o consumidor final (browser/WhatsApp/Meta).
Autenticação interna
O header Authorization deve possuir como valor a chave compartilhada entre os serviços internos para autorização no chat-storage. Esse valor corresponde à configuração storage.token.value (no Consul da aplicação). O segredo já está disponível em fluxos que integram com o chat-storage ou pode ser solicitado ao time de Infra
Base URL por ambiente
Ambiente | Base URL |
|---|---|
Produção | |
Homologação |
Visão geral do fluxo
O cliente solicita ao chat-storage a criação de um token, informando como buscar a mídia na origem e o tempo de expiração.
O cliente monta uma URL pública temporária com o token retornado e envia para o consumidor final (browser/WhatsApp/Meta).
1) Gerando o token de requisição
Endpoint
POST <BASE_URL>/storage/proxy/token
Exemplo (produção):
POST https://files.neppo.com.br/storage/proxy/token
Headers
Nome | Obrigatório | Descrição |
|---|---|---|
Authorization | Sim | Valor da chave compartilhada entre os serviços internos |
Body
Campo | Obrigatório | Tipo | Descrição |
|---|---|---|---|
sourceUrl | Sim | string | URL da origem que retorna o binário (ex.: endpoint privado da Sankhya). |
httpMethod | Sim | string | Método HTTP para consumir a origem (ex.: "GET") |
sourceHeaders | Sim | object (map) | Headers que serão enviados para a origem |
responseContentType | Não | string | Content-Type devolvido ao cliente final. Se omitido, será usado o Content-Type retornado pela origem |
expiresIn | Sim | number | Timestamp epoch em segundos de expiração. Após expirar, o token não é mais aceito |
Exemplo de requisição (imagem de produto da Sankhya)
curl --location 'https://files.neppo.com.br/storage/proxy/token
'
--header 'Authorization: <SECRET>'
--header 'Content-Type: application/json'
--data-raw '{
"sourceUrl": "https://api.sankhya.com.br/gateway/v1/mge/Produto@IMAGEM@CODPROD=
1232.dbimage",
"httpMethod": "GET",
"sourceHeaders": {
"Authorization": "Bearer <ACCESS_TOKEN>"
},
"responseContentType": "image/png",
"expiresIn": 1765802610
}'Resposta
{
"requestToken": "<REQUEST_TOKEN>",
"expiresIn": 1765802610
}O campo requestToken é o valor que será usado na URL pública do streaming.
2) Streaming da mídia via URL pública temporária
Endpoint
GET <BASE_URL>/storage/proxy/<REQUEST_TOKEN>/<FILE_NAME>.<FILE_EXTENSION>
Onde:
<REQUEST_TOKEN>: token retornado no passo 1
<FILE_NAME>: nome do arquivo exposto no Content-Disposition
<FILE_EXTENSION>: extensão exposta no Content-Disposition (ex.: png, jpg, pdf)
Exemplo de chamada
curl --location 'https://files.neppo.com.br/storage/proxy/<REQUEST_TOKEN>/1232.png'Comportamento esperado
No servidor (chat-storage):
Decodifica o requestToken e valida a expiração (expiresIn).
Faz a requisição HTTP para sourceUrl usando httpMethod e sourceHeaders.
Realiza o streaming do corpo da resposta para o cliente (sem carregar tudo em memória).
No cliente (browser / Meta/WhatsApp):
A URL pode ser utilizada diretamente como mídia em bots de WhatsApp/Meta ou aberta no navegador.
Headers de resposta
O chat-storage responde ao cliente com:
Content-Type
Se responseContentType foi informado ao gerar o token, ele será usado (ex.: image/png).
Caso contrário, será usado o Content-Type retornado pela origem.Content-Disposition
inline; filename="<FILE_NAME>.<FILE_EXTENSION>Body
Conteúdo em streaming
Observação (WhatsApp/Meta)
A presença de um nome + extensão na URL e no Content-Disposition ajuda na renderização correta (ex.: .png, .jpg).
Segurança e boas práticas
O que este proxy protege
Tokens/credenciais sensíveis não precisam ser expostos ao cliente final (ex.: Bearer da Sankhya).
A mídia pode vir de endpoints privados e ainda assim ser consumida como URL pública temporária.
O token expira automaticamente em expiresIn.
Recomendações
Use expiresIn curto (ex.: 5–60 minutos), conforme o caso.
Nunca compartilhe o chave compartilhada para fora dos serviços internos autorizados, se possível armazenar no Neppo Vault com a máscara aplicada.
Prefira responseContentType explícito quando a origem não retorna um Content-Type confiável.
Use nomes de arquivo simples em <FILE_NAME> (sem espaços, sem caracteres especiais), ex.:
produto_12345.png.
Comentários
0 comentário
Escreva seu comentário aqui
Por favor, entre para comentar.