Pré-requisitos
- Conta de desenvolvedor e um app configurado para OAuth 2.0
- Token de acesso do usuário com
dm.read,dm.write,tweet.readeusers.read
1. Instalar dependências
- Python
- TypeScript
- Rust
- Go
- C#
- Java
chatxdk; importe-o como chat_xdk. Requer Python 3.10+.- Python
- TypeScript
- Rust
- Go
- C#
- Java
2. Inicializar o Chat XDK com chaves existentes
Este passo carrega chaves que você já tem — use-o quando esta identidade já concluiu a configuração inicial antes:- Backup seguro de chaves: construa o SDK com o
juicebox_configdo seu registro de chave pública e depois façaunlockcom seu código de acesso para recuperar as chaves privadas (por exemplo, em um novo dispositivo). - Blob de chave:
import_keyscom um blob que você exportou anteriormente viaexport_keys, passando junto a versão de chave registrada (Rust e Go nomeiam essa variante comoimport_keys_with_version/ImportKeysWithVersion).
set_identity(user_id, signing_key_version) uma vez, com seu ID de usuário e o public_key_version do seu registro. Isso armazena a identidade da sessão: toda chamada posterior de encrypt e prepare assina como essa identidade, então você nunca passa um ID de remetente ou versão de chave de assinatura por chamada.
Configurando pela primeira vez? Construa o SDK da mesma forma, mas pule unlock/import_keys e continue para o passo 3 para criar, fazer backup e registrar suas chaves.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
export_keys / import_keys). Apps cliente frequentemente usam backup seguro de chaves (setup / unlock com um código de acesso). Veja a referência do Chat XDK para ambos os caminhos.
Trazendo suas próprias chaves?
import_keys só aceita o blob opaco produzido por export_keys do Chat XDK — é uma serialização privada e versionada do estado completo das chaves, não chaves P-256 em bruto ou codificadas em PEM. Você não pode construir esse blob por conta própria: gere as chaves com generate_keypairs (passo 3), exporte o blob uma vez e armazene-o codificado em base64. Blobs criados à mão ou modificados falham na importação.3. Criar e registrar chaves (configuração inicial)
Pule este passo se você carregou chaves existentes no passo 2. Caso contrário, a configuração única de uma nova identidade faz três coisas:- Criar os pares de chaves —
generate_keypairsproduz os pares de chaves de identidade e de assinatura. - Armazenar as chaves privadas —
setupcom um código de acesso as grava no backup seguro de chaves (clientes), ouexport_keysretorna um blob de chave para você armazenar com segurança (servidores e bots). - Registrar as chaves públicas — faça POST do payload de registro para o endpoint add-public-key para que outros possam criptografar para você e verificar suas assinaturas.
set_identity com a versão de chave do registro, para que esta sessão assine como a nova identidade.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
4. Configurar chaves de conversa
Chameprepare_conversation_key_change com a chave pública de identidade de cada participante; a identidade do remetente vem da sessão que você configurou no passo 2. Uma única chamada gera uma nova chave de conversa, criptografa-a para cada participante e assina a mudança. Faça POST do resultado no endpoint add conversation keys (POST /2/chat/conversations/{id}/keys) — o corpo precisa de conversation_key_version, conversation_participant_keys (SDK encrypted_key → API encrypted_conversation_key) e action_signatures (obrigatório; a API rejeita a chamada sem eles). Mantenha a chave de conversa em bruto para envio.
A resposta retorna o ID canônico da conversa (data.conversation_id — o par unido por hífen para uma 1:1, ou o ID com prefixo g para um grupo) e o data.sequence_id da mudança de chave. Use esse ID retornado para requisições subsequentes em vez de reconstruí-lo no cliente. A mesma chamada também rotaciona chaves depois: passe o ID de conversa existente para prepare_conversation_key_change e faça POST com a nova versão de chave. Rotacione quando suspeitar que a chave de conversa foi exposta — a rotação protege apenas mensagens futuras; mensagens criptografadas sob versões de chave anteriores permanecem legíveis para quem possui essas versões.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
5. Enviar uma mensagem
Criptografe com a chave de conversa em bruto do passo 4. O SDK gera o ID da mensagem (um UUID), o embute no evento assinado e o retorna no payload — você nunca cria um por conta própria. Na requisição de envio, faça o mapeamento:
Use um ID de conversa com hífen no path da URL quando a API exigir (
: → -). O próprio SDK é flexível: encrypt_message e encrypt_reply aceitam o ID em qualquer forma que você tenha — A:B de eventos, A-B de listagens ou paths de URL (em qualquer ordem), ou apenas o ID de usuário do destinatário — e o canonicalizam antes de assinar. IDs de grupo (prefixados com g) passam sem alteração.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
Os snippets passam a chave de conversa explicitamente porque neste fluxo você acabou de criá-la no passo 4. Depois que o cache de chaves está ativo e uma passagem de
decrypt_events verificou a chave da conversa (passo 6), encrypt_message(conversation_id, text) sozinho é suficiente — o SDK preenche a chave verificada mais recente. Reenvios devem reenviar o mesmo payload criptografado, para que um ID nunca seja cunhado duas vezes.6. Receber e descriptografar
Use webhooks ou o stream de atividades para tráfego ao vivo, ou pagine os eventos de conversa para o histórico.- Campos de payload ao vivo:
encoded_event, opcionalconversation_key_change_event - Histórico:
GET /2/chat/conversations/{id}/events— prefiradecrypt_eventsem todos os eventos, junto commeta.conversation_key_events - A descriptografia precisa das chaves de assinatura dos remetentes para que o SDK possa verificar quem escreveu cada mensagem. Essas são as chaves públicas dos outros participantes — busque-as no mesmo endpoint de chaves públicas que você usou no passo 4 e mapeie os campos para
SigningKeyEntry(os snippets abaixo incluem o mapeamento) - Você pode passar as chaves de assinatura (e, para
decrypt_event, as chaves de conversa) em cada chamada, ou definir dois armazenamentos de sessão opcionais uma vez e usar as formas curtas de chamada. Os snippets abaixo usam os armazenamentos:set_signing_keys(entries)mantém as chaves dos participantes, eset_cache_keys(true)(desligado por padrão) mantém a chave com assinatura verificada mais recente de cada conversa para que chamadas posteriores possam omitir argumentos de chave. Os dois estilos verificam de forma idêntica - JavaScript usa tipos de evento em camelCase (
message); outras linguagens usam"Message"e campos snake_case no JSON
- Python
- TypeScript
- Rust
- Go
- C#
- Java
Serverless ou multi-instância? O armazenamento de chaves de assinatura e o cache de chaves vivem na memória da instância do SDK. Quando isso não se encaixa — uma invocação descriptografa, outra envia — passe as chaves explicitamente:
decrypt_events(events, signing_keys), decrypt_event(event_b64, conversation_keys, signing_keys), e as sobrescritas conversation_key/conversation_key_version nos métodos de encrypt. Persista você mesmo as conversation_keys retornadas por decrypt_events e passe-as de volta.Melhores práticas
- Mantenha o armazenamento de chaves de assinatura atualizado: chame
set_signing_keysnovamente com o conjunto completo de participantes quando um remetente registrar uma nova versão de chave, e atualize em falhas de verificação de assinatura - Deduplique entregas ao vivo com
event_uuid