Enviar e Receber Mensagens

Envie e receba mensagens criptografadas ponta a ponta entre o operador e o cliente.

Direções das Mensagens

  1. Empresa → Contato: enviada pela API, exibida no chat do cliente.
  2. Contato → Empresa: enviada do chat do cliente, entregue via webhook.

Todo o conteúdo das mensagens é criptografado ponta a ponta. O backend apenas armazena e retransmite ciphertext — nunca vê o texto plano.

Enviar Mensagem (Empresa)

Envie mensagens de texto com application/json ou mensagens de mídia com multipart/form-data. Para mensagens de mídia, o campo content se torna a legenda criptografada.

cURL (mensagem de texto)
curl -X POST https://api.ixblix.app/api/messages/company \
  -H "X-API-Key: smci_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "conversationId": "conv_xxxx",
    "content": "<base64 ciphertext AES-GCM>",
    "iv": "<base64>",
    "authTag": "<base64>",
    "encryptedKey": "<base64 chave AES envolvida com RSA-OAEP>",
    "selfEncryptedKey": "<base64 chave AES envolvida com RSA-OAEP>",
    "keyId": "<id da chave do operador>"
  }'
cURL (mensagem de mídia)
curl -X POST https://api.ixblix.app/api/messages/company \
  -H "X-API-Key: smci_xxxx" \
  -F "conversationId=conv_xxxx" \
  -F "content=<base64 legenda AES-GCM>" \
  -F "file=@arquivo_criptografado.bin" \
  -F "iv=<base64>" \
  -F "authTag=<base64>" \
  -F "encryptedKey=<base64>" \
  -F "selfEncryptedKey=<base64>" \
  -F "keyId=<id da chave do operador>"

Campos da Requisição

CampoObrigatórioDescrição
conversationIdSimID da conversa.
contentSimCiphertext AES-256-GCM em base64.
ivSimVetor de inicialização AES-GCM (base64).
authTagSimTag de autenticação AES-GCM (base64).
encryptedKeySimChave AES envolvida pela chave RSA pública do cliente.
selfEncryptedKeySimChave AES envolvida pela própria chave RSA do operador.
keyIdSimIdentificador da chave pública do operador.
operatorUuidSimUUID do operador que envia esta mensagem. Deve ser um UUID válido.
replyToIdNãoID da mensagem a qual esta responde.
attachmentsNãoString JSON criptografada com anexos ricos (botões, vcard, localização). A identidade do operador (nome, imagem, gravatarHash) deve ser incorporada pelo remetente neste JSON antes da criptografia para o cliente renderizar o avatar correto por mensagem.
metadataNãoObjeto JSON opaco armazenado com a mensagem. Use encryptedPushPayload para incluir uma prévia de notificação push criptografada (veja abaixo). O backend nunca inspeciona o conteúdo.

Enviar Mensagem (Contato)

cURL
curl -X POST https://api.ixblix.app/api/messages/contact \
  -H "Content-Type: application/json" \
  -d '{
    "token": "abc123def456",
    "content": "<base64 ciphertext AES-GCM>",
    "iv": "<base64>",
    "authTag": "<base64>",
    "encryptedKey": "<base64>",
    "selfEncryptedKey": "<base64>",
    "keyId": "<id da chave do cliente>"
  }'

Listar Mensagens

cURL
curl https://api.ixblix.app/api/messages/{conversationId} \
  -H "X-API-Key: smci_xxxx"

Prefira webhooks ao invés de polling. O ixblix envia um webhook MESSAGE_RECEIVED sempre que um contato envia uma mensagem.

Entrega e Recibos de Leitura

Toda mensagem passa por três estados de confirmação: sent, delivered e read. read implica delivered — marcar como lida também registra a entrega quando ela ainda não ocorreu. Ambos os timestamps são expostos na mensagem como deliveredAt e readAt.

Marque uma mensagem do cliente como entregue (lado do operador) assim que seu cliente a receber:

cURL
curl -X POST https://api.ixblix.app/api/messages/company/delivered \
  -H "X-API-Key: smci_xxxx" \
  -H "Content-Type: application/json" \
  -d '{ "conversationId": "conv_xxxx", "messageId": "msg_xxxx" }'

Marque uma mensagem do cliente como lida (lado do operador) quando o operador realmente a tiver visto:

cURL
curl -X POST https://api.ixblix.app/api/messages/company/read \
  -H "X-API-Key: smci_xxxx" \
  -H "Content-Type: application/json" \
  -d '{ "conversationId": "conv_xxxx", "messageId": "msg_xxxx" }'

Só reporte leitura quando a janela do chat estiver em foco e a mensagem estiver visível na viewport. Reporte entrega quando a mensagem estiver fora da tela ou a janela estiver em segundo plano — caso contrário o cliente vê um recibo de leitura falso.

Do lado do cliente, o ixblix envia um webhook MESSAGE_DELIVERED quando o dispositivo do cliente recebe sua mensagem e um webhook MESSAGE_READ quando o cliente realmente a vê.

Reações

Reações são mensagens criptografadas com contentType definido como react e replyToId apontando para a mensagem alvo. Envie content vazio para limpar uma reação.

Prévias de Notificação Push

Quando o cliente tem notificações push ativadas, o dispositivo mostra uma notificação para cada nova mensagem da empresa. Por padrão, a notificação mostra um texto genérico "Nova mensagem". Para mostrar o conteúdo real da mensagem, inclua um encryptedPushPayload nos metadata da mensagem.

A prévia é um pequeno objeto JSON criptografado com a chave RSA pública do cliente (RSA-OAEP/SHA-256):

Prévia push em texto plano (antes da criptografia)
{
  "text": "Olá, como posso ajudar?",
  "senderName": "Atendente",
  "thumbnailBase64": "/9j/4AAQ..." // opcional, para mensagens de mídia
}

Criptografe a prévia e inclua nos metadata da mensagem:

Mensagem com prévia push
{
  "conversationId": "conv_xxxx",
  "content": "<ciphertext AES-GCM em base64>",
  "iv": "<base64>",
  "authTag": "<base64>",
  "encryptedKey": "<base64>",
  "selfEncryptedKey": "<base64>",
  "keyId": "<id da chave do operador>",
  "metadata": {
    "encryptedPushPayload": "<ciphertext RSA-OAEP em base64 do JSON da prévia>"
  }
}

O backend nunca vê o texto plano da prévia push. Ele apenas retransmite o ciphertext opaco para o dispositivo do cliente, que o descriptografa com sua chave privada.

Helper do SDK

O SDK fornece encryptPushPreview() para criptografar o JSON da prévia, e sendEncryptedMessage() aceita uma opção pushPreview que gera e inclui automaticamente o payload criptografado:

SDK (prévia push automática)
await client.sendEncryptedMessage(conversationId, {
  content: "Olá, como posso ajudar?",
  operatorIdentity: { uuid: "op-1", name: "Atendente" },
  pushPreview: {
    text: "Olá, como posso ajudar?",
    senderName: "Atendente",
  },
});