Skip to main content
Ayrshare Connect ウィジェットは、当社の連携ボタンを貴社自身のダッシュボードの中に配置します。 スクリプトを 1 つ読み込み、レイアウト内でネットワークを置きたい場所にスロットを置くと、当社がそこに ボタンをレンダリングします。ボタンにはアカウントが接続済みかどうかがすでに表示されています。ユーザー はそれをクリックし、貴社のページを離れることなくアカウントを連携します — 表示されるポップアップは 最大でも 1 つ、ネットワーク自身のものだけです。 ポップアップの処理も、OAuth コールバックも、セッションのリフレッシュも、ネットワークごとのロジックも 書く必要はありません。ネットワーク側で何かが変更されたときは、当社がデプロイした瞬間に修正が当社の フレーム内に反映されます。貴社が再デプロイするものはありません。

どのサーフェスを使うべきか

A customer dashboard with Ayrshare Connect tiles for Instagram, TikTok and LinkedIn embedded in a card

埋め込みフレーム: 貴社自身のレイアウト内にレンダリングされる当社のタイル。ネットワークごとに 1 スロット、または複数ネットワークで 1 スロット。

A customer dashboard with its own Connect buttons and an Ayrshare popup showing the Facebook hand-off screen

独自のボタン: ボタンは貴社がレンダリングし、当社の短時間のポップアップ 1 つがネットワークを処理します。

The hosted social linking page showing every available network

ホスト型リンクページ: 当社がホストし、貴社のロゴとカラーが反映されたページ。ユーザーは貴社のアプリを離れて使用します。

ウィジェットの 2 つの行は 2 つの統合ではなく、1 つの統合です。1 回の init で両方が使えます: 当社のボタンを置きたい場所にフレームをマウントし、それ以外の場所では独自のボタンから popup() を 呼び出します。両者は 1 つのセッションを共有し、同じハンドラーに結果を報告します。ダイレクトモード(Direct Mode)は、当社のスクリプトなしの 同じポップアップです — 厳格な Content-Security-Policy を持つページ、サーバーレンダリングされる ページ、ネイティブアプリ向けで、この場合はポップアップを自分で開いて監視します。

スクリプトの追加

バージョンとそのハッシュを固定するか、ハッシュなしでチャンネルを追従するかのどちらかにしてください。 両方は決して行わないでください — 変化する URL に integrity 属性を付けると、次のリリースで動作 しなくなります。その URL が指すファイルが正当に変更されるためです。
Pinned version
Tracking v1
推奨するチャンネルは v1 です。 修正は取り込みますが、破壊的変更を跨ぐことはありません。 latest は定義上メジャーバージョンを跨ぐため、いずれは動作を確認していないバージョンを貴社の ページに渡すことになります。 各バージョンのハッシュは manifest.json で公開されており、各 チャンネルが現在何を配信しているかもここに記載されています:
manifest.json
各バンドルは自身のバージョンを記したコメントで始まります。ページが実際に何を実行しているかを当社に 伝える最速の方法です:

Content-Security-Policy

ページが Content-Security-Policy を送信している場合、2 つのエントリが必要です。どちらも スクリプトの読み込み元ホストを指定します:
必要なのはこれだけです。当社向けの connect-src エントリは不要で — 当社のフレームは貴社の ページからではなくフレーム内部から当社の API に到達します — ポップアップ用のエントリも不要です。 ポップアップは貴社のポリシーが管理しないトップレベルのウィンドウだからです。どちらのエントリも実測で 確認済みです: script-src を外すとスクリプトがブロックされ、frame-src を外すとフレームがブロック されます。

インスタンスの開始

必須のオプションは session だけです。これはマウントごとではなくインスタンスごとに 1 回 呼び出され、mode: "connect" を指定した Link Session の作成へのバックエンドのレスポンス — { sessionId, token, expiresAt } — を、返ってきたそのままの形で返す必要があります。
Your page
Your backend
ウィジェットのセッションは network指定しません — アカウントが許可するすべてのネットワーク を認可し、どのネットワークを表示するかは貴社のページでマウントごとに決まります。一方で origin は 必ず含みます。これこそがフレームをレンダリングさせる唯一の要素です: フレームは自身を埋め込んでいる ページをその値と照合し、それ以外の場所ではレンダリングを拒否します。
セッションはサーバー上で作成してください。この呼び出しには API Key が必要で、返されるトークンは ユーザーを User Profile にサインインさせます — パスワードと同様に扱ってください。
トークンの期限が切れる前に当社が session を再度呼び出すため、終日開きっぱなしのページでも ウィジェットは動作し続けます。reject した呼び出しや、トークンを返さなかった呼び出しは、0.5 秒後、 次に 1 秒後の計 2 回再試行され、その後に諦めて error を発行します。つまり 1 回のリフレッシュで 貴社のエンドポイントへの呼び出しは最大 3 回です。

スロットのマウント

スロットごとに 1 回の mount です。1 つのネットワーク、複数、またはセッションが許可するすべてを 要求できます — 粒度は貴社次第なので、スロットは既存のテーブルの 1 行にも、すべてをまとめた 1 つの パネルにもなります。
mount は CSS セレクタまたは要素を受け取り、{ unmount, element } を返します。ターゲットが何にも 一致しない場合は throw します — ほとんどの場合、まだ存在しないスロットが原因なので、マークアップが ドキュメントに入った後にマウントしてください。 各マウントは 1 つの iframe です。フレームは自身の高さを当社に報告し、当社がそれに合わせてリサイズ するため、当社のコンテンツの変化に応じて貴社のレイアウトはリフローします。maxHeight を超えると、 フレームはページからはみ出す代わりに内部でスクロールします。サポートする最小のスロット幅は 300px です。 ネットワークキーは Ayrshare 自身のもので、エイリアス表記も使えます: instagraminstagramapi はどちらも instagramApi を意味し、xtwitter を意味します。ネットワークでないキーはタイルを レンダリングしません。

独自のボタン

当社のフレームより自社のボタンを使いたいお客様は、代わりに popup を呼び出します。同じセッション上 で同じフローが実行され、同じハンドラーに報告されます。
クリックハンドラーの中で、何も await せずに直接呼び出してください。 ブラウザは、ユーザーの クリックを処理している間しかポップアップを許可せず、その許可は await を越えて存続しません。 そもそも await するものはありません — セッションは init の時点で作成済みです。
popup{ close(), network } を返し、常にハンドルを返します — ポップアップがブロックされた 後(この場合 close() は何もしません)を含めてです。そのため、close() を呼ぶ前にコードで null チェックをする必要はありません。 ここではすべてのネットワークが動作します。フレームなら自身のパネル内で完結するものも含まれます: Facebook はハンドオフの説明をポップアップに表示し、Bluesky と X は認証情報フォームを表示し、 LinkedIn、Pinterest、YouTube、Google Business はネットワークへ出て戻ってきます。 プログラミング上の誤りである 3 つのケース — network がない、破棄されたインスタンス、まだ解決して いないセッション — に対しては同期的に throw します。ブロックされたポップアップはこれに含まれません: その場合は reason: "popupBlocked" を伴う error が発行されます。ユーザーは何も間違っていないから です。 一度に開くポップアップは最大 1 つです。2 回目の呼び出しは 1 つ目を閉じ、そちらに reason: "superseded"cancelled を報告します。当社のフレームが開いたポップアップは別物で あり、決して触れられません。そのため、貴社のボタンがマウント済みスロット内で進行中のフローを キャンセルすることはありません。
セッションがそのネットワークを連携できるかどうかは、スクリプトではなくサーバーが答えます。 Bluesky にスコープされたセッションで LinkedIn を要求すると、拒否がポップアップ内にレンダリング され、error として報告されます。スクリプトが確認するのは、ネットワークが指定されたかどうか だけです。

React

スクリプトはフレームワークに依存しないため、React に特別な対応は不要です — ただし、ライフサイクル について最初から正しくしておく価値のあることが 4 つあります。 スクリプトはコンポーネントツリーの外で一度だけ読み込んでください。Next.js ならルートレイアウトの next/script、Vite や Create React App なら index.html のタグです。コンポーネントごとに読み込む と、マウントのたびに再実行されます。
ConnectAccounts.jsx
destroy() の後にインスタンスを再利用してはいけません。 破棄されたインスタンスは破棄された ままです — popup() は throw し、mount() で復活することもありません。上記コードのように、次の effect の実行で新しいインスタンスを作成してください。
このパターンには 2 つの帰結があり、どちらもバグではありません:
  • 開発時には session コールバックが 2 回発火します。 React の Strict Mode は effect を mount → unmount → mount の順に実行するため、インスタンスは作成、破棄、再作成されます。上記の クリーンアップがそれを安全にします。コストは開発時のバックエンドへの 1 回の追加呼び出しだけで、 本番ではゼロです。
  • effect の依存配列を安定させてください。 親の render から mount に直接渡された配列リテラルは 毎回新しい値になるため、それに依存する effect は render のたびにウィジェットを破棄して再構築 します。メモ化するか、上記のように定数にしてください。

イベント

on で購読します。on は購読解除関数を返します。ハンドラーはイベントペイロードと、その発生元の マウントを受け取ります。ハンドラーを名前で指定したい場合は off(name, handler) が同じ役割を 果たします。
イベントは 10 個です。ready と、ネットワークとはまったく無関係な種類の error を除き、すべてが network を伴います — 下記の error には 2 つの発生源があるを参照して ください。 このうち 4 つが結末ですsuccessunlinkederrorcancelled で、試行ごとにちょうど 1 つが届きます。closed は結末ではなく、結末の後に続くライフサイクル通知です。 click は連携処理が始まるに発火するため、ブロックされたポップアップや失効したセッションに よって拒否されることになるクリックも報告します。貴社独自のアナリティクスにはこのイベントを使って ください。試行が実際に進行していることを意味するのは started です。

Reason

error には 2 つの発生源がある

連携の失敗はそのうち 1 つだけで、それぞれ異なるフィールドを持ちます。
  • 連携エラーnetworkcode、そして発生元のマウントを伴います。
  • セッションエラー — セッションを作成またはリフレッシュできなかった場合 — は message のみを 伴います。その時点では何も連携されていなかったからです。
防御的に分割代入してください: 後者では codenetworkundefined です。

state でポーリングが不要になる

state は、試行の報告ではなくデータチャンネルです。各フレームはマウント時にネットワークごとに 1 つ 発行し、そのネットワークの現在の状態と、それを保持し始めた since タイムスタンプを伝えます。さらに 状態が変わるたびにもう 1 つ発行されます — トークンが失効して再連携が必要になった場合など、当社側で 発生した変化も含みます。つまり、何もポーリングせずに UI 全体をウィジェットから駆動できます。 値は GET /profilesinclude=state が返すのと同じ enum です: linkedunlinkedidentityVerificationRequiredrestrictedrateLimitedsuspended

リンク解除

当社のタイルは連携だけでなくリンク解除も行います。ユーザーが接続済みネットワークをクリックし、確認 すると、アカウントが削除されます:
  1. action: "unlink" を伴って click が発火します。
  2. 削除が保存されると unlinked が発火します。
失敗したリンク解除は error を報告し、確認ステップでユーザーがやめた場合は cancelled を報告 します。リンク解除失敗の専用イベントはありません。

外観

お客様のスタイルシートはクロスオリジンフレームの内部には届かないため、スタイルはデータとして渡され、 当社がフレーム内で適用します。appearance を CSS カスタムプロパティとして init に渡してください。 受け取らなかったものはそれぞれ当社のデフォルトのままになります。
色はペアで設定してください。 前景トークンを添えずに背景トークンだけを設定することが、読めない ものを生み出す唯一の方法です: --ayr-connect-surface-bg だけを暗い値に設定しても、当社のデフォルト の --ayr-connect-surface-fg は依然として濃いネイビーのままです。もう片方を推測してくれるものは ありません。
appearance をまったく渡さない場合、すべてのトークンはデフォルトを保持し、フレームは次のように 表示されます:
Three Ayrshare Connect tiles with the default appearance

デフォルトのトークン: 白のサーフェス、濃いネイビーのテキスト、インディゴのアクセント、8px の角丸。

いくつかのトークンを渡すだけで、同じフレームが貴社のパレットになります。この例ではサーフェスを淡い ブルーにし、テキストとアクセントをそれに合わせて深くし、角をもう少し丸くしています:
Three Ayrshare Connect tiles restyled with pale blue surfaces and a deeper blue accent

上記のトークンを適用した後の、同じ 3 つのタイル。

パレットは 1 つで、ライト/ダークのプリセットはありません。 prefers-color-scheme に反応する ものは意図的にありません — 貴社のページのテーマはユーザーの OS 設定と一致するとは限らず、メディア クエリは貴社が選んだ色を黙って上書きしてしまうからです。ダークなダッシュボードには、ダークな値を 渡してテーマを適用します。 このトークン一覧は、バージョンを跨いで維持されるサポート対象の契約です。

トークン一覧

そのトークンにとって有効な CSS でない値は、適用されるのではなくコンソールに警告を出して無視 されます。これは見た目以上に重要です: --ayr-connect-spacing に単位なしの 8 を渡すのはまったく 無害な文字列に見えますが、適用されればそれを読むすべての計算を無効にし、どこにもエラーを出さずに レイアウトを崩壊させます。長さには単位を付けてください。

ハンドオフ画面に貴社の名前を表示する

ユーザーをネットワークに引き渡す前に、誰を通じて接続しているのかを示す短い画面を表示します。これを 貴社のものにするためのフックが 2 つあり、どちらもバージョン間で安定しています。 --ayr-connect-partner-name はラベルを設定します。値がテキストである唯一のトークンなので、CSS 文字列として引用符で囲む必要があります — 引用符のない値は無効で、何もレンダリングされません:
ロゴはトークンではありません。当社はマークを位置とサイズが決められた要素として提供し、貴社は上記の ように cssbackground-image で埋めます — 当社のドキュメント内から画像を取得できるトークンは 受け付けられないため、リクエストは貴社が渡した値からではなく、貴社が書いたルールから発生します。
[data-ayr-connect-partner-mark][data-ayr-connect-partner-name] は、下記のカスタム CSS の 注意書きの例外です: この 2 つのセレクタは契約の一部であり、バージョンを跨いで維持されます。

カスタム CSS

css は、トークンでカバーできないケースのために、すべてのフレーム内に適用される文字列を受け取り ます。
カスタム CSS はバージョンを跨いでサポートされません。 そのセレクタは当社の内部マークアップを 対象としており、これはリリース間で変わります — 今日動くルールが、更新後に静かにマッチしなくなる ことがあります。維持されるのは上記のトークン契約です。カスタム CSS に依存する場合はバージョンを 固定してください。
ポップアップはフレームと同様にインスタンスの appearancecss を継承するため、フローの途中で 当社の無個性なデフォルトが現れるのをユーザーが目にすることはありません。

リリース前に知っておくべきこと

popup() で開いたポップアップには、トークンが拒否された理由を伝えられません — 伝えるには、まだ 検証していないオリジンを信頼する必要があり、当社のセキュリティモデルはそれを許可しないためです。 そのため、失効したトークンを持つポップアップは閉じられ、error ではなく reason: "popupClosed"cancelled として現れます。実際にはこれは稀です: サイレントリフレッシュの前に開かれたポップアップは、開いた時点でトークン を検証しているため動作し続けます。説明のつかない popupClosed が発生する場合は、session エンドポイントが新しいセッションを返していることを確認してください。
14 個のマウントは 1 つのトークンを共有し、バックエンドへの呼び出しは 14 回ではなく 1 回です。 スコープの異なるスロット — 一部だけ別の allowedSocial — が必要な場合は、マウントで絞り込める ことを期待するのではなく、独自のセッションを持つ 2 つ目の init を実行してください。
すべてのセッションは、貴社のページが動作する origin を保持しており、フレームは何かをレンダリング する前に、自身を埋め込んでいるページをその値と照合します。別の場所に埋め込まれたフレームは空白の ままで、イベントも送信しません。登録するホワイトリストも設定項目もありません — セッション作成時に 正しい origin を送ってください。
フレームは高さをスクリプトに報告し、スクリプトがリサイズします。貴社のレイアウトはただリフロー します。購読すべき resize イベントはなく、貴社側で測定するものもありません。

要件

  • Max Pack。ウィジェットのセッションは connect モードのセッションであり、 Max Pack なしで作成すると code: 504 が返されます。Max Pack のないアカウントで connect モードを 有効にする必要がある場合は、サポートにお問い合わせください。
  • すべてのセッションに origin — 貴社のページが動作する正確なオリジン。省略すると code: 505 が返されます。https オリジン、カスタムスキーム、http://localhost のいずれでも ない値は code: 506 を返します。
  • セッションに network を指定しないこと。このパラメータはセッションを ダイレクトモードにするものであり、ダイレクトモードの セッションの URL はスクリプトが期待するものではありません。
上記のすべてのコードは、API が返す正確なメッセージと対処方法とともに Link Session エラーリファレンスに記載されています。