Requisitos previos
- Cuenta de desarrollador y una app configurada para OAuth 2.0
- Token de acceso de usuario con
dm.read,dm.write,tweet.readyusers.read
1. Instalar dependencias
- Python
- TypeScript
- Rust
- Go
- C#
- Java
chatxdk; impórtalo como chat_xdk. Requiere Python 3.10+.- Python
- TypeScript
- Rust
- Go
- C#
- Java
2. Inicializar el Chat XDK con claves existentes
Este paso carga claves que ya tienes—úsalo cuando esta identidad ya haya completado la configuración inicial antes:- Copia de seguridad segura de claves: construye el SDK con el
juicebox_configde tu registro de public-key, luegounlockcon tu código de acceso para recuperar las claves privadas (por ejemplo, en un nuevo dispositivo). - Blob de claves:
import_keyscon un blob que exportaste previamente medianteexport_keys, pasando junto a él la versión de clave registrada (Rust y Go llaman a esta varianteimport_keys_with_version/ImportKeysWithVersion).
set_identity(user_id, signing_key_version) una vez, con tu ID de usuario y el public_key_version de tu registro. Esto almacena la identidad de la sesión: cada llamada posterior de encrypt y prepare firma como esta identidad, así que nunca pasas un ID de remitente ni una versión de clave de firma por llamada.
¿Configurando por primera vez? Construye el SDK de la misma forma pero omite unlock/import_keys, y continúa al paso 3 para crear, respaldar y registrar tus claves.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
export_keys / import_keys). Las apps de cliente suelen usar copia de seguridad segura de claves (setup / unlock con un código de acceso). Consulta la referencia del Chat XDK para ambas rutas.
¿Traes tus propias claves?
import_keys solo acepta el blob opaco producido por export_keys del Chat XDK—es una serialización privada y versionada del estado completo de la clave, no claves P-256 en bruto o codificadas en PEM. No puedes construir este blob por tu cuenta: genera claves mediante generate_keypairs (paso 3), exporta el blob una vez y guárdalo codificado en base64. Los blobs artesanales o modificados fallan al importar.3. Crear y registrar claves (configuración inicial)
Omite este paso si cargaste claves existentes en el paso 2. En caso contrario, la configuración única para una nueva identidad hace tres cosas:- Crear los pares de claves —
generate_keypairsproduce los pares de claves de identidad y de firma. - Almacenar las claves privadas —
setupcon un código de acceso las escribe en la copia de seguridad segura de claves (clientes), oexport_keysdevuelve un blob de claves para que lo guardes de forma segura (servidores y bots). - Registrar las claves públicas — POST al payload de registro al endpoint add-public-key para que otros puedan cifrar hacia ti y verificar tus firmas.
set_identity con la versión de clave del registro, para que esta sesión firme como la nueva identidad.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
4. Configurar claves de conversación
Llama aprepare_conversation_key_change con la clave pública de identidad de cada participante; la identidad del remitente proviene de la sesión que configuraste en el paso 2. Una llamada genera una nueva clave de conversación, la cifra para cada participante y firma el cambio. Envía el resultado con POST al endpoint add conversation keys (POST /2/chat/conversations/{id}/keys)—el cuerpo necesita conversation_key_version, conversation_participant_keys (SDK encrypted_key → API encrypted_conversation_key) y action_signatures (obligatorio; la API rechaza la llamada sin ellas). Guarda la clave de conversación en bruto para enviar.
La respuesta devuelve el ID canónico de la conversación (data.conversation_id—el par unido por guion para un 1:1, o el ID con prefijo g para un grupo) y el data.sequence_id del cambio de clave. Usa ese ID devuelto para solicitudes posteriores en lugar de reconstruirlo del lado del cliente. La misma llamada también rota claves más tarde: pasa el ID de conversación existente a prepare_conversation_key_change y haz POST con la versión de clave más reciente. Rota cuando sospeches que la clave de conversación fue expuesta—la rotación protege solo los mensajes futuros; los mensajes cifrados con versiones anteriores de la clave siguen siendo legibles para cualquiera que tenga esas versiones.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
5. Enviar un mensaje
Cifra con la clave de conversación en bruto del paso 4. El SDK genera el ID del mensaje (un UUID), lo incrusta en el evento firmado y lo devuelve en el payload—nunca lo generas tú mismo. En la solicitud de envío, mapea:
Usa un ID de conversación con guiones en la ruta de la URL cuando la API lo requiera (
: → -). El SDK en sí es flexible: encrypt_message y encrypt_reply aceptan el ID en cualquier forma que tengas—A:B de eventos, A-B de listados o rutas URL (en cualquier orden), o simplemente el user id del destinatario—y lo canonicaliza antes de firmar. Los IDs de grupo (con prefijo g) se pasan sin cambios.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
Los snippets pasan la clave de conversación explícitamente porque en este flujo acabas de crearla en el paso 4. Una vez que la caché de claves esté activada y una pasada de
decrypt_events haya verificado la clave de la conversación (paso 6), basta con encrypt_message(conversation_id, text)—el SDK completa con la última clave verificada. Los reintentos deben reenviar el mismo payload cifrado, para que nunca se genere un ID dos veces.6. Recibir y descifrar
Usa webhooks o el activity stream para el tráfico en vivo, o pagina los events de conversación para el historial.- Campos del payload en vivo:
encoded_event, opcionalconversation_key_change_event - Historial:
GET /2/chat/conversations/{id}/events— prefieredecrypt_eventsen todos los eventos másmeta.conversation_key_events - Descifrar necesita las claves de firma de los remitentes para que el SDK pueda verificar quién escribió cada mensaje. Estas son las claves públicas de los demás participantes — obténlas del mismo endpoint public-keys que usaste en el paso 4 y mapea los campos a
SigningKeyEntry(los snippets a continuación incluyen el mapeo) - Puedes pasar las claves de firma (y, para
decrypt_event, las claves de conversación) en cada llamada, o configurar dos almacenes de sesión opcionales una vez y usar las formas de llamada breves. Los snippets a continuación usan los almacenes:set_signing_keys(entries)guarda las claves de los participantes, yset_cache_keys(true)(desactivado por defecto) mantiene la última clave verificada por firma de cada conversación para que las llamadas posteriores puedan omitir los argumentos de clave. Ambos estilos verifican de forma idéntica - JavaScript usa tipos de evento en camelCase (
message); otros lenguajes usan"Message"y campos en snake_case en JSON
- Python
- TypeScript
- Rust
- Go
- C#
- Java
¿Serverless o multi-instancia? El almacén de claves de firma y la caché de claves viven en la memoria de la instancia del SDK. Donde eso no encaja—una invocación descifra, otra envía—pasa las claves explícitamente en su lugar:
decrypt_events(events, signing_keys), decrypt_event(event_b64, conversation_keys, signing_keys), y las anulaciones conversation_key/conversation_key_version en los métodos de cifrado. Persiste tú mismo las conversation_keys devueltas por decrypt_events y vuelve a pasarlas.Buenas prácticas
- Mantén el almacén de claves de firma actualizado: vuelve a llamar a
set_signing_keyscon el conjunto completo de participantes cuando un remitente registre una nueva versión de clave, y refresca ante fallos de verificación de firma - Deduplica las entregas en vivo con
event_uuid