Skip to main content
Chat XDK は X Chat の鍵管理、暗号化、復号、署名を処理します。X の HTTP API を呼び出すことはありませんPython または TypeScript XDK、あるいはユーザーアクセストークンを使った HTTPS と組み合わせてください。 アプリのウォークスルー: Getting Started。サンプルボット: chat-xdk/examples

インストール

PyPI パッケージは chatxdk です。chat_xdk としてインポートします。Python 3.10+ が必要です。

クイックスタート

鍵をロードし、identity を一度設定し、バックログを復号し、1 つのライブイベントを復号し、メッセージを暗号化します。Getting Started のように送信ボディを POST /2/chat/conversations/{id}/messages に接続します。 スニペットは、最短の呼び出し形式のために 2 つのオプションのセッションストアを使用します: set_signing_keys は他の参加者の公開鍵を保持し(public-keys エンドポイントから取得)、復号呼び出しは呼び出しごとの引数なしで送信者を検証でき、set_cache_keys(true) は SDK に各会話の検証済み鍵を記憶させるので、暗号化呼び出しは会話 ID とテキストだけを必要とします。どちらかをスキップして代わりに呼び出しごとに同じ値を渡してください — 両方のスタイルは同じように検証します;復号 を参照してください。

ライフサイクルと鍵

SDK を構築し、秘密鍵を保存し(パスコード保護された安全な鍵バックアップまたはローカル鍵 blob)、Chat API で公開鍵を登録し、unlock または import の後に set_identity(user_id, signing_key_version) を呼び出します — これは、すべての署名付きアクションがデフォルトで使用する送信者と署名鍵バージョンを設定するため、encrypt および prepare メソッドは呼び出しごとの identity 引数なしで動作します。デバイス/アプリの identity ごとに generate_keypairs を一度呼び出します;登録ペイロードを public-keys エンドポイントに POST します。すべてのバインディングで安全な鍵バックアップに setup / unlock(および関連するパスコードヘルパー)を使用します。export_keys / import_keys(ボットとサーバー向けの生の鍵 blob 永続化)はネイティブバインディングのみで利用可能です — Python、Go、.NET、JVM、Rust。JS/WASM バインディングは生の鍵のエクスポートやインポートを公開しません: ブラウザではインスタンスに到達するあらゆるスクリプトが identity を流出させる可能性があるため、JS は鍵を安全な鍵バックアップ内に保持します。リクエストごとのバックアップ realm ラウンドトリップを避けたい JS サーバーは、リクエスト間でアンロック済みの 1 つの Chat インスタンスを再利用するか、鍵 blob がサポートされているネイティブバインディングを実行してください。 SDK は、登録済み公開鍵について X API が報告するバージョンも必要とします。これにより、他のバージョンを対象とする鍵変更エントリはスキップされます。set_identity は、これをユーザー ID と一緒に記録します;import_keys はオプション引数として直接受け付けます(Rust と Go は import_keys_with_version / ImportKeysWithVersion を使用します)。
安全な鍵バックアップの設定は 3 つの形式を受け付けます: X API の juicebox_config オブジェクト(推奨 — そのまま渡します)、完全な sdk_config ラッパー、または裸の token_map オプション: 署名検証はデフォルトでオンです(reject_unverified = true) — 無効にするには set_reject_unverified(false) を呼び出します(推奨されません);バックアップ realm 設定が変更された場合は update_config;UI の状態のために is_unlocked / has_identity_key。完全なフィールドリストは chat-xdk リポジトリ のスタブにあります。

会話鍵

3 つの prepare メソッドは、鍵変更に必要なすべてを 1 回の呼び出しで実行します: 新しい会話鍵を生成し、(渡された公開鍵から)各参加者に対して暗号化し、変更に署名します。送信者 ID と署名鍵バージョンはセッション(set_identity)から取得されます;params 上で sender_id / signing_key_version を設定して上書きします。すべては同じ PreparedConversationChange 形状を返し、POST の準備ができています — conversation_participant_keys の SDK フィールド encrypted_keyencrypted_conversation_key にリネームし、アクション署名を必要な action_signatures ボディフィールドにマップします。 encrypt_message およびメディア用に未加工の鍵バイトを保持してください;API の暗号化エンベロープを暗号化に渡さないでください。
ラップする前に取得した鍵を検証してください。 prepare メソッドは、渡された任意の公開鍵に対して新しい会話鍵を暗号化します。渡す前に、各取得済みレコードに対して verify_key_binding(identity, signing, signature) を呼び出します — public-keys API のレコードの public_keysigning_public_keyidentity_public_key_signature フィールドを渡します — 置き換えられた identity 鍵が会話鍵を受け取れないようにします。
鍵変更イベントペイロードに対して extract_conversation_keys を使い、{ keys, latest_version } を再構築します。decrypt_conversation_key は 1 つの ECIES blob をアンラップします。
グループの作成とメンバー追加については、各メソッドが必要とする params を渡します(prepare_group_create にはメンバー/管理者 ID リスト;prepare_group_members_change には新規プラス現在のロスター) — サンプルは Groups を参照。両方とも2 つのアクション署名を返します;POST には両方を含める必要があります。

復号

decrypt_events は履歴とバックログ用です: ストリームから会話鍵を取り出し、復号済みメッセージを返し、バッチ全体を失敗させる代わりにイベントごとのエラーを収集します。decrypt_event は 1 つのライブイベント用です;失敗時に raise/throw します。 SDK が送信者を検証できるように署名鍵を渡します。API の public-key フィールドを SigningKeyEntry にマップします: public_key_versionpublic_key_version(同じ名前)、signing_public_keypublic_keypublic_keyidentity_public_key、加えて identity_public_key_signatureuser_id 2 つのオプトインセッションストアを使用すると、呼び出しごとの鍵引数を省略できます:
  • set_signing_keys(entries) は参加者の署名鍵を保存します;署名鍵引数を省略(または空を渡す)した復号呼び出しは、代わりにストアを使用します。検証自体は変わりません — 鍵は復号中のイベントからではなく、この呼び出しを通してのみストアに入ります。各呼び出しは前のセットを置き換えます。
  • set_cache_keys(true) は会話鍵キャッシュを有効にします(デフォルトではオフ)。有効な間、decrypt_events は、鍵変更が有効な署名を持っていた最新の鍵を会話ごとにキャッシュします;decrypt_event は会話鍵引数が省略されるとそこにフォールバックし、encrypt ヘルパーは省略された会話鍵をそこから解決します。無効にするとキャッシュはクリアされます。
明示的な空でない引数は常にストアより優先されます。明示的な呼び出しごとの引数はファーストクラスのままで — サーバーレスやマルチインスタンスデプロイでは正しい選択です。そこではリクエストが、ストアが空のフレッシュなインスタンスに着地することがあります。 検証はデフォルトで必須です: 署名鍵を省略してもそれをスキップしません。何も渡されず、何も保存されていない場合、署名付きイベントは失敗します(decrypt_events の場合は errors に収集され、decrypt_event の場合はスローされます)。実際に検証をスキップするには、最初に set_reject_unverified(false) を呼び出す必要があります(本番では推奨されません)。

暗号化と送信ヘルパー

encrypt_message(conversation_id, text) はテキストメッセージ用の署名付き暗号文を構築します;オプションで entitiesattachmentsmedia_hash_key 経由)、should_notifyttl_msec。送信者 ID はセッション(set_identity)から、会話鍵はオプトインの鍵キャッシュ(set_cache_keys)から解決されます — または sender_id / signing_key_versionconversation_key + conversation_key_version を明示的に渡します。SDK は message_id(署名付きイベントに埋め込まれた UUID)を生成し、ペイロードで返します — 自分で生成しないでください;再試行時には同じペイロードを再利用して、ID が二度と生成されないようにしてください。ペイロードを送信メッセージボディにマップします: message_idmessage_idencrypted_contentencoded_message_create_eventencoded_event_signatureencoded_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 を導出します;同じ params でリアクションを追加し、後で削除できます。未加工のイベントをもう保持していない場合のみ、conversation_idtarget_message_sequence_id を明示的に設定してください。 受信側では、返信を引用する復号済みメッセージには reply_preview_validation"Valid" / "Invalid";JS バインディングは 'valid' / 'invalid' を使用)が付与されます: SDK は、埋め込まれたオリジナルの署名を、イベントに含まれる鍵ではなく、あなたの署名鍵に対して検証し、復号し、引用コンテンツと作者をそれと比較しました。プレビューが編集イベントを埋め込む場合、SDK は編集を同じ方法で検証し(同じ会話、同じ作者)、引用テキストを編集前のテキストではなく編集済みコンテンツと照合します。メッセージにプレビューがない、またはプレビューにオリジナルが埋め込まれていない場合、フィールドは存在しません。Invalid プレビューは信頼できないものとして扱ってください: メッセージ自体は真正ですが、引用素材はそうではありません — 引用は検証済みオリジナルからのみレンダリングしてください。 encrypt / decrypt は、会話鍵を使った UTF-8 メタデータ用です(たとえば暗号化されたグループ名) — メッセージエンベロープではありません。encrypt_stream / decrypt_stream は添付バイトを暗号化します;Media を参照。低レベルの sign / verify / verify_key_binding は高度なフローをサポートします;会話鍵変更、グループ作成、メンバー追加は prepare メソッド が署名します。 encrypt_message / encrypt_reply に渡す会話 ID は、保持している任意の形式で構いません — イベントからの A:B、リストや URL パスからの A-B(どちらの順序でも)、または受信者のユーザー ID だけ — SDK は署名する前に正規化します。グループ ID(g プレフィックス付き)はそのまま渡されます。

メディアストリーム

テキストで使用したのと同じ会話鍵でファイルバイトを暗号化し、Chat メディア API 経由でアップロードし、encrypt_messagemedia_hash_key を添付します。これは Posts メディアモデル(expansions=attachments.media_keys)ではありません。完全なアップロード/ダウンロードフロー: Media

大きなメディア向けのインクリメンタルストリーミング

大きなファイルの場合、ペイロード全体をメモリに保持するのを避けます: stream_encryptor() / stream_decryptor()StreamEncryptor / StreamDecryptor を返し、push(chunk) でチャンク(約 1 MB ずつ)を供給し、最後に finish() を 1 回呼び出します。復号時、finish() は切り詰められたストリームを検出します(入力が最終フレームより前に終了した場合失敗します)ので、成功するまでプッシュ済み平文を完全とみなさないでください。
JS/WASM のみ: finish() は基盤となる WASM オブジェクトを消費して解放します — finish() の後に決して free() を呼び出さないでください(スローします)。free() は、finish のにストリームを放棄する場合(たとえばエラー経路)のみ呼び出してください。

ユーティリティ

Base64/hex ヘルパー、MIME 検出、および画像寸法は、モジュールレベルの関数(Python/JS/Rust/Go)または ChatXdkUtilities(C#/Java)として利用できます — 追加のライブラリを引き込むことなく添付メタデータを構築するのに便利です。

重要な型

これらの概念的な型は言語をまたがって出現します(正確なフィールド名は異なります;JS はしばしば message のような camelCase のイベント識別子を使います):
  • SendPayloadencrypt_message およびその他の暗号化ヘルパーの戻り値: SDK 生成の message_id(署名付きイベントに埋め込まれた UUID — メッセージの message_id として送信し、重複排除のために保持)、encrypted_contentencoded_event_signature、署名メタデータ、conversation_key_version、および should_notify。Chat API 送信ボディにマップします。
  • PublicKeyRegistrationPayload — add-public-key API 用の generate_keypairs / 公開鍵ゲッターの出力。
  • SigningKeyEntry — 署名検証のために decrypt に渡す、または set_signing_keys 経由で保存する送信者の公開素材。
  • PreparedConversationChange — 3 つの prepare メソッドの出力: 導出または渡された conversation_id、未加工の conversation_key バイト、conversation_key_versionparticipant_keysuser_idencrypted_keypublic_key_version)、および action_signaturesmessage_idencoded_message_event_detailsignaturesignature_versionpublic_key_version、オプションの signature_payload — 鍵変更署名では、そのペイロードが平文の鍵を埋め込んでいるため省略されます)。
  • DecryptEventsResult — メッセージ、オプションのエラー、および抽出された conversation_keys。返信を引用する復号済みメッセージには reply_preview_validation が付与されます(暗号化と送信ヘルパー を参照)。
完全なフィールドリストについては、chat-xdk リポジトリ の言語スタブ(docs/API.md*.pyiindex.d.ts)を使用してください。

エラー

Python は通常、記述的なメッセージ付きの ValueError を発生させます(たとえば無効なパスコード)。TypeScript/JavaScript は Error をスローします。Go は (value, error) を返します。1 つの不正なイベントがバッチを中止しないよう、履歴には decrypt_events を優先してください;部分的な失敗については errors コレクションを検査します。 一部の検証エラーは恒久的です。署名は不変であり、イベント自体から署名済みペイロードを再構築することで検証されるため、signature missing or no matching signing key や ECDSA 不一致で失敗する古いイベントは、将来のすべてのロードで失敗します — 再試行、鍵の更新、または API 呼び出しでは治せません。これらはトゥームストーンとして扱い、一時的なエラーとしないでください。会話鍵をローテーションすると、その時点からクリーンで検証可能な履歴が始まります。

次のステップ

Getting Started

Chat XDK を Chat API に接続する

Media

ストリーム暗号化とメディア REST

Real-time events

Webhook とアクティビティ配信

Troubleshooting

よくある失敗