> ## Documentation Index
> Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# अपना ख़ुद का लिंकिंग पॉपअप बनाएँ

> डायरेक्ट मोड — आपके अपने डैशबोर्ड के बटन से एक समय में एक नेटवर्क कनेक्ट करें, ऐसे पॉपअप के साथ जिसे आप स्वयं खोलते और देखते हैं।

export const PlansAvailable = ({plans = [], maxPackRequired}) => {
  let displayPlans = plans;
  if (plans && plans.length === 1) {
    const lowerCasePlan = plans[0].toLowerCase();
    if (lowerCasePlan === "business") {
      displayPlans = ["Launch", "Business", "Enterprise"];
    } else if (lowerCasePlan === "premium") {
      displayPlans = ["Premium", "Launch", "Business", "Enterprise"];
    }
  }
  return <Note>
Available on {displayPlans.length === 1 ? "the " : ""}
{displayPlans.join(", ").replace(/\b\w/g, l => l.toUpperCase())}{" "}
{displayPlans.length > 1 ? "plans" : "plan"}.

{maxPackRequired && <span onClick={() => window.open('https://www.ayrshare.com/docs/additional/maxpack', '_self')} className="flex items-center mt-2 cursor-pointer">
 <span className="px-1.5 py-0.5 rounded text-sm" style={{
    backgroundColor: '#C264B6',
    color: 'white',
    fontSize: '12px'
  }}>
   Max Pack required
 </span>
</span>}
</Note>;
};

<PlansAvailable plans={["business"]} maxPackRequired={true} />

डायरेक्ट मोड (Direct Mode) आपके अपने डैशबोर्ड के किसी बटन से **एक समय में एक सोशल नेटवर्क**
कनेक्ट करता है। आप उस नेटवर्क के लिए एक लिंक सेशन बनाते हैं, उसका लौटाया `url` एक पॉपअप में खोलते
हैं, और आपका पेज सुनता है कि क्या हुआ। आपका उपयोगकर्ता कभी हर नेटवर्क की सूची वाला पेज नहीं
देखता, और नेटवर्क के अपने लॉगिन से अधिक देर के लिए कभी आपका ऐप नहीं छोड़ता।

## आपको कौन सा सरफ़ेस चाहिए

तीन रूप, और पहले दो एक ही इंटीग्रेशन हैं। यह पेज वह है जो आप स्वयं बनाते हैं।

| सरफ़ेस | आपका उपयोगकर्ता देखता है | व्हाइट-लेबलिंग | इसे कब चुनें |
| - | - | - | - |
| **विजेट — एम्बेडेड फ़्रेम** ([mount](/docs/multiple-users/connect-widget#mount-a-slot)) | हमारे बटन आपके अपने लेआउट में inline; नेटवर्क के अपने पॉपअप तक कोई पॉपअप नहीं | **सबसे मज़बूत।** आपका पेज, आपके फ़ॉन्ट और रंग, और आपका उपयोगकर्ता उसे कभी नहीं छोड़ता | आपके पास प्रति नेटवर्क एक row वाला डैशबोर्ड है और आप चाहते हैं कि लिंकिंग वहीं हो। Max Pack। |
| **विजेट — आपका अपना बटन** ([popup](/docs/multiple-users/connect-widget#your-own-button)) | आपका बटन, फिर नेटवर्क के लिए एक पॉपअप | **मज़बूत।** पॉपअप हमारा है, लेकिन वह संक्षिप्त है और आपका appearance अपनाता है | आप अपना बटन और styling चाहते हैं, और अपने लेआउट में कोई फ़्रेम नहीं। Max Pack। |
| **होस्टेड लिंकिंग पेज** ([कैसे करें](/docs/multiple-users/api-integration-business#single-sign-on-with-jwt-authentication)) | हमारे द्वारा होस्ट किया गया पेज, जिस पर आपका लोगो, रंग और कस्टम CSS होते हैं | **सबसे कमज़ोर।** यह हमारा पेज है, और आपका उपयोगकर्ता इसका उपयोग करने के लिए आपका पेज छोड़ता है | आप बाँटने के लिए एक ही लिंक चाहते हैं, या ईमेल से ऑनबोर्ड कर रहे हैं। कुछ भी बनाने की ज़रूरत नहीं, कोई Max Pack नहीं। |

<Note>
  **डायरेक्ट मोड तीसरी row का पॉपअप है, हमारी स्क्रिप्ट के बिना।** यदि आपका पेज स्क्रिप्ट लोड कर
  सकता है, तो [विजेट](/docs/multiple-users/connect-widget) इस पेज का सब कुछ आपके लिए करता है — वह
  पॉपअप स्वयं खोलता और देखता है, और फ़्रेम भी embed कर सकता है। डायरेक्ट मोड तब चाहिए जब आपका
  पेज कोई third-party स्क्रिप्ट लोड नहीं कर सकता, या सरफ़ेस ब्राउज़र के बजाय native ऐप है।
</Note>

<Frame caption="आपका बटन, आपका पेज। पॉपअप ही हमारी एकमात्र चीज़ है जो आपका उपयोगकर्ता देखता है, और केवल उतनी देर के लिए जितनी नेटवर्क को चाहिए।">
  <img src="https://mintcdn.com/ayrshare-docs/-2tpx3mFy9vWIObd/images/multiple-users/connect-widget-popup.webp?fit=max&auto=format&n=-2tpx3mFy9vWIObd&q=85&s=b68021d477703d97a5994ee85d299be6" alt="A customer dashboard with its own Connect buttons and an Ayrshare popup showing the Facebook hand-off screen" width="2880" height="1317" data-path="images/multiple-users/connect-widget-popup.webp" />
</Frame>

## आप क्या बनाते हैं

चार चरण। पहला आपके server पर है, बाक़ी आपके पेज में।

<Steps>
  <Step title="एक नेटवर्क के लिए सेशन बनाएँ">
    अपने backend से, `mode: "connect"`, `network`, और उस `origin` के साथ जिस पर आपका पेज चलता
    है, [Link Session बनाएँ](/docs/apis/profiles/create-link-session) को कॉल करें।

    ```javascript Your backend theme={"system"}
    const response = await fetch("https://api.ayrshare.com/api/profiles/link-sessions", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${process.env.AYRSHARE_API_KEY}`,
        "Profile-Key": profileKey,
      },
      body: JSON.stringify({
        mode: "connect",
        network: "reddit",
        origin: "https://app.example.com",
      }),
    });

    const { url } = await response.json();
    ```

    आपको वापस एक `url` मिलता है जो single-network connect पेज की ओर इशारा करता है, और कोई
    `token` नहीं — token URL के अंदर है। पूरे URL को पासवर्ड की तरह मानें: यह आपके उपयोगकर्ता को
    उनके User Profile में साइन इन कर देता है।

    <Warning>
      सेशन अपने server पर बनाएँ, कभी ब्राउज़र में नहीं। कॉल को आपकी API Key चाहिए।
    </Warning>
  </Step>

  <Step title="इसे click handler में, synchronously खोलें">
    पॉपअप को `window.open` से **click handler के अंदर ही** खोलना होगा। ब्राउज़र पॉपअप की अनुमति
    केवल तब तक देता है जब तक वह आपके उपयोगकर्ता के क्लिक को process कर रहा होता है, और वह
    अनुमति किसी `await` के बाद नहीं बचती — इसलिए पहले URL fetch करके उसे callback में खोलना
    निश्चित रूप से popup-blocked होता है।

    URL तब fetch करें जब आप बटन render करते हैं, या जब आपका उपयोगकर्ता उस पर hover करता है।
    क्लिक के समय तक वह आपके पास पहले से होना चाहिए।

    ```javascript Your page theme={"system"}
    // `url` was fetched earlier. Nothing async between the click and window.open.
    button.addEventListener("click", () => {
      const popup = window.open(url, "ayrshare-connect", "width=600,height=800");
      if (!popup) {
        showError("Allow popups for this site to connect an account.");
        return;
      }
      listenForOutcome(popup, url);
    });
    ```
  </Step>

  <Step title="परिणाम के लिए सुनें">
    चूँकि आपने `origin` पास किया, पॉपअप उसमें घटित होने वाली हर चीज़ के लिए आपके पेज पर एक event
    पोस्ट करता है: `connect:success`, `connect:error`, `connect:cancelled`, और बीच में progress
    events। प्रति कनेक्शन उन तीनों में से ठीक एक आता है।

    [Link Completion Events](/docs/multiple-users/link-completion-events) पर पूरी event टेबल और
    copy-paste listener है — ऊपर का `listenForOutcome` वही snippet है। उसके दो हिस्से छूट जाना
    आसान है और दोनों वास्तविक bugs पैदा करते हैं:

    * **`event.origin` जाँचें**, उस URL के origin के विरुद्ध जो आपने खोला। कोई भी पेज आपकी विंडो
      को message पोस्ट कर सकता है, और origin ही message का एकमात्र हिस्सा है जिसे जाली नहीं
      बनाया जा सकता।
    * **`popup.closed` poll करें**, कोई निष्कर्ष निकालने से पहले एक छोटी grace window के साथ। जो
      पॉपअप आपके उपयोगकर्ता ने हाथ से बंद किया वह कुछ भी नहीं भेजता, और grace window के बिना
      एक सफल कनेक्शन cancelled के रूप में रिपोर्ट हो सकता है।
  </Step>

  <Step title="हर अंत को संभालें">
    | अंत | इसका अर्थ | क्या करें |
    | - | - | - |
    | `connect:success` | अकाउंट कनेक्टेड **और सेव** है | उस row को refresh करें। इसके तुरंत बाद [`GET /user`](/docs/apis/user/profile-details) उसे पहले से दिखाता है। |
    | `connect:error` | कनेक्शन विफल हुआ | `message` दिखाएँ। विफलता का कोई catalogued code होने पर `code` मौजूद होता है, न होने पर अनुपस्थित। |
    | `connect:cancelled` | आपका उपयोगकर्ता पीछे हट गया, या विंडो बंद कर दी | row को जैसी थी वैसी रहने दें। `reason` `popupClosed`, `scopesDenied` या `userCancelled` है। |
    | कुछ नहीं आता | लिंक expired, revoked या unknown था, इसलिए पेज को पता ही नहीं चला कि events कहाँ भेजने हैं | [Link Session प्राप्त करें](/docs/apis/profiles/get-link-session) को poll करें, जो उन states को प्रामाणिक रूप से रिपोर्ट करता है। |
  </Step>
</Steps>

<Tip>
  विकास के दौरान URL में `&autoClose=false` जोड़ें। तब पॉपअप हर परिणाम के बाद स्वयं बंद होने के
  बजाय खुला रहता है, ताकि आप पढ़ सकें कि वह क्या कहता है।
</Tip>

## प्रति-नेटवर्क नोट्स

अधिकांश नेटवर्क एक पॉपअप और बस इतना ही हैं: आपका उपयोगकर्ता क्लिक करता है, नेटवर्क पर authorize
करता है, और पॉपअप बंद हो जाता है। ये वे अपवाद हैं जो बनाने से पहले जानने योग्य हैं।

<AccordionGroup>
  <Accordion title="X के लिए आपकी अपनी API keys आवश्यक हैं">
    डायरेक्ट मोड में X **आपकी** X Developer App क्रेडेंशियल्स का उपयोग करता है, जो सेशन बनाते समय
    [Link Session बनाएँ](/docs/apis/profiles/create-link-session) पर `X-Twitter-OAuth1-Api-Key` और
    `X-Twitter-OAuth1-Api-Secret` हेडरों के रूप में दी जाती हैं।

    उन हेडरों के **बिना** `twitter` या `x` के लिए बनाया गया सेशन पॉपअप खुलते ही ठुकरा दिया जाता
    है: आपके उपयोगकर्ता को बताया जाता है कि कनेक्शन उपलब्ध नहीं है और कोई फ़ॉर्म नहीं दिखाया
    जाता, और आपके पेज को `message` और **बिना `code`** के `connect:error` मिलता है। यह जानबूझकर
    है। गुम क्रेडेंशियल आपकी है, आपके उपयोगकर्ता की नहीं, और end users से कभी आपकी API keys टाइप
    करने को नहीं कहा जाना चाहिए।

    इसकी तुलना Bluesky से करें, जहाँ app password end user की अपनी क्रेडेंशियल है — उसे connect
    पेज पॉपअप के अंदर एक फ़ॉर्म में एकत्र ज़रूर करता है।
  </Accordion>

  <Accordion title="Facebook, Meta के लॉगिन से पहले एक बटन दिखाता है">
    `network: "facebook"` पॉपअप में एक अकेला बटन दिखाता है, और Meta का अपना लॉगिन उस क्लिक से
    खुलता है — Meta को अपना लॉगिन उस पेज के अंदर के क्लिक से शुरू होना चाहिए जो उसका SDK होस्ट
    करता है। आपका उपयोगकर्ता एक के बजाय दो बार क्लिक करता है; और कुछ भी अलग नहीं है।

    Instagram भी वैसा ही व्यवहार करता है जब वह **Facebook Page के माध्यम से** लिंक होता है —
    यानी जब सेशन `instagramLinkMethod: "facebook"` ले जाता है, या जब आपके अकाउंट की
    [Instagram Login](/docs/multiple-users/manage-user-profiles#instagram-login) सेटिंग वह फ़्लो
    चुनती है। सीधे Instagram Login के साथ कोई अतिरिक्त बटन नहीं है।
  </Accordion>

  <Accordion title="Bluesky और Telegram redirect नहीं, पेज content दिखाते हैं">
    दोनों में से कोई भी आपके उपयोगकर्ता को नेटवर्क लॉगिन पर नहीं भेजता। पॉपअप इसके बजाय content
    render करता है: Bluesky के लिए handle और app-password फ़ॉर्म, और Telegram के लिए इस्तेमाल
    करने का एक code। परिणाम events दोनों तरह से एक जैसे हैं।

    X इस समूह में नहीं आता। सेशन पर आपकी keys होने पर वह आपके उपयोगकर्ता से कुछ भी पूछे बिना पूरा
    हो जाता है, और उनके बिना ठुकरा दिया जाता है — ऊपर देखें।
  </Accordion>

  <Accordion title="Telegram out of band पूरा होता है">
    Telegram कहीं redirect करने के बजाय एक code दिखाता है, और कनेक्शन तब पूरा होता है जब आपका
    उपयोगकर्ता उस code का उपयोग करता है — पॉपअप के जा चुकने के बाद। इंतज़ार करने के लिए कोई
    ब्राउज़र event नहीं है, इसलिए [Link Session प्राप्त करें](/docs/apis/profiles/get-link-session) को
    poll करें और `completedNetworks` पर नज़र रखें।
  </Accordion>

  <Accordion title="Facebook Groups इस तरह कनेक्ट नहीं किए जा सकते">
    Facebook Groups कोई link target नहीं है, इसलिए `network: "fbg"` सेशन बनाते समय `code: 508`
    लौटाता है।

    WhatsApp डायरेक्ट मोड में उपलब्ध **है**। वह पॉपअप में Meta का Embedded Signup खोलता है, और
    परिणाम events किसी भी अन्य नेटवर्क जैसे ही हैं।
  </Accordion>
</AccordionGroup>

<h2 id="native-apps">
  Native ऐप्स
</h2>

Native ऐप वही `url` खोलता है, **सिस्टम ब्राउज़र** में, और परिणाम
[Link Session प्राप्त करें](/docs/apis/profiles/get-link-session) को poll करके पता करता है। `origin`
को अपनी custom scheme (`myapp://connected`) पर सेट करें ताकि पेज के पास आपके ऐप में लौटने का
रास्ता हो; custom scheme events प्राप्त नहीं कर सकती, क्योंकि उन्हें पोस्ट करने के लिए कोई ब्राउज़र
विंडो नहीं है।

* **iOS** — `ASWebAuthenticationSession`, या `SFSafariViewController`।
* **Android** — Chrome Custom Tabs।

<Warning>
  **लिंकिंग URL को कभी embedded webview में न खोलें** (`WKWebView`, `UIWebView`, Android
  `WebView`)। सोशल नेटवर्क उसमें प्रमाणित करने से इनकार करते हैं: Google साइन-इन को
  `disallowed_useragent` के साथ अस्वीकार करता है, और Meta उसे सिरे से ब्लॉक कर देता है। आपका
  उपयोगकर्ता नेटवर्क का अपना error पेज देखता है, हमारा नहीं, और आपकी तरफ़ का कोई भी बदलाव इसे
  ठीक नहीं करता। ऊपर दिए सिस्टम ब्राउज़र components ठीक इसी कारण से हैं और उपयोगकर्ता को आपके
  ऐप के अंदर रखते हैं।
</Warning>

## डायरेक्ट मोड को क्या चाहिए

<ul className="custom-bullets">
  <li>
    **[Max Pack](/docs/additional/maxpack)।** इसके बिना connect-mode सेशन बनाने पर `code: 504` लौटता
    है, बाक़ी अनुरोध चाहे जो कहे।
  </li>

  <li>
    हर सेशन पर एक **`origin`**। कोई allowlist नहीं है और कोई registration चरण नहीं — आप इसे प्रति
    कॉल भेजते हैं। इसे छोड़ने पर `code: 505` लौटता है; ऐसा मान जो `https` origin, custom scheme,
    या `http://localhost` नहीं है, `code: 506` लौटाता है।
  </li>

  <li>
    ऐसा **`network`** जिसे आपके अकाउंट ने सक्षम किया है। अपरिचित नाम `code: 508` लौटाता है;
    पहचाना हुआ लेकिन आपके अकाउंट पर सक्षम न किया गया नाम `code: 509` लौटाता है, जिसे आप अपने
    [Social Networks](/docs/multiple-users/manage-user-profiles#set-social-networks-access) पेज पर ठीक
    कर सकते हैं।
  </li>

  <li>
    **`allowedSocial` नहीं।** इसे `network` के साथ जोड़ा नहीं जा सकता (`code: 507`) —
    single-network सेशन पहले से अपनी ख़ुद की allowlist है।
  </li>
</ul>

इनमें से हर एक
[Link Session त्रुटियाँ](/docs/errors/errors-ayrshare#link-session-errors) संदर्भ में है, API द्वारा
लौटाए जाने वाले message के साथ।

## अगले चरण

<Card title="Link Completion Events" icon="tower-broadcast" href="/docs/multiple-users/link-completion-events" horizontal>
  पॉपअप द्वारा भेजा जाने वाला हर event, और उन्हें प्राप्त करने वाला listener।
</Card>

## संबंधित

<Card title="Create a Link Session" icon="link" href="/docs/apis/profiles/create-link-session#connect-mode" horizontal>
  `mode`, `origin` और `network` पैरामीटर, और प्रतिक्रिया के आकार।
</Card>

<Card title="Get a Link Session" icon="magnifying-glass" href="/docs/apis/profiles/get-link-session" horizontal>
  जब आप पॉपअप का उपयोग नहीं कर सकते, तो पूर्णता के लिए poll करें।
</Card>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.