Skip to main content
Ayrshare Connect 小工具將我們的連結按鈕放進你自己的儀表板。你載入一個指令碼,在版面中每個 網路所屬的位置放一個插槽,我們就會在那裡渲染一顆按鈕,且按鈕已經顯示該帳號是否已連結。你的 使用者點擊它,不必離開你的頁面就能連結帳號——最多只會出現一個彈出視窗,也就是社群網路自己的視窗。 你不需要撰寫任何彈出視窗處理、OAuth 回呼、工作階段更新或針對個別網路的邏輯。當某個網路在他們 那一端有所變動時,修正會在我們部署的那一刻直接送進我們的框架中;你什麼都不用重新部署。

你需要哪一種介面

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

內嵌框架:我們的方塊渲染在你自己的版面中,每個網路一個插槽,或一個插槽容納多個網路。

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

你自己的按鈕:按鈕由你渲染,我們短暫的彈出視窗負責處理社群網路。

The hosted social linking page showing every available network

代管連結頁面:由我們代管、帶有你的 logo 與顏色的頁面,你的使用者離開你的應用程式來使用它。

兩個小工具列是同一個整合,不是兩個。單一 init 便同時提供兩者:在你想放我們按鈕的位置掛載框架, 並在其他任何地方從你自己的按鈕呼叫 popup()。它們共用同一個工作階段,並在相同的處理常式上回報。直接模式(Direct Mode)不使用我們指令碼的同一個彈出視窗—— 適用於帶有嚴格 Content-Security-Policy 的頁面、伺服器端渲染的頁面,或原生應用程式。在那裡, 你自行開啟並監看彈出視窗。

加入指令碼

釘選一個版本及其雜湊值,或追蹤一個不帶雜湊值的頻道。切勿兩者並用——在會變動的 URL 上加 integrity 屬性,會在我們下一次發布時失效,因為它所指的檔案已經合法地變更了。
Pinned version
Tracking v1
**v1 是我們建議的頻道。**它會取得修正,但絕不會跨越破壞性變更。latest 依定義會跨越主要版本, 因此它終究會把一個你尚未審閱過其行為的版本交給你的頁面。 每個版本的雜湊值都發布在 manifest.json 中,該檔案也記載了 每個頻道目前提供的版本:
manifest.json
每個 bundle 的開頭也有一行註解標明自身的版本,這是告訴我們某個頁面實際執行哪個版本的最快方式:

Content-Security-Policy

如果你的頁面會送出 Content-Security-Policy,需要兩個項目,兩者都指向你載入指令碼的主機:
清單就這麼多。你不需要為我們加入 connect-src 項目——我們的框架從它們自己內部呼叫我們的 API,而不是從你的頁面——也不需要為彈出視窗加入任何項目,因為彈出視窗是頂層視窗,不受你的 政策管轄。這兩個項目都經過實測:移除 script-src 會封鎖指令碼,移除 frame-src 會封鎖框架。

啟動一個實例

session 是唯一必要的選項。它會被呼叫每個實例一次,而不是每次掛載一次,且必須回傳你的 後端對 建立 Link Session(帶 mode: "connect")的回應—— { sessionId, token, expiresAt }——原封不動地回傳。
Your page
Your backend
小工具的工作階段指定 network——它授權你的帳戶允許的每一個網路,而哪些網路會出現,是在 你的頁面中由每次掛載決定的。它確實帶有 origin,這是讓框架得以渲染的唯一關鍵:框架會將嵌入它 的頁面與該值比對,並拒絕在其他任何地方渲染。
請在你的伺服器上建立工作階段。這個呼叫需要你的 API Key,而它回傳的 token 會讓你的使用者登入 他們的 User Profile——請像對待密碼一樣對待它。
我們會在 token 過期之前再次呼叫 session,因此在整天開著的頁面上,小工具仍能持續運作。若某次 呼叫被拒絕或未回傳 token,會再重試兩次——分別在 0.5 秒與 1 秒後——之後我們才放棄並發出 error。 所以一次更新最多只需要三次對你端點的呼叫。

掛載一個插槽

每個插槽一次 mount。可以要求一個網路、多個網路,或工作階段允許的所有網路——顆粒度由你決定, 所以插槽可以是現有表格中的一列,也可以是容納全部內容的一個面板。
mount 接受一個 CSS 選擇器或一個元素,並回傳 { unmount, element }。若目標不符合任何元素, 它會拋出例外——這幾乎總是因為插槽還不存在,所以請在你的標記已進入文件後再掛載。 每次掛載就是一個 iframe。它會向我們回報自己的高度,我們再調整 iframe 的大小以配合,因此你的 版面會隨我們的內容變化而重排;超過 maxHeight 後,框架會改為在內部捲動,而不會溢出你的頁面。 我們支援的最窄插槽為 300px。 網路鍵名採用 Ayrshare 自己的名稱,別名拼寫也可以使用:instagraminstagramapi 都代表 instagramApix 代表 twitter。不是網路的鍵名不會渲染任何方塊。

你自己的按鈕

寧可使用自己的按鈕、不想使用我們框架的客戶,可以改為呼叫 popup。它執行相同的流程、 使用相同的工作階段,並在相同的處理常式上回報。
**請在點擊處理常式中直接呼叫它,且之前不能有任何 await。**瀏覽器只在仍在處理使用者點擊的 期間允許開啟彈出視窗,而這個許可撐不過一個 await。反正也沒有什麼需要 await——工作階段在 init 時就已建立。
popup 回傳 { close(), network },且一定會回傳一個 handle——包括彈出視窗被封鎖時 (此時 close() 不做任何事)——因此你的程式碼在呼叫 close() 之前永遠不需要做 null 檢查。 每個網路在這裡都可以使用,包括那些在框架自己面板內完成的網路:Facebook 會在彈出視窗中顯示它的 轉交說明畫面,Bluesky 與 X 會顯示它們的憑證表單,而 LinkedIn、Pinterest、YouTube 與 Google Business 會前往該網路再返回。 對三種屬於程式錯誤的情況,它會同步拋出例外——沒有 network、已銷毀的實例,或尚未解析完成的 工作階段。被封鎖的彈出視窗在其中:那會發出帶 reason: "popupBlocked"error, 因為你的使用者並沒有做錯任何事。 同一時間最多只有一個彈出視窗開啟。第二次呼叫會關閉第一個,並在其上回報帶 reason: "superseded"cancelled。由我們的框架開啟的彈出視窗則是另一回事,永遠不會被 碰觸,因此你的按鈕不可能取消正在已掛載插槽內執行的流程。
工作階段是否可以連結某個網路,由伺服器決定,而不是指令碼。一個範圍限定在 Bluesky 的 工作階段被要求連結 LinkedIn 時,會在彈出視窗中看到拒絕畫面,並以 error 回報。指令碼只檢查 是否有指定網路。

React

這個指令碼不依賴任何框架,因此 React 不需要我們提供任何特別支援——但關於它的生命週期, 有四件事值得第一次就做對。 指令碼只載入一次,且在你的元件樹之外。在 Next.js 中是根 layout 裡的 next/script;在 Vite 或 Create React App 中則是 index.html 裡的標籤。若在每個元件中載入,它會在每次掛載時重新執行。
ConnectAccounts.jsx
**切勿在 destroy() 之後重複使用實例。**已銷毀的實例會一直保持銷毀狀態——在其上呼叫 popup() 會拋出例外,mount() 也無法讓它復活。請在下一次 effect 執行時建立新的實例,上面的程式碼正是 這樣做的。
這個模式有兩個後果,兩者都不是 bug:
  • **在開發環境中,你會看到 session 回呼觸發兩次。**React 的 Strict Mode 會以「掛載 → 卸載 → 掛載」 的方式執行 effect,因此實例會被建立、銷毀、再建立一次。上面的清理程式讓這件事是安全的; 它在開發環境多花一次對你後端的呼叫,在正式環境則一次也不多。
  • **保持 effect 的相依項穩定。**從父層渲染直接傳進 mount 的陣列字面值每次都是新值,因此依賴它的 effect 會在每次渲染時拆掉小工具再重建。請將它 memoize,或像上面那樣保持常數。

事件

on 訂閱,它會回傳一個取消訂閱的函式。處理常式會收到事件的酬載與事件來自的掛載; off(name, handler) 在你想用具名處理常式時做同樣的事。
十個事件。除了 ready,以及那種與網路完全無關的 error(見下方 error 有兩種來源),每個事件都帶有 network 其中四個是結局——successunlinkederrorcancelled——每次嘗試恰好送達一個。 closed 是跟在結局之後的生命週期通知,本身不是結局。 click 在任何連結工作開始之前就會觸發,因此它也會回報之後被封鎖的彈出視窗或失效的工作階段 所拒絕的點擊。它是你自己的分析所該使用的事件;started 才代表一次嘗試真正在執行。

Reasons

error 有兩種來源

其中只有一種是連結失敗,且兩者帶有不同的欄位。
  • 連結錯誤帶有 networkcode 以及它來自的掛載。
  • 工作階段錯誤——我們無法建立或更新你的工作階段——只帶有 message,因為當時沒有任何東西 正在被連結。
請防禦性地解構:在第二種情況下,codenetwork 都是 undefined

state 讓你不必輪詢

state 是資料通道,而不是對某次嘗試的回報。每個框架在掛載時會對每個網路各發出一次,帶有該網路 目前的狀態以及它持有該狀態起始的 since 時間戳記;狀態一有變化就再發出一次——包括源自我們 這一側的變化,例如 token 失效變成需要重新連結。因此你可以完全由小工具驅動你的 UI, 不需要輪詢任何東西。 其值與 GET /profilesinclude=state 回傳的是同一組列舉值: linkedunlinkedidentityVerificationRequiredrestrictedrateLimitedsuspended

取消連結

我們的方塊既能連結也能取消連結。你的使用者點擊已連結的網路、確認後,帳號即被移除:
  1. click 觸發,帶 action: "unlink"
  2. 移除儲存完成後,unlinked 觸發。
失敗的取消連結會回報 error;使用者在確認步驟退出的則回報 cancelled。沒有獨立的 「取消連結失敗」事件。

外觀

客戶的樣式表無法觸及跨來源框架的內部,因此樣式是以資料的形式傳遞,由我們在框架內套用。將 appearance 以 CSS 自訂屬性的形式傳給 init;我們沒有收到的每一項都保持我們的預設值。
**顏色要成對設定。**只設定背景 token 而不設定旁邊的前景 token,是唯一會讓結果變得難以閱讀的 方式:單獨把 --ayr-connect-surface-bg 設成深色,而我們預設的 --ayr-connect-surface-fg 仍是深海軍藍。沒有任何機制能替你推斷另一半。
完全不帶 appearance 時,每個 token 都保持預設值,框架看起來像這樣:
Three Ayrshare Connect tiles with the default appearance

預設 token:白色表面、深海軍藍文字、靛藍強調色、8px 圓角。

傳入幾個 token,同一個框架就會換上你的色盤。這個範例把表面改為淡藍色、將文字與強調色加深以搭配, 並把圓角再修得圓一點:
Three Ayrshare Connect tiles restyled with pale blue surfaces and a deeper blue accent

套用上述 token 之後的同樣三個方塊。

**只有一個色盤,沒有亮/暗預設組。**沒有任何東西依 prefers-color-scheme 切換,這是刻意的—— 你頁面的主題未必與使用者的作業系統一致,而 media query 會悄悄推翻你選擇的顏色。深色儀表板 要透過提供深色的值來設定主題。 這份 token 清單是我們跨版本維持的受支援契約。

Token 清單

對其 token 而言不是有效 CSS 的值會被忽略,並在你的主控台留下警告,而不會被套用。這比聽起來 更重要:--ayr-connect-spacing 的無單位 8 是一個看似無害的字串,卻會讓所有讀取它的計算失效 並使版面崩壞,而且任何地方都不會出現錯誤。請為長度加上單位。

在轉交畫面放上你自己的名稱

在把你的使用者交給社群網路之前,我們會顯示一個短暫的畫面,說明他們是透過誰連結的。有兩個掛勾 可以讓你把它變成自己的,且兩者都跨版本穩定。 --ayr-connect-partner-name 設定標籤。它是唯一以文字為值的 token,因此必須以 CSS 字串的 形式加上引號——未加引號的值是無效的,什麼都不會渲染:
Logo 不是 token。我們把該標誌以定位好、設好尺寸的元素出貨,你透過 cssbackground-image 填入內容,如上所示——一個能從我們文件內部抓取圖片的 token 不是我們會接受的東西,所以這個請求 來自你撰寫的規則,而不是你傳給我們的值。
[data-ayr-connect-partner-mark][data-ayr-connect-partner-name] 是下方自訂 CSS 注意事項的例外:這兩個選擇器屬於契約的一部分,我們會跨版本維持它們。

自訂 CSS

css 接受一個套用在每個框架內的字串,用於 token 無法涵蓋的情況。
**自訂 CSS 不跨版本受支援。**它的選擇器指向我們的內部標記,而內部標記會在版本之間改變——今天 有效的規則可能在任何更新之後悄悄不再匹配。上方的 token 契約才是我們維持的部分。如果你依賴 自訂 CSS,請釘選一個版本。
彈出視窗會與框架完全一樣地繼承實例的 appearancecss,因此你的使用者不會在流程中途 突然看到我們中性的預設樣式。

上線前值得知道的事

你以 popup() 開啟的彈出視窗無法被告知 token 為何被拒絕——要說明原因,它必須信任一個尚未 驗證的來源,而這是我們的安全模型所不允許的。因此帶著失效 token 的彈出視窗會關閉,並以帶 reason: "popupClosed"cancelled 呈現,而不是 error實務上這很少見:在靜默更新之前開啟的彈出視窗會繼續運作,因為它在開啟時就已驗證了自己的 token。如果你看到無法解釋的 popupClosed 結果,請檢查你的 session 端點是否回傳了 新鮮的工作階段。
十四個掛載共用一個 token,只花費你後端一次呼叫,而不是十四次。如果你想要不同範圍的插槽—— 其中一些帶不同的 allowedSocial——請以自己的工作階段執行第二個 init,而不要期待某次掛載 能縮小它的範圍。
每個工作階段都帶有你頁面執行所在的 origin,框架在渲染任何內容之前會將嵌入它的頁面與該值 比對。被嵌在其他地方的框架會保持空白,且不發送任何事件。沒有需要註冊的允許清單,也沒有 任何要設定的東西——建立工作階段時送出正確的 origin 即可。
框架向指令碼回報自己的高度,指令碼再調整框架的大小。你的版面只是自然重排。沒有可訂閱的 resize 事件,你這一側也沒有任何需要量測的東西。

需求

  • Max Pack。小工具的工作階段是 connect 模式的工作階段,在沒有 Max Pack 的情況下建立會回傳 code: 504。如果你需要在沒有 Max Pack 的帳戶上啟用 connect 模式,請聯絡支援團隊。
  • 每個工作階段都要有 origin——你頁面執行所在的確切來源。省略它會回傳 code: 505; 不是 https 來源、自訂 scheme 或 http://localhost 的值會回傳 code: 506
  • 工作階段上不要有 network。那個參數會讓工作階段變成 直接模式,而直接模式工作階段的 URL 不是指令碼 所預期的。
上面提到的每個錯誤碼都收錄在 Link Session 錯誤參考中,包含 API 回傳的確切訊息 以及處理方式。