インストール
- Python
- TypeScript
- Rust
- Go
- C#
- Java
chatxdk で、chat_xdk としてインポートします。Python 3.10 以上が必要です。クイックスタート
鍵をロードし、アイデンティティを一度セットし、バックログを復号し、ライブイベントを 1 つ復号し、メッセージを暗号化します。送信ボディは、はじめに と同じようにPOST /2/chat/conversations/{id}/messages に配線してください。
スニペットは 2 つのオプションセッションストアを使って最も短い呼び出し形式を使用します:set_signing_keys は他の参加者の公開鍵を保持(public-keys エンドポイント から取得)して、復号呼び出しが呼び出し単位の引数なしに送信者を検証できるようにし、set_cache_keys(true) は SDK が各会話の検証済み鍵を記憶できるようにして、暗号化呼び出しには会話 ID とテキストだけあれば済むようにします。どちらかをスキップして呼び出しごとに同じ値を渡すこともできます——どちらのスタイルでも検証は同じです。復号 を参照してください。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
ライフサイクルと鍵
SDK を構築し、秘密鍵を保管し(パスコードで保護されるセキュアキーバックアップまたはローカル鍵ブロブ)、Chat API に公開鍵を登録し、アンロックまたはインポートの後にset_identity(user_id, signing_key_version) を呼び出します——これは、署名されるアクションが既定とする送信者と署名鍵バージョンを設定するので、encrypt および prepare メソッドが呼び出し単位のアイデンティティ引数なしで動作します。デバイス/アプリのアイデンティティごとに generate_keypairs を一度呼び出し、登録ペイロードを public-keys エンドポイントに POST してください。セキュアキーバックアップには全バインディングで setup / unlock(および関連するパスコードヘルパー)を使用します。export_keys / import_keys(ボットとサーバー向けの生の鍵ブロブ永続化)はネイティブバインディングでのみ利用できます——Python、Go、.NET、JVM、Rust。JS/WASM バインディングは生の鍵のエクスポート/インポートを公開しません:ブラウザではインスタンスに到達する任意のスクリプトがアイデンティティを持ち出しうるため、JS は鍵をセキュアキーバックアップ内に保持します。リクエストごとのバックアップレルムのラウンドトリップを避けたい JS サーバーは、リクエスト間で 1 つのアンロック済み Chat インスタンスを再利用するか、鍵ブロブがサポートされるネイティブバインディングを実行してください。
SDK は登録済み公開鍵に対して X API が報告するバージョンも必要とします。これにより、他のバージョンを対象とする鍵変更エントリはスキップされます。set_identity はそれをユーザー ID と一緒に記録します。import_keys はそれをオプションの引数として直接受け付けます(Rust と Go では import_keys_with_version / ImportKeysWithVersion を使用)。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
juicebox_config オブジェクト(推奨——そのまま渡す)、完全な sdk_config ラッパー、または裸の token_map。
オプション:署名検証はデフォルトでオンです(reject_unverified = true)——無効にするには set_reject_unverified(false) を呼び出します(推奨されません)。バックアップレルム構成が変わった場合は update_config を使用します。UI の状態には is_unlocked / has_identity_key を使用します。完全なフィールドリストは chat-xdk リポジトリ のスタブにあります。
会話鍵
3 つの prepare メソッドはそれぞれ、鍵変更に必要な処理を 1 回の呼び出しで完了します:新しい会話鍵を生成し、渡された公開鍵からすべての参加者に対して暗号化し、変更に署名します。送信者のアイデンティティと署名鍵バージョンはセッションから来ます(set_identity)。パラメーターに sender_id / signing_key_version を設定すればオーバーライドできます。すべて同じ PreparedConversationChange 形状を返し、POST 準備が整っています——SDK のフィールド encrypted_key を conversation_participant_keys の encrypted_conversation_key にリネームし、アクション署名を必須の action_signatures ボディフィールドにマップしてください。
encrypt_message とメディア用に生の鍵バイトを保持してください。API の暗号化エンベロープを暗号化に渡さないでください。
鍵変更イベントペイロードに対して extract_conversation_keys を使って { keys, latest_version } を再構築します。decrypt_conversation_key は 1 つの ECIES ブロブをアンラップします。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
prepare_group_create はメンバー/管理者 ID リスト、prepare_group_members_change は新規 + 現在の名簿)を渡してください——サンプルはグループを参照してください。どちらも2 つのアクション署名を返します。POST には両方を含める必要があります。
復号
decrypt_events は履歴とバックログ用です:ストリームから会話鍵を取得し、復号済みメッセージを返し、バッチ全体を失敗させる代わりにイベントごとのエラーを収集します。decrypt_event は 1 つのライブイベント用です。失敗時に raise/throw します。
送信者を SDK が検証できるよう、署名鍵を渡してください。API の public-key フィールドを SigningKeyEntry にマップしてください:public_key_version → public_key_version(同じ名前)、signing_public_key → public_key、public_key → identity_public_key、および identity_public_key_signature と user_id。
呼び出し単位の鍵引数を省略できるようにする、2 つのオプトインなセッションストアがあります:
set_signing_keys(entries)は参加者の署名鍵を保管します。復号呼び出しが署名鍵引数を省略(または空を渡す)した場合、代わりにストアが使われます。検証自体は変わりません——鍵はこの呼び出しを通じてのみストアに入り、復号対象のイベントからは決して入りません。呼び出しごとに以前のセットが置き換わります。set_cache_keys(true)は会話鍵キャッシュを有効にします(デフォルトはオフ)。有効な間、decrypt_eventsは会話ごとに、鍵変更が有効な署名を持っていた最新の鍵をキャッシュします。decrypt_eventは会話鍵引数が省略された場合にそこにフォールバックし、暗号化ヘルパーは省略された会話鍵をそこから解決します。無効化するとキャッシュはクリアされます。
decrypt_events では errors に収集され、decrypt_event ではスローされます)。実際に検証をスキップするには、まず set_reject_unverified(false) を呼び出す必要があります(本番環境では推奨されません)。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
暗号化と送信ヘルパー
encrypt_message(conversation_id, text) はテキストメッセージ用に署名付き暗号文を構築します。オプションで entities、attachments(media_hash_key 経由)、should_notify、ttl_msec。送信者アイデンティティはセッション(set_identity)から、会話鍵はオプトインの鍵キャッシュ(set_cache_keys)から解決されます——または sender_id / signing_key_version と conversation_key + conversation_key_version を明示的に渡します。SDK は message_id を生成し(署名済みイベントに埋め込まれた UUID)、ペイロード上で返します——自分で発行しないでください。リトライ時は同じペイロードを再利用して、ID が二度発行されないようにしてください。ペイロードを send-message ボディにマップしてください:message_id → message_id、encrypted_content → encoded_message_create_event、encoded_event_signature → encoded_message_event_signature。
返信はイベントベースです。 encrypt_reply(conversation_id, text, reply_to_event) は返信対象の base64 生イベントを受け取ります。SDK はそこから引用プレビュー(シーケンス ID、送信者、テキスト、エンティティ、添付)を導出し、署名済みオリジナルを送信メッセージに埋め込むので、受信者は引用を検証できます。オリジナルが返信より古い鍵バージョンで暗号化されている場合は、reply_to_ckces——生の鍵変更イベント——を渡してください。オリジナルが編集されている場合は、生の編集イベントを reply_to_edit_event として渡してください:プレビューはメッセージが現在示している内容を引用します(そのテキストとエンティティは編集から取られます)、そして受信者がチェックできるよう編集がオリジナルと一緒に伝わります。明示的な reply_to_* フィールドは、生のイベントをもはや保持していない呼び出し元向けのオーバーライドとして残されています。
リアクションもイベントベースです。 encrypt_add_reaction(target_event, emoji) と encrypt_remove_reaction(...) は、リアクションの対象となる生のイベントから会話 ID と対象シーケンス ID を導出します。同じパラメーターでリアクションの追加と後の削除ができます。生のイベントを保持していないときにのみ、conversation_id と target_message_sequence_id を明示的に設定してください。
受信側では、返信を引用する復号済みメッセージは reply_preview_validation("Valid" / "Invalid"。JS バインディングは 'valid' / 'invalid')を持ちます:SDK は埋め込まれたオリジナルの署名をあなたの署名鍵に対して検証し(イベントに含まれる鍵ではなく)、復号し、引用されたコンテンツと作者をそれに対して比較しました。プレビューが編集イベントを埋め込んでいる場合、SDK は編集を同様に検証し(同じ会話、オリジナルと同じ作者)、引用テキストを編集前のテキストではなく編集後の内容に対してチェックします。メッセージがプレビューを持たない、またはプレビューがオリジナルを埋め込まない場合、このフィールドは存在しません。Invalid なプレビューは信頼できないものとして扱ってください:メッセージ自体は本物ですが、引用素材はそうではありません——引用は検証済みオリジナルからのみ描画してください。
encrypt / decrypt は会話鍵下の UTF-8 メタデータ用です(たとえば暗号化されたグループ名)——メッセージエンベロープ用ではありません。encrypt_stream / decrypt_stream は添付ファイルのバイト列を暗号化します。メディア を参照してください。低レベルの sign / verify / verify_key_binding は高度なフローをサポートします。会話鍵の変更、グループ作成、メンバー追加は prepare メソッド によって署名されます。
encrypt_message / encrypt_reply に渡される会話 ID は、保持している任意の形式で構いません——イベントからの A:B、リスティングや URL パスからの A-B(順不同)、または裸の受信者ユーザー ID——SDK は署名前に正規化します。グループ ID(g プレフィックス付き)はそのまま渡ります。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
メディアストリーム
テキストと同じ会話鍵でファイルバイト列を暗号化し、Chat メディア API 経由でアップロードし、encrypt_message に media_hash_key を添付します。これは Posts のメディアモデル(expansions=attachments.media_keys)ではありません。完全なアップロード/ダウンロードのフロー:メディア。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
大きなメディア向けの増分ストリーミング
大きなファイルでは、ペイロード全体をメモリに保持することを避けてください:stream_encryptor() / stream_decryptor() は push(chunk) でチャンク(それぞれ約 1 MB)を送り込み、最後に一度 finish() を呼び出す StreamEncryptor / StreamDecryptor を返します。復号時、finish() は切り捨てられたストリームを検出します(最終フレームより前に入力が終わっている場合は失敗します)。したがって、成功するまで push されたプレーンテキストを完全と扱わないでください。
- Python
- TypeScript
ユーティリティ
Base64/hex ヘルパー、MIME スニッフィング、画像寸法は、モジュールレベルの関数(Python/JS/Rust/Go)またはChatXdkUtilities(C#/Java)として利用可能です——追加のライブラリを取り込まずに添付メタデータを構築するときに便利です。
- Python
- TypeScript
- Rust
- Go
- C#
- Java
重要な型
これらの概念的な型は各言語で登場します(正確なフィールド名は異なります。JS ではmessage のような camelCase のイベント識別子が使われることが多いです):
- SendPayload —
encrypt_messageおよび他の暗号化ヘルパーの戻り値:SDK 生成のmessage_id(署名済みイベントに埋め込まれた UUID——メッセージのmessage_idとして送信し、重複排除用に保持)、encrypted_content、encoded_event_signature、署名メタデータ、conversation_key_version、should_notify。Chat API の送信ボディにマップしてください。 - PublicKeyRegistrationPayload — add-public-key API 用の
generate_keypairs/ public-key ゲッターの出力。 - SigningKeyEntry — 署名検証のために復号に渡されるか、
set_signing_keysで保存される送信者の公開素材。 - PreparedConversationChange — 3 つの prepare メソッドの出力:導出または渡された
conversation_id、生のconversation_keyバイト、conversation_key_version、participant_keys(user_id、encrypted_key、public_key_version)、action_signatures(message_id、encoded_message_event_detail、signature、signature_version、public_key_version、オプションでsignature_payload——鍵変更署名では省略されます。そのペイロードには平文の鍵が埋め込まれるためです)。 - DecryptEventsResult — メッセージ、オプションのエラー、抽出された
conversation_keys。返信を引用する復号済みメッセージにはreply_preview_validationが付きます(暗号化と送信ヘルパー を参照)。
docs/API.md、*.pyi、index.d.ts)を使用してください。
エラー
Python は通常、記述的なメッセージ付きのValueError を送出します(たとえば無効なパスコード)。TypeScript/JavaScript は Error をスローします。Go は (value, error) を返します。1 つの不良イベントがバッチを中断しないよう、履歴には decrypt_events を優先してください。部分的な失敗については errors コレクションを検査してください。
一部の検証エラーは恒久的です。署名は不変であり、イベント自体から署名済みペイロードを再構築することで検証されます。そのため、signature missing or no matching signing key や ECDSA 不一致で失敗する古いイベントは、以後のロードでも毎回失敗します——リトライ、鍵の更新、API 呼び出しでは修復できません。これらは一時的なエラーではなく tombstone として扱ってください。会話鍵をローテーションすれば、そこから先はクリーンで検証可能な履歴が始まります。
次のステップ
はじめに
Chat XDK を Chat API に配線
メディア
ストリーム暗号化とメディア REST
リアルタイムイベント
Webhook とアクティビティ配信
トラブルシューティング
よくある失敗