@@ -353,28 +353,98 @@ def exchange_device_code_with_merge(device_code):
353353
354354## Unmerging Provisional Accounts
355355
356- When a player wants to unlink their Discord account from their provisional account, there are two options.
356+ When a player wants to unlink their Discord account from their provisional account, there are three options:
357357
358- 1 . The user can unmerge their account from the Discord client.
359- 2 . A developer can unmerge the account using the unmerge endpoint on the Discord API.
358+ 1 . The user can unmerge their account from the Discord client
359+ 2 . A developer can use the SDK helper method for public clients
360+ 3 . A developer can unmerge the account using the unmerge endpoint on the Discord API
361+
362+ :::warn
363+ Unmerging invalidates all access/refresh tokens for the user. They cannot be used again after the unmerge operation completes.
364+ :::
360365
361366### Discord Users
362367
363368Users can unmerge their account by removing access to your application on their Discord ` User Settings -> Authorized Apps ` page.
364369
370+ This method doesn't require any code changes from developers, but we recommend providing unmerging functionality through
371+ one of the options below for a better user experience.
372+
373+ ### Using the SDK Helper Method
374+
375+ <PublicClient />
376+
377+ The quickest way to unmerge accounts is to leverage the [ ` Client::UnmergeIntoProvisionalAccount ` ] method,
378+ which will handle the entire process for you. This method is designed for public clients that don't have a backend server.
379+
380+ ** Important Notes:**
381+ - This function only works for ** public clients** (applications without backend servers)
382+ - You'll need to enable "Public Client" on your Discord application's OAuth2 tab in the Discord developer portal
383+ - After unmerging, you should use [ ` Client::GetProvisionalToken ` ] to get a new provisional token for the newly created provisional account
384+
385+ ``` cpp
386+ // unmerge a user account
387+ void UnmergeUserAccount (const std::shared_ptr<discordpp::Client>& client) {
388+ // Get your external auth token (Steam, OIDC, etc.)
389+ std ::string externalToken = GetExternalAuthToken ();
390+
391+ // Unmerge the Discord account from the external identity
392+ client - > UnmergeIntoProvisionalAccount (
393+ YOUR_DISCORD_APPLICATION_ID ,
394+ discordpp ::AuthenticationExternalAuthType ::OIDC , // or STEAM, EOS, etc.
395+ externalToken ,
396+ [client , externalToken ](const discordpp ::ClientResult & result ) {
397+ if (result.Successful()) {
398+ std ::cout << " ✅ Account unmerged successfully! Creating new provisional account...\n " ;
399+
400+ // Now get a new provisional token for the unlinked identity
401+ client - > GetProvisionalToken (
402+ YOUR_DISCORD_APPLICATION_ID ,
403+ discordpp ::AuthenticationExternalAuthType ::OIDC ,
404+ externalToken ,
405+ [client ](const discordpp ::ClientResult & result ,
406+ const std ::string & accessToken ,
407+ const std ::string & refreshToken ,
408+ discordpp ::AuthorizationTokenType tokenType ,
409+ int32_t expiresIn ,
410+ const std ::string & scopes ) {
411+ if (result.Successful()) {
412+ std ::cout << " 🔓 New provisional account created! Establishing connection...\n " ;
413+ client - > UpdateToken (discordpp ::AuthorizationTokenType ::Bearer , accessToken ,
414+ [client ](const discordpp ::ClientResult & updateResult ) {
415+ if (updateResult.Successful()) {
416+ client - > Connect ();
417+ } else {
418+ std ::cerr << " ❌ Failed to update token: " << updateResult .Error () << std ::endl ;
419+ }
420+ }
421+ );
422+ } else {
423+ std ::cerr << " ❌ Failed to create new provisional account: " << result .Error () << std ::endl ;
424+ }
425+ }
426+ );
427+ } else {
428+ std ::cerr << " ❌ Unmerge failed: " << result .Error () << std ::endl ;
429+ }
430+ }
431+ );
432+ }
433+ ```
434+
365435### Unmerging using the unmerge endpoint
366436
367437A developer can unmerge a user's account by sending a request to the unmerge endpoint on the Discord API.
368438
369439
370440```python
371441import requests
372-
442+
373443API_ENDPOINT = ' https://discord.com/api/v10'
374444CLIENT_ID = ' 332269999912132097'
375445CLIENT_SECRET = ' 937it3ow87i4ery69876wqire'
376446EXTERNAL_AUTH_TYPE = ' OIDC'
377-
447+
378448def unmerge_provisional_account(external_auth_token):
379449 data = {
380450 ' client_id' : CLIENT_ID ,
@@ -386,6 +456,10 @@ def unmerge_provisional_account(external_auth_token):
386456 r.raise_for_status()
387457```
388458
459+ :::info
460+ If you have a server backend, you'll want to use the server-to-server unmerge endpoint rather than the SDK helper method to maintain better security and control over the unmerge process.
461+ :::
462+
389463---
390464
391465## Next Steps
@@ -421,4 +495,5 @@ Now that you've set up provisional accounts for your game, you can explore more
421495[ `Client::GetTokenFromDeviceProvisionalMerge` ] : https://discord.com/developers/docs/social-sdk/classdiscordpp_1_1Client.html#afd2207590ae7d6f60ee7bbb4fc7c21c8
422496[ `Client::GetTokenFromProvisionalMerge` ] : https://discord.com/developers/docs/social-sdk/classdiscordpp_1_1Client.html#a41062b7dafa331ddd2320daf1b4b273b
423497[ `Client::SetTokenExpirationCallback` ] : https://discord.com/developers/docs/social-sdk/classdiscordpp_1_1Client.html#aab5bfc76809ea22e79f2f7a067ac4519
498+ [ `Client::UnmergeIntoProvisionalAccount` ] : https://discord.com/developers/docs/social-sdk/classdiscordpp_1_1Client.html#a2da21ae8a3015e0e5e42c1a7226b256f
424499[ `Client::UpdateProvisionalAccountDisplayName` ] : https://discord.com/developers/docs/social-sdk/classdiscordpp_1_1Client.html#a7485979ab2d4c533b75f8efd5e50bc60
0 commit comments