技術の詳細
プロトコル、エラーコード、アクセシビリティと、各説明を裏付ける状況。
このページは、詳細を知りたい人向けです。ここにある内容はすべて、測定またはソースの確認に基づき、推定ではありません。
ウィジェットの読み込み
2段階で読み込みます。最初は、ボタンを描画するだけの小さなローダーです。チャット本体を取得するのは、5つのトリガーのいずれかが発生したときです。ブラウザーがアイドル状態になる(遅くとも3秒後)、マウスや指がボタンに触れる、ページからコマンドが来る、MousePlayerから不満のシグナルが来る、サービスワーカーなどからプッシュの呼びかけが来る、という条件です。
理由があります。大半の訪問者はチャットを開きません。その人たちのページ読み込みを遅らせないためです。適用するトリガーはscriptタグで設定します。
- ローダー: 当社CDNのgzip転送で3.48 kB
- ウィジェット全体: 同じ方式で85.5 kB。いずれかのトリガーが発生した後にのみ転送
- ボタンが表示されるまで: 11~21 ms
- レイアウトのずれ: 0.0000。表示前に領域を確保
比較として、3つともbrotliで圧縮して測定すると、Crispのローダーは2,876 B、Intercomは3,161 Bです。当社は3,069 Bでその間にあり、桁違いに小さいわけではありません。そう主張するなら、測定していないということです。
Webサイトに干渉しない
ウィジェットは閉じたshadow DOM内にあります。ページのスタイルはウィジェットに届かず、ウィジェットのスタイルもページに届きません。* { box-sizing: border-box }を設定したり、全体を再定義するCSSフレームワークを使ったりしても同じです。
厳格なContent Security Policyの下でも、コンソールメッセージを1つも出さずに動作します。eval、Webフォント、トラッキングピクセルは使いません。スタイルはstyle-srcの対象外であるconstructable stylesheetsで設定します。そのため、ボタン、チャットウィンドウ、製品ツアー、サイト上のオペレーターコンソールにはunsafe-inlineが不要です。style-src 'self'でも、style-src 'none'でも測定し、違反はゼロで、すべてのスタイルが適用されました。現在のChromiumでの測定です。Safari 16.4より前など、constructable stylesheetsに未対応の古いブラウザーでは、<style>要素にフォールバックするため、厳格なポリシーがブロックします。
他のサーバーへのリクエストはゼロです。 すべてreactive.chatから、独自ドメインでは運営側のアドレスから取得します。ロゴやアバターなどの画像は、運営側が指定したアドレスから取得します。
プロトコル
接続にはWebSocketを使い、ネットワークが通さない場合は通常のHTTPSリクエスト(Server-Sent Eventsまたはロングポーリング)を使います。プロトコルはバージョン管理され、31個のエラーコードを定義しています。26個はウィジェット用、残りはオペレーター画面とサイト内検索用です。それぞれにクライアントの対応(即時再試行、待機後に再試行、再接続後に再試行、再試行しない)を定め、一部には切断コードもあります。一覧にないエラーは一時的なサーバーエラーとして扱います。待機後に再試行し、5回試しても失敗したメッセージは未配信となり、再送信できます。無限に繰り返すことはありません。
待機時間を延ばしながら再接続します。 接続が切れるとメッセージをバッファーに保持し、復旧次第送信します。各メッセージにはIDがあり、サーバーが再送を認識して重複保存しません。
アクセシビリティ
WCAG 2.2 AAに沿って構築しています。
- 開いたウィンドウ内にフォーカスを保持し、ESCで閉じ、元の場所に戻す
aria-liveで新着メッセージを通知- テキストと表面色のコントラストを、想定ではなく計算。下記参照
- キーボードだけで操作でき、フォーカスリングが見える
コントラストを計算する
色を指定すると、表面色はその色をそのまま使います。その上のテキストは、通常のテキストに対するWCAG要件の4.5:1に達するまで調整します。
178色、2テーマ、3組み合わせの計1,068データ点で測定し、4.5:1未満は1つもなく、最小値は4.50:1でした。
他のサービスとの違いはここです。他では、誰にも読めなくなるまでウィジェットの設定を変えられます。
個人データ
マスクは2か所で行います。端末から何かが出る前に訪問者のブラウザーで行い、保存前にサーバーでも行います。カード番号(Luhn検査付き)、IBAN、メールアドレス、電話番号、税番号、身分証番号を認識します。注文番号と顧客番号は変更しません。
1か所では不十分なので、2か所です。ブラウザー側は無効にでき、サーバー側には届いたものしか見えません。
ルール
ウィジェットが話しかけるタイミングは、コード内の条件ではなく宣言的なルール一覧で定義します。既定で6つのルールがあります。ページへの滞在、連続クリック、JavaScriptエラー、入力に行き詰まったフォーム、購入意図、購入手続きからの離脱です。連続クリック、フォームの行き詰まり、購入意図は、MousePlayerと組み合わせた場合だけ検出します。独自のルールはアカウントで追加できます。Freeプランでは、1プロジェクトで有効な呼びかけ1つが適用されます。
実用上の違いは、ルール変更にデプロイは不要で、アカウントの設定を変えるだけという点です。
連携
WebhookとSlackは完成しています。さらに30を超えるサービスへの接続を用意しています。大半は模擬環境でテストしていますが、実際のサービスではまだ動作しておらず、アカウントの連携ページにもその旨を表示します。
サーバーAPI(RESTとMCP)は、会話、メッセージ、プロジェクト、訪問者、イベント、ルールを読み取り、メッセージやイベントを書き込み、Webhookを登録します。訪問者一覧とMCPは、プロジェクトごとに無効にできます。
各連携は、サーキットブレーカー付きのキューで処理します。第三者サービスが応答しなければ、繰り返し失敗した後、しばらくスキップします。チャットメッセージを止めないことが、この層で最も重要なルールです。
未完成の部分
導入中に初めて気付くことがないよう、次を明記します。
- MousePlayerが合意したイベントをまだ自発的に発行しないため、ブリッジはポーリングします。
- 添付ファイル、A/Bテスト、独自ドメインはベータ版です。動作し、測定済みですが、今後変わる可能性があります。
- メール、Telegram、SMS、WhatsApp、Messenger、Instagramのチャネルは、模擬環境でテストしており、実際のアカウントではまだです。チャネル経由の返信が最終的に失敗しても、現在は会話に表示されません。
ドキュメントの関連項目
ウィジェット、サーバー、接続の連携:構成と処理の流れ。接続、HTTPフォールバック、再接続:通信。すべての章:ドキュメント。
最終更新: