23 | );
24 | }
25 |
26 | // TODO: Add analytics about where users go from here, and how they got here in order to improve the docs
27 | export default function NotFound() {
28 | return (
29 |
30 |
31 |
32 |
33 |
34 |
35 | 404: Page not found
36 |
37 |
38 | This Bot Doesn't have that Intent!
39 |
40 |
41 |
42 |
43 | Learn more about how to write bots using Application Commands!
44 |
45 |
46 | Learn more about how to add Message Components like Buttons to your bot messages!
47 |
48 |
49 | Learn more about the Discord API and philosophy, and how to write your own bot!
50 |
51 |
52 | Join us in our official Discord Developer community server!
53 |
54 |
55 |
56 |
57 |
58 |
59 | Learn about Slash Commands while you're here!
60 |
61 |
62 |
63 |
64 |
65 | We stan Muffins for making this amazing video
66 |
67 |
68 |
69 |
70 | );
71 | }
72 |
--------------------------------------------------------------------------------
/pages/intro.mdx:
--------------------------------------------------------------------------------
1 | # Introduction
2 |
3 | You’ve found the Discord Developer Documentation! These pages are dedicated to showing you all the ways that you can use Discord to make cool stuff. Whether you’re looking to create awesome bots for your community, empower your applications with our API, or hook us right into your game with Rich Presence or the GameSDK, Discord has something for you.
4 |
5 | All of our [documentation is on GitHub](https://github.com/discord/discord-api-docs) and we <3 corrections and improvements!
6 |
7 | ## Bugs
8 |
9 | If you believe you're experiencing a bug with our API or want to report incorrect documentation, open an issue on our [issue tracker](https://github.com/discord/discord-api-docs/issues).
10 |
11 | ## Bots and Apps
12 |
13 | Bots and apps are the lifeblood of the Discord development community. They come in all shapes and sizes, from small hobby projects for your server with friends, to huge projects that live in hundreds of thousands of servers. We love seeing the unique, fun, and sometimes downright strange (in a good way) creations that come from our community.
14 |
15 | Discord offers an open API to serve requests for both bots and OAuth2 integrations. So whether you’re making your own [`/wumpus` commands](/interactions/application-commands/) or looking to [`Log In With Discord`](/topics/oauth2/), we’ve got you covered.
16 |
17 | So go do it! Go! Go [make an app](https://discord.com/developers/applications) and create something awesome.
18 |
19 | ## Games
20 |
21 | We love games, and we love helping game developers. If YOU have a game that you want to supercharge with Discord, then we have just the thing for you.
22 |
23 | #### Your Game On Discord
24 |
25 | If you haven’t yet noticed, Discord allows you to [sell your game](https://discord.com/sell-your-game) right from Discord servers! We’ve got a whole suite of tools to help bring your game to life on Discord. Need networking? Have [networking](/game-sdk/networking/)! Want a friends list? Take [relationships](/game-sdk/relationships/) too!
26 |
27 | #### Rich Presence
28 |
29 | No matter where your game lives, it should have a first-class experience in Discord. [Rich Presence](https://discord.com/rich-presence) is the way to make that a reality! We got tired of exchanging usernames, friend codes, and lobby passwords, so we created Rich Presence, an easy-to-use, easy-to-integrate way to get people playing games together that lets you:
30 |
31 | - Display rich game data on your players’ profiles
32 | - Empower them to send game invites to each other
33 | - Ask to Join and Spectate their friends' games
34 | - Spend more time playing together and less time setting up
35 |
36 | It’s free, easy, and self-serve, so check out [the GameSDK Activity Manager](/game-sdk/activities/) and get started!
37 |
38 | ## Still need some help?
39 |
40 | Join the [Official Discord Developers server](https://discord.gg/discord-developers) for support and discussion regarding Discord's APIs.
41 |
42 | ## Go Make Cool Stuff!
43 |
44 | We love our developers, and we plan to keep making practical tools so that YOU can keep making cool stuff. Build a bot, integrate our account system, or put us right in your game; whatever you do, do it with Discord.
45 |
46 | We can’t wait to see what you make.
47 |
48 | -- Discord
49 |
--------------------------------------------------------------------------------
/components/ThemeSwitcher.tsx:
--------------------------------------------------------------------------------
1 | import { Fragment, useCallback } from "react";
2 | import { Transition, Menu } from "@headlessui/react";
3 | import classNames from "classnames";
4 | import { useTheme } from "next-themes";
5 | import Moon from "./icons/Moon";
6 | import Sun from "./icons/Sun";
7 | import Gear from "./icons/Gear";
8 | import Lightbulb from "./icons/Lightbulb";
9 | import Check from "./icons/Check";
10 |
11 | export default function ThemeSwitcher() {
12 | const { theme, setTheme } = useTheme();
13 |
14 | const getMenuItemClasses = useCallback(
15 | (active: boolean) =>
16 | classNames("group flex items-center px-2 py-2 w-full text-sm rounded-md", {
17 | "bg-brand-blurple text-white": active,
18 | "text-gray-900 dark:text-theme-dark-sidebar-text": !active,
19 | }),
20 | []
21 | );
22 |
23 | return (
24 |
82 | );
83 | }
84 |
--------------------------------------------------------------------------------
/pages/dispatch/error-codes.mdx:
--------------------------------------------------------------------------------
1 | # Error Codes
2 |
3 |
4 |
5 | Need help with Dispatch? Talk to us in the [Discord Developers Server](https://discord.gg/discord-developers)!
6 |
7 |
8 |
9 | This page outlines some of the common errors codes that may be encountered when using Dispatch.
10 |
11 | | Code | Name | Possible Solution |
12 | | ---- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
13 | | 2020 | Request Signing Failed | Check user entitlement |
14 | | 2022 | Disk Space Low | Free up disk space |
15 | | 2023 | Disk Permission Denied | Choose a new location, or change write permissions on desired location |
16 | | 2024 | Uninstall Failed | Attempt to manually remove game files from disk |
17 | | 2025 | Install Script Failed | Restart Discord, attempt to uninstall/reinstall the game, ensure script is correct |
18 | | 2029 | Build Not Found | Completely close and re-open Discord |
19 | | 2051 | Panic! | Escalate in the dev server in #dispatch |
20 | | 2058 | Too Many API Retries | Escalate in the #dispatch channel of the [Discord Developers server](https://discord.gg/discord-developers) |
21 | | 2059 | Failed to set Registry Key | User most likely denied Windows administrator permissions prompt. Try again, and accept the prompt |
22 | | 2064 | Failed to Patch File | Attempted to patch the game while running: ensure the game process is entirely ended, try restarting Discord, try disabling antivirus |
23 | | 2065 | No Manifests | Ensure that your manifests are properly selected in the Developer Portal for your SKU |
24 | | 2069 | API Error | Intermittent API issues. Wait, escalate to #dispatch in the dev server if it persists |
25 | | 2070 | Bad Reponse | Intermittent API issues. Wait, escalate to #dispatch in the dev server if it persists |
26 | | 2073 | Not Entitled | Check that your manifests are properly configured in the Developer Portal. Have the user install the game from the Library, not the store page |
27 | | 2076 | Two Clients Patching | User has multiple Discords open trying to patch the same game; only use one |
28 | | 9001 | Unknown | Catch-all error code. Escalate to #dispatch in dev server with repro steps/as much info as possible |
29 |
--------------------------------------------------------------------------------
/pages/game-and-server-management/special-channels.mdx:
--------------------------------------------------------------------------------
1 | # Store Channels
2 |
3 | One of the new flagship features of Verified Servers and Game Servers are the ability to host your store pages directly in your server. We know that community is everything for games, and that your server is already the place where your community lives. Rather than the friction and impersonality of traditional storefronts, you can let your fans find your game in the cozy comfort of their home (your server!).
4 |
5 | In order to create a store channel for your game, you'll need to make sure you've followed [the Walkthrough](/game-and-server-management/how-to-get-your-game-on-discord/) up to `Getting Approved`. If you've done that, you'll see in your server that you can create a new channel type: `Store`.
6 |
7 | 
8 |
9 | Along with entering a name for your new channel, you'll be prompted to select an application. This should be the app you created when you started; it's the one linked to your server. After selecting your app, you'll be prompted to select a SKU. What's a SKU? A SKU is simply a thing that a user can buy. This is most likely your game (a SKU of type `Game`), but could also be `IAP`, `DLC`, or a `Bundle`.
10 |
11 | You can create SKUs to put up for sale by going to your app and selecting `SKU Management`.
12 |
13 | 
14 |
15 | Once you select your SKU and create your channel...it's there! You now have a store channel in your server! If you want, you can set permissions on this channel like any channel in a server to restrict who can see it. Learn more about that by reading [Alpha and Beta Testing](/game-and-server-management/alpha-and-beta-testing/).
16 |
17 | ## Lurker Mode
18 |
19 | Store channels also have a special property that we call `lurkability`. "Lurker Mode" is a feature that we've been experimenting with throughout Discord; it allows users to read public channels in a server without _actually_ joining the server. It also allows users to look at these channels without being logged in to Discord.
20 |
21 |
22 |
23 | Users viewing channels in Lurker Mode will not be able to send messages in those channels. They'll be prompted to log in and join the server if they want to chat.
24 |
25 |
26 |
27 | Lurker Mode is automatically enabled for store channels in your server. When someone accepts a server invite that links to a store channel, they'll be viewing in "Lurker Mode".
28 |
29 | We know that your server and community are at the heart of your game's success on Discord. Having Discord users see your store pages in the context of your server will help drive more members to your community and help you grow that awesome fanbase for your game.
30 |
31 | # Announcement Channels
32 |
33 | As part of our ongoing effort to help you build your game community, all [Community servers](https://dis.gd/communityservers) (along with [Developer License](/game-and-server-management/how-to-get-your-game-on-discord#your-server---your-kingdom) servers) have the ability to create Announcement Channels!
34 |
35 | Unlike a regular text channel, Announcement Channels comes with a “Follow” button that allows your superfans to hook and connect your channel into their own personal servers. Now, select messages in your Announcement Channels can be "published" in your players' friend servers as regular messages, allowing them to get the latest updates of their favorite game in the places they hang out most. Because these posts appear and function as messages, it means that everyone in your superfan’s server can find them, discuss them live, and receive them as mobile notifications, if they have this setting enabled.
36 |
37 | [Learn more here](https://support.discord.com/hc/en-us/articles/360032008192).
38 |
--------------------------------------------------------------------------------
/pages/resources/voice.mdx:
--------------------------------------------------------------------------------
1 | # Voice Resource
2 |
3 | ### Voice State Object
4 |
5 | Used to represent a user's voice connection status.
6 |
7 | ###### Voice State Structure
8 |
9 | | Field | Type | Description |
10 | | -------------------------- | ----------------------------------------------------------- | ---------------------------------------------- |
11 | | guild_id? | snowflake | the guild id this voice state is for |
12 | | channel_id | ?snowflake | the channel id this user is connected to |
13 | | user_id | snowflake | the user id this voice state is for |
14 | | member? | [guild member](/resources/guild#guild-member-object) object | the guild member this voice state is for |
15 | | session_id | string | the session id for this voice state |
16 | | deaf | boolean | whether this user is deafened by the server |
17 | | mute | boolean | whether this user is muted by the server |
18 | | self_deaf | boolean | whether this user is locally deafened |
19 | | self_mute | boolean | whether this user is locally muted |
20 | | self_stream? | boolean | whether this user is streaming using "Go Live" |
21 | | self_video | boolean | whether this user's camera is enabled |
22 | | suppress | boolean | whether this user is muted by the current user |
23 | | request_to_speak_timestamp | ?ISO8601 timestamp | the time at which the user requested to speak |
24 |
25 | ###### Example Voice State
26 |
27 | ```json
28 | {
29 | "channel_id": "157733188964188161",
30 | "user_id": "80351110224678912",
31 | "session_id": "90326bd25d71d39b9ef95b299e3872ff",
32 | "deaf": false,
33 | "mute": false,
34 | "self_deaf": false,
35 | "self_mute": true,
36 | "suppress": false,
37 | "request_to_speak_timestamp": "2021-03-31T18:45:31.297561+00:00"
38 | }
39 | ```
40 |
41 | ### Voice Region Object
42 |
43 | ###### Voice Region Structure
44 |
45 | | Field | Type | Description |
46 | | ---------- | ------- | --------------------------------------------------------------------- |
47 | | id | string | unique ID for the region |
48 | | name | string | name of the region |
49 | | vip | boolean | true if this is a vip-only server |
50 | | optimal | boolean | true for a single server that is closest to the current user's client |
51 | | deprecated | boolean | whether this is a deprecated voice region (avoid switching to these) |
52 | | custom | boolean | whether this is a custom voice region (used for events/etc) |
53 |
54 | ## Endpoints
55 |
56 |
57 | List Voice Regions
58 |
59 |
60 | Returns an array of [voice region](#voice-region-object) objects that can be used when creating servers.
61 |
--------------------------------------------------------------------------------
/pages/rich-presence/faq.mdx:
--------------------------------------------------------------------------------
1 | # Rich Presence FAQ
2 |
3 |
4 |
5 | The SDK that this documentation references, [Discord-RPC](https://github.com/discord/discord-rpc), has been deprecated in favor of our new [Discord GameSDK](/game-sdk/sdk-starter-guide/). Replacement functionality for the Rich Presence SDK can be found in the [Activity Manager](/game-sdk/activities/) of that SDK. This documentation can be referenced for education but does not entirely reflect the new SDK.
6 |
7 |
8 |
9 | Below are answers to some common questions about integrating Rich Presence with your game. If you don't see your question answered here, feel free to reach out to [gamedevs@discord.com](mailto:gamedevs@discord.com) for more help.
10 |
11 | #### Q: I see "Playing MyGame", but no Rich Presence data.
12 |
13 | There's a couple things that could be going on:
14 |
15 | - If you're running two instances of the Discord client, check both!
16 | - Double check that your `Discord_Initialize()` function is correct.
17 |
18 | Throughout development, make sure you have your `errored()` and `disconnected()` callbacks hooked up for debugging. You can open up the console in Discord and look for errors pertaining to `SET_ACTIVITY` for more information as well.
19 |
20 | #### Q: I'm not seeing Spectate buttons on my profile.
21 |
22 | Make sure you applied for approval! If you want the Spectate button on your players' profiles, we require your integration to go through an approval process. If you have applied and have been approved and still don't see the buttons, check your Discord console for errors.
23 |
24 | #### Q: What happens if someone has more than one game running that supports Rich Presence?
25 |
26 | Due to recent changes in our infrastructure for support of multi-activities, the behavior of multiple connected Rich Presence apps has changed from what it was before. Previously, whichever application was focused would be the presence that was shown. With the recent changes, the application that connected _first_ is now displayed.
27 |
28 | However, invite functionality across multiple connected applications now works no matter which app is display on a user's profile. For example, if you are hosting a Spotify listening party, playing Game A that allows you to send Join invites, and playing Game B that allows you to send Spectate invites, you'll be able to send invites to all three simultaneously!
29 |
30 | #### Q: What if someone looking at my profile or an invite doesn't own the game?
31 |
32 | Anyone can see your profile data, whether they own the game or not. They'll only be able to interact with chat invites or profile buttons if they own the game and have launched it at least once. Otherwise, the invite/button tooltip will show "Game Not Detected".
33 |
34 | #### Q: Do join invitations allow players to select the number of open slots?
35 |
36 | Currently, the SDK does not support this. Party slot information is determined by the party data you sent in your presence payload.
37 |
38 | #### Q: Can I send images via the payload rather than uploading them to my Developer Dashboard?
39 |
40 | Unfortunately, the SDK does not support this feature right now. However, we hear your desires! We know that a lot of games, like customization-heavy RPGs, would benefit greatly from being able to programmatically upload assets. It may be something we tackle in the future.
41 |
42 | #### Q: Can I change something in the SDK for my own purposes?
43 |
44 | Go nuts! The SDK is open source by design. If you need or want to change something for the purposes of your specific integration—like changing our JSON parser, or changing all of the variable names to the names of your pets—go ahead and tinker to your heart's content.
45 |
46 | #### Q: OK—I've got it working! Now, how do I make my integration look _awesome_?
47 |
48 | I'm happy ~~we preempted your question~~ you asked! Check out our [Rich Presence Best Practices](/rich-presence/best-practices/) guide for a rundown on how to make your integration the best that it can be!
49 |
--------------------------------------------------------------------------------
/pages/dispatch/field-values.mdx:
--------------------------------------------------------------------------------
1 | # Predefined Field Values
2 |
3 |
4 |
5 | Need help with Dispatch? Talk to us in the [Discord Developers Server](https://discord.gg/discord-developers)!
6 |
7 |
8 |
9 | ###### Accepted Locales
10 |
11 | | Locale | Language Name |
12 | | ------ | ----------------------- |
13 | | en-US | English (United States) |
14 | | en-GB | English (Great Britain) |
15 | | zh-CN | Chinese (China) |
16 | | zh-TW | Chinese (Taiwan) |
17 | | cs | Czech |
18 | | da | Danish |
19 | | nl | Dutch |
20 | | fr | French |
21 | | de | German |
22 | | el | Greek |
23 | | hu | Hungarian |
24 | | it | Italian |
25 | | ja | Japanese |
26 | | ko | Korean |
27 | | no | Norwegian |
28 | | pl | Polish |
29 | | pt-BR | Portuguese (Brazil) |
30 | | ru | Russian |
31 | | es-ES | Spanish (Spain) |
32 | | sv-SE | Swedish |
33 | | tr | Turkish |
34 | | bg | Bulgarian |
35 | | uk | Ukrainian |
36 | | fi | Finnish |
37 | | hr | Croatian |
38 | | ro | Romanian |
39 | | lt | Lithuanian |
40 |
41 | ## Manifests
42 |
43 | ###### Platform Values
44 |
45 | | Platform |
46 | | -------- |
47 | | macos |
48 | | win32 |
49 | | win64 |
50 | | linux |
51 |
52 | ###### Redistributable values
53 |
54 | | Redistributable |
55 | | -------------------------- |
56 | | directx_june_2010 |
57 | | vcredist_2005_x86 |
58 | | vcredist_2008_sp1_x86 |
59 | | vcredist_2010_x64 |
60 | | vcredist_2010_x86 |
61 | | vcredist_2012_update_4_x64 |
62 | | vcredist_2012_update_4_x86 |
63 | | vcredist_2013_x64 |
64 | | vcredist_2013_x86 |
65 | | vcredist_2015_x64 |
66 | | vcredist_2015_x86 |
67 | | vcredist_2017_x64 |
68 | | vcredist_2017_x86 |
69 | | xnafx_40 |
70 |
71 | ###### Cloud Save Path Replacements
72 |
73 | | value | Windows path | macOS path | linux path |
74 | | ---------------- | ----------------------------------------------------------------------------------- | ----------------------------- | ------------------- |
75 | | \${HOME} | %USERPROFILE% | ~/ | ~/ |
76 | | \${DOCUMENTS} | %USERPROFILE%\Documents | ~/Documents | \$XDG_DOCUMENTS_DIR |
77 | | \${DATA} | %USERPROFILE%\AppData\Roaming | ~/Library/Application Support | \$XDG_DATA_HOME |
78 | | \${DATALOCAL} | %USERPROFILE%\AppData\Local | ~/Library/Application Support | \$XDG_DATA_HOME |
79 | | \${DATALOCALLOW} | %USERPROFILE%\AppData\LocalLow | ~/Library/Application Support | \$XDG_DATA_HOME |
80 | | \${SAVEDGAMES} | %USERPROFILE%\Saved Games | (not supported) | (not supported) |
81 | | \${INSTALLDIR} | the game's install directory | (same) | (same) |
82 | | \${USERID} | the user's id - use within a path to define saves for multiple users | (same) | (same) |
83 | | \${BRANCHID} | the id of the game branch - use within a path to define saves for multiple branches | (same) | (same) |
84 |
--------------------------------------------------------------------------------
/components/Snowflake.tsx:
--------------------------------------------------------------------------------
1 | export default function Snowflake(props: unknown) {
2 | return (
3 |
127 | );
128 | }
129 |
--------------------------------------------------------------------------------
/components/icons/Discord.tsx:
--------------------------------------------------------------------------------
1 | export default function Discord(props: JSX.IntrinsicElements["svg"]) {
2 | return (
3 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/pages/resources/stage-instance.mdx:
--------------------------------------------------------------------------------
1 | # Stage Instance Resource
2 |
3 | A _Stage Instance_ holds information about a live stage.
4 |
5 | ### Stage Instance Object
6 |
7 | ###### Stage Instance Structure
8 |
9 | | Field | Type | Description |
10 | | --------------------- | --------- | --------------------------------------------------------- |
11 | | id | snowflake | The id of this Stage instance |
12 | | guild_id | snowflake | The guild id of the associated Stage channel |
13 | | channel_id | snowflake | The id of the associated Stage channel |
14 | | topic | string | The topic of the Stage instance (1-120 characters) |
15 | | privacy_level | integer | The [privacy level](#privacy-level) of the Stage instance |
16 | | discoverable_disabled | boolean | Whether or not Stage Discovery is disabled |
17 |
18 | ###### Privacy Level
19 |
20 | | Level | Value | Description |
21 | | ---------- | ----- | ------------------------------------------------------------------- |
22 | | PUBLIC | 1 | The Stage instance is visible publicly, such as on Stage Discovery. |
23 | | GUILD_ONLY | 2 | The Stage instance is visible to only guild members. |
24 |
25 | ###### Example Stage Instance
26 |
27 | ```json
28 | {
29 | "id": "840647391636226060",
30 | "guild_id": "197038439483310086",
31 | "channel_id": "733488538393510049",
32 | "topic": "Testing Testing, 123",
33 | "privacy_level": 1,
34 | "discoverable_disabled": false
35 | }
36 | ```
37 |
38 | ## Definitions
39 |
40 | Below are some definitions related to stages.
41 |
42 | - **Liveness:** A Stage channel is considered _live_ when there is an associated stage instance. Conversely, a Stage channel is _not live_ when there is no associated stage instance.
43 | - **Speakers:** A participant of a Stage channel is a _speaker_ when their [voice state](/resources/voice#voice-state-object)
44 | is not `suppress`ed, and has no `request_to_speak_timestamp`.
45 | - **Moderators**: A member of the guild is a _moderator_ of a Stage channel if they have all of the following [permissions](/topics/permissions#permissions):
46 | - `MANAGE_CHANNELS`
47 | - `MUTE_MEMBERS`
48 | - `MOVE_MEMBERS`
49 | - **Topic**: This is the blurb that gets shown below the channel's name, among other places.
50 | - **Public**: A Stage instance is public when it has a `privacy_level` of `PUBLIC`. While a guild has a public Stage instance:
51 | - The guild will be lurkable.
52 | - Lurkers may join any Stage channel with a public Stage instance.
53 | - Users in the Stage can have the Stage show in their [activities](/topics/gateway#presence).
54 | - [Invites](/resources/invite#invite-object) to the Stage channel will have the `stage_instance` field.
55 |
56 | ## Auto Closing
57 |
58 | When a Stage channel has no speakers for a certain period of time (on the order of minutes) it will be automatically deleted.
59 |
60 |
61 | Create Stage Instance
62 |
63 |
64 | Creates a new Stage instance associated to a Stage channel.
65 |
66 | Requires the user to be a moderator of the Stage channel.
67 |
68 | ###### JSON Params
69 |
70 | | Field | Type | Description |
71 | | -------------- | --------- | ------------------------------------------------------------------------------ |
72 | | channel_id | snowflake | The id of the Stage channel |
73 | | topic | string | The topic of the Stage instance (1-120 characters) |
74 | | privacy_level? | integer | The [privacy level](#privacy-level) of the Stage instance (default GUILD_ONLY) |
75 |
76 | ## Endpoints
77 |
78 |
79 | Get Stage Instance
80 |
81 |
82 | Gets the stage instance associated with the Stage channel, if it exists.
83 |
84 |
85 | Modify Stage Instance
86 |
87 |
88 | Updates fields of an existing Stage instance.
89 |
90 | Requires the user to be a moderator of the Stage channel.
91 |
92 | ###### JSON Params
93 |
94 | | Field | Type | Description |
95 | | -------------- | ------- | --------------------------------------------------------- |
96 | | topic? | string | The topic of the Stage instance (1-120 characters) |
97 | | privacy_level? | integer | The [privacy level](#privacy-level) of the Stage instance |
98 |
99 |
100 | Delete Stage Instance
101 |
102 |
103 | Deletes the Stage instance.
104 |
105 | Requires the user to be a moderator of the Stage channel.
106 |
--------------------------------------------------------------------------------
/pages/topics/teams.mdx:
--------------------------------------------------------------------------------
1 | # Teams
2 |
3 | Teams are groups of developers on Discord who want to collaborate on apps. On other platforms, these may be referred to as "organizations", "companies", or "teams". We went with the name Teams because it best encompassed all the awesome conglomerates of devs that work together to make awesome things on Discord. Also, we never got picked for kickball in gym class, so now we get to be on a team.
4 |
5 | ## What Do They Do
6 |
7 | Teams allow you and other Discord users to share access to apps. No more sharing login credentials in order to reset the token on a bot that your friend owns but you work on, or other such cases.
8 |
9 | For game developers, this means that you can get your engineers access to your app for credentials they may need, your marketing folks access to store page management, and your finance people access to sales and performance metrics.
10 |
11 |
12 |
13 | For the initial release, Teams only support one kind of user: Admin. Admins have full access to all parts of an app _except_ for deleting the app and adding/removing users. That can only be done by the owner of the Team.
14 |
15 |
16 |
17 | ## How Do I Make One
18 |
19 | Making a Team is easy! Head on over to our [Team creation](https://discord.com/developers/teams) page and make your own.
20 |
21 | 
22 |
23 | Note that to use Discord Teams, you need to have 2FA enabled on your account. Security is of the utmost importance, especially when it comes to shared resources. If you're developing on your own and don't want to use Teams, you do not need 2FA. But, in order to keep other Team members safe, you'll need to add it to use Teams.
24 |
25 | 
26 |
27 | Once your team is made, you can start inviting other Discord users to join.
28 |
29 |
30 |
31 | For the initial release, only the Team owner can invite or remove additional users.
32 |
33 |
34 |
35 | ## Apps on Teams
36 |
37 | Now that you've got your Team set up, you can start creating apps under it. Teams can own a maximum of 25 apps. To create a new app under a Team, select the Team in the app creation modal. If you want to keep the app under your own ownership, choose `Personal`:
38 |
39 | 
40 |
41 | If you have an existing app that you want to transfer to a Team, you can do that, too! Just go into the app that you want to transfer, hit `Transfer App to Team`, and send the app to its new home.
42 |
43 | 
44 |
45 |
46 |
47 | Once an app has been transferred to a team, it _cannot_ be transferred back.
48 |
49 |
50 |
51 | ## What Next
52 |
53 | What next? Go make awesome stuff! Whether you're a Game Developer, Mad Bot Scientist, or OAuth2 Enthusiast, you can now work together with other like-minded Discordians to bring your creations to life.
54 |
55 | We've got a lot of awesome features planned for teams in the future, so stay tuned for things like:
56 |
57 | - Roles and Permissions
58 | - Audit Logs
59 | - More cat pictures
60 |
61 | Go team!
62 |
63 | ## Data Models
64 |
65 | ###### Team Object
66 |
67 | | field | type | description |
68 | | ------------- | ---------------------------------------------------- | -------------------------------------- |
69 | | icon | ?string | a hash of the image of the team's icon |
70 | | id | snowflake | the unique id of the team |
71 | | members | array of [team member](#team-members-object) objects | the members of the team |
72 | | name | string | the name of the team |
73 | | owner_user_id | snowflake | the user id of the current team owner |
74 |
75 | ###### Team Members Object
76 |
77 | | field | type | description |
78 | | ---------------- | -------------------------------------------------- | ----------------------------------------------------------------- |
79 | | membership_state | integer | the user's [membership state](#membership-state-enum) on the team |
80 | | permissions | array of strings | will always be `["*"]` |
81 | | team_id | snowflake | the id of the parent team of which they are a member |
82 | | user | partial [user](/resources/user#user-object) object | the avatar, discriminator, id, and username of the user |
83 |
84 | ###### Membership State Enum
85 |
86 | | name | value |
87 | | -------- | ----- |
88 | | INVITED | 1 |
89 | | ACCEPTED | 2 |
90 |
--------------------------------------------------------------------------------
/pages/game-and-server-management/alpha-and-beta-testing.mdx:
--------------------------------------------------------------------------------
1 | # Alpha and Beta Testing
2 |
3 | Alphas and betas are a critical part of a game's development lifecycle. We understand the value of getting feedback early and often and involving your community early on. That's why we've built some awesome alpha and beta testing functionality for you!
4 |
5 | ## Beta Entitlements
6 |
7 | As you develop your game, you'll constantly be making improvements. You want real-time feedback from players, and there's no better place for that than Discord. In the past, players would need to dig through menus to find out how to unlock test branches, as well as remembering secret passwords _and_ typing them in correctly. Was that an `I` or an `l`? `O` or `0`?
8 |
9 | One of the cool features of [Store Channels](/game-and-server-management/special-channels/) is their ability to grant a Beta Entitlement for your game. That means that while you keep your master branch safe and sound, users can test on `beta-branch-please-ignore-bugs` in an isolated test environment.
10 |
11 |
12 |
13 | To learn more about creating branches, start with [Dispatch and You](/dispatch/dispatch-and-you/).
14 |
15 |
16 |
17 | When you create a store channel in your server, you'll be prompted with a choice to make it a Beta channel. That will allow you to grant users entitlement to the non-master branch of your game when visiting the store page. When your beta period is over and your game is ready for release and purchase, you can brick/delete these branches if you choose, and prompt users to get the full game by putting up a new store channel that's not Beta.
18 |
19 |
20 |
21 | Beta branches cannot be sold. If a user has access to a store channel for a beta entitlement, they will be able to claim it for free.
22 |
23 |
24 |
25 | ## Role-Based Entitlement
26 |
27 | So, you've started getting a bunch of fans into your server. Hundreds, thousands, millions! Uh, if you hit millions, let us know. Within your hordes of adoring fans lies your Trusted Testing Group (tm), the best of the best when it comes to feedback. Maybe you want to give them access to a special `insider-only-private-beta` branch of your game. You can, with role-based entitlement!
28 |
29 | Store channels in Discord are just like any other channel in that they can have a set of permissions applied to them. What is special about them is that if they are set as a Beta branch, entitlement to that branch is tied to having permissions to view the channel. So, all your testers with a `Beta Tester` role, for example, will be able to get entitlement to the `insider-only-private-beta` branch. And, if they are later removed from that role, entitlement from that branch will be removed.
30 |
31 | A scenario might look like this: you create a Beta store channel. Only users with role `Awesome Tester` can view it. Player A is an `Awesome Tester`. They can view the channel and get entitlement to the beta branch. Player A becomes inactive; you remove them from the `Awesome Tester` role. Player A loses entitlement to `insider-only-private-beta`
32 |
33 |
34 |
35 | Role-based entitlement will only work if you use Discord's DRM, which is a simple entitlement check. You can do that with the Dispatch command [`dispatch build drm-wrap`](/dispatch/list-of-commands#build-drm-wrap) or by calling [`ApplicationManager.ValidateOrExit()`](/game-sdk/applications#validateorexit). Otherwise, Discord will not check the user's entitlement when the game starts.
36 |
37 |
38 |
39 | Role-based entitlements help keep your beta community active and interactive, while also providing a way to reward your biggest fans with secret access to special things.
40 |
41 | ## Gift Codes
42 |
43 |
44 |
45 | Note that only Approved Games can generate gift codes.
46 |
47 |
48 |
49 | If you want to push out access to your game at scale, rather than inviting people into your server and giving them a role, you can create gift codes in the Developer Portal! Gift codes are like game keys on other platforms that you might be familiar with, with an added bonus: the ability to specify the entitlement time window. That means that you can create codes for your game to give to everyone, but they won't be able to play until the `VALID FROM` date. Similarly, you can set a `VALID UNTIL` date on all your gift codes if you want the entitlements to expire after a certain time, removing access from players.
50 |
51 | Note that the `VALID UNTIL` date will not remove the game from the user's library, but they will no longer be able to launch it.
52 |
53 | Up to 25,000 gift codes can be created at a time. When you go to create gift codes, you'll notice there are a few fields for you to fill out. Here's what they mean:
54 |
55 |
62 |
63 | - SKU: the SKU that you want the user to get
64 | - Branch: the branch of your game you want the user to get
65 | - Valid From: the start date at which the entitlement is valid
66 | - Valid Until: the date at which the entitlement is no longer valid
67 | - Amount: the number of codes you want to create (up to 25,000 per batch)
68 | - Description: a short description of why you made the codes, so you remember!
69 |
70 | Once you've made your codes, you can download the `.csv` that has them all in it, and distribute them however you'd like!
71 |
--------------------------------------------------------------------------------
/components/mdx/Code.tsx:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 |
3 | import React from "react";
4 | import Highlight, { Prism, defaultProps } from "prism-react-renderer";
5 | import classNames from "classnames";
6 |
7 | import FileIcon from "../icons/File";
8 | import CopyIcon from "../icons/Copy";
9 | import CopyButton from "../Copy";
10 |
11 | // Extend base classes
12 | globalThis.Prism = Prism;
13 | import("prismjs/components/prism-docker");
14 |
15 | const diffBgColorMap = {
16 | "+": "var(--prism-highlight-add)",
17 | "-": "var(--prism-highlight-delete)",
18 | "|": "var(--prism-highlight)",
19 | };
20 |
21 | const SYMBOLS = {
22 | normal: "|",
23 | add: "+",
24 | delete: "-",
25 | };
26 |
27 | function cleanTokens(tokens: Token[][]): Token[][] {
28 | const tokensLength = tokens.length;
29 |
30 | if (tokensLength === 0) {
31 | return tokens;
32 | }
33 |
34 | const lastToken = tokens[tokensLength - 1];
35 |
36 | if (lastToken.length === 1 && lastToken[0].empty) {
37 | return tokens.slice(0, tokensLength - 1);
38 | }
39 |
40 | return tokens;
41 | }
42 |
43 | interface InfoBarProps {
44 | fileName?: string | null;
45 | language: string;
46 | }
47 |
48 | function InfoBar({ fileName, language }: InfoBarProps) {
49 | return (
50 |
168 | );
169 | }
170 |
--------------------------------------------------------------------------------
/pages/resources/application.mdx:
--------------------------------------------------------------------------------
1 | # Application Resource
2 |
3 | ### Application Object
4 |
5 | ###### Application Structure
6 |
7 | | Field | Type | Description |
8 | | ---------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
9 | | id | snowflake | the id of the app |
10 | | name | string | the name of the app |
11 | | icon | ?string | the [icon hash](/reference#image-formatting) of the app |
12 | | description | string | the description of the app |
13 | | rpc_origins? | array of strings | an array of rpc origin urls, if rpc is enabled |
14 | | bot_public | boolean | when false only app owner can join the app's bot to guilds |
15 | | bot_require_code_grant | boolean | when true the app's bot will only join upon completion of the full oauth2 code grant flow |
16 | | terms_of_service_url? | string | the url of the app's terms of service |
17 | | privacy_policy_url? | string | the url of the app's privacy policy |
18 | | owner? | partial [user](/resources/user#user-object) object | partial user object containing info on the owner of the application |
19 | | summary | string | if this application is a game sold on Discord, this field will be the summary field for the store page of its primary sku |
20 | | verify_key | string | the hex encoded key for verification in interactions and the GameSDK's [GetTicket](/game-sdk/applications#getticket) |
21 | | team | ?[team](/topics/teams#team-object) object | if the application belongs to a team, this will be a list of the members of that team |
22 | | guild_id? | snowflake | if this application is a game sold on Discord, this field will be the guild to which it has been linked |
23 | | primary_sku_id? | snowflake | if this application is a game sold on Discord, this field will be the id of the "Game SKU" that is created, if exists |
24 | | slug? | string | if this application is a game sold on Discord, this field will be the URL slug that links to the store page |
25 | | cover_image? | string | the application's default rich presence invite [cover image hash](/reference#image-formatting) |
26 | | flags? | integer | the application's public [flags](/resources/application#application-flags) |
27 |
28 | ###### Example Application Object
29 |
30 | ```json
31 | {
32 | "bot_public": true,
33 | "bot_require_code_grant": false,
34 | "cover_image": "31deabb7e45b6c8ecfef77d2f99c81a5",
35 | "description": "Test",
36 | "guild_id": "290926798626357260",
37 | "icon": null,
38 | "id": "172150183260323840",
39 | "name": "Baba O-Riley",
40 | "owner": {
41 | "avatar": null,
42 | "discriminator": "1738",
43 | "flags": 1024,
44 | "id": "172150183260323840",
45 | "username": "i own a bot"
46 | },
47 | "primary_sku_id": "172150183260323840",
48 | "slug": "test",
49 | "summary": "This is a game",
50 | "team": {
51 | "icon": "dd9b7dcfdf5351b9c3de0fe167bacbe1",
52 | "id": "531992624043786253",
53 | "members": [
54 | {
55 | "membership_state": 2,
56 | "permissions": ["*"],
57 | "team_id": "531992624043786253",
58 | "user": {
59 | "avatar": "d9e261cd35999608eb7e3de1fae3688b",
60 | "discriminator": "0001",
61 | "id": "511972282709709995",
62 | "username": "Mr Owner"
63 | }
64 | }
65 | ]
66 | },
67 | "verify_key": "1e0a356058d627ca38a5c8c9648818061d49e49bd9da9e3ab17d98ad4d6bg2u8"
68 | }
69 | ```
70 |
71 | ###### Application Flags
72 |
73 | | Value | Flag |
74 | | ------- | -------------------------------- |
75 | | 1 << 12 | GATEWAY_PRESENCE |
76 | | 1 << 13 | GATEWAY_PRESENCE_LIMITED |
77 | | 1 << 14 | GATEWAY_GUILD_MEMBERS |
78 | | 1 << 15 | GATEWAY_GUILD_MEMBERS_LIMITED |
79 | | 1 << 16 | VERIFICATION_PENDING_GUILD_LIMIT |
80 | | 1 << 17 | EMBEDDED |
81 |
--------------------------------------------------------------------------------
/pages/resources/emoji.mdx:
--------------------------------------------------------------------------------
1 | # Emoji Resource
2 |
3 |
4 |
5 | Routes for controlling emojis do not follow the normal rate limit conventions. These routes are specifically limited on a per-guild basis to prevent abuse. This means that the quota returned by our APIs may be inaccurate, and you may encounter 429s.
6 |
7 |
8 |
9 | ### Emoji Object
10 |
11 | ###### Emoji Structure
12 |
13 | | Field | Type | Description |
14 | | --------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------- |
15 | | id | ?snowflake | [emoji id](/reference#image-formatting) |
16 | | name | ?string (can be null only in reaction emoji objects) | emoji name |
17 | | roles? | array of [role](/topics/permissions#role-object) object ids | roles allowed to use this emoji |
18 | | user? | [user](/resources/user#user-object) object | user that created this emoji |
19 | | require_colons? | boolean | whether this emoji must be wrapped in colons |
20 | | managed? | boolean | whether this emoji is managed |
21 | | animated? | boolean | whether this emoji is animated |
22 | | available? | boolean | whether this emoji can be used, may be false due to loss of Server Boosts |
23 |
24 | ###### Emoji Example
25 |
26 | ```json
27 | {
28 | "id": "41771983429993937",
29 | "name": "LUL",
30 | "roles": ["41771983429993000", "41771983429993111"],
31 | "user": {
32 | "username": "Luigi",
33 | "discriminator": "0002",
34 | "id": "96008815106887111",
35 | "avatar": "5500909a3274e1812beb4e8de6631111",
36 | "public_flags": 131328
37 | },
38 | "require_colons": true,
39 | "managed": false,
40 | "animated": false
41 | }
42 | ```
43 |
44 | ###### Gateway Reaction Standard Emoji Example
45 |
46 | ```json
47 | {
48 | "id": null,
49 | "name": "🔥"
50 | }
51 | ```
52 |
53 | ###### Gateway Reaction Custom Emoji Examples
54 |
55 |
56 |
57 | In `MESSAGE_REACTION_ADD` gateway events `animated` will be returned for animated emoji.
58 |
59 |
60 |
61 |
62 |
63 | In `MESSAGE_REACTION_ADD` and `MESSAGE_REACTION_REMOVE` gateway events `name` may be `null` when custom emoji data is not available (for example, if it was deleted from the guild).
64 |
65 |
66 |
67 | ```json
68 | {
69 | "id": "41771983429993937",
70 | "name": "LUL",
71 | "animated": true
72 | }
73 | ```
74 |
75 | ```json
76 | {
77 | "id": "41771983429993937",
78 | "name": null
79 | }
80 | ```
81 |
82 | ## Endpoints
83 |
84 |
85 | List Guild Emojis
86 |
87 |
88 | Returns a list of [emoji](#emoji-object) objects for the given guild.
89 |
90 |
91 | Get Guild Emoji
92 |
93 |
94 | Returns an [emoji](#emoji-object) object for the given guild and emoji IDs.
95 |
96 |
97 | Create Guild Emoji
98 |
99 |
100 | Create a new emoji for the guild. Requires the `MANAGE_EMOJIS_AND_STICKERS` permission. Returns the new [emoji](#emoji-object) object on success. Fires a [Guild Emojis Update](/topics/gateway#guild-emojis-update) Gateway event.
101 |
102 |
103 |
104 | Emojis and animated emojis have a maximum file size of 256kb. Attempting to upload an emoji larger than this limit will fail and return 400 Bad Request and an error message, but not a [JSON status code](/topics/opcodes-and-status-codes#json).
105 |
106 |
107 |
108 | ###### JSON Params
109 |
110 | | Field | Type | Description |
111 | | ----- | ----------------------------------- | ------------------------------- |
112 | | name | string | name of the emoji |
113 | | image | [image data](/reference#image-data) | the 128x128 emoji image |
114 | | roles | array of snowflakes | roles allowed to use this emoji |
115 |
116 |
117 | Modify Guild Emoji
118 |
119 |
120 | Modify the given emoji. Requires the `MANAGE_EMOJIS_AND_STICKERS` permission. Returns the updated [emoji](#emoji-object) object on success. Fires a [Guild Emojis Update](/topics/gateway#guild-emojis-update) Gateway event.
121 |
122 |
123 |
124 | All parameters to this endpoint are optional.
125 |
126 |
127 |
128 | ###### JSON Params
129 |
130 | | Field | Type | Description |
131 | | ----- | -------------------- | ------------------------------- |
132 | | name | string | name of the emoji |
133 | | roles | ?array of snowflakes | roles allowed to use this emoji |
134 |
135 |
136 | Delete Guild Emoji
137 |
138 |
139 | Delete the given emoji. Requires the `MANAGE_EMOJIS_AND_STICKERS` permission. Returns `204 No Content` on success. Fires a [Guild Emojis Update](/topics/gateway#guild-emojis-update) Gateway event.
140 |
--------------------------------------------------------------------------------
/pages/game-sdk/users.mdx:
--------------------------------------------------------------------------------
1 | # Users
2 |
3 |
4 |
5 | Need help with the SDK? Talk to us in the [Discord Developers Server](https://discord.gg/discord-developers)!
6 |
7 |
8 |
9 |
10 |
11 | Game approval submissions are currently paused due to unforeseen circumstances. We apologize for the inconvenience. [Click here for more info.](https://support-dev.discord.com/hc/en-us/articles/360041437171)
12 |
13 |
14 |
15 | This manager helps retrieve basic user information for any user on Discord.
16 |
17 | ## Data Models
18 |
19 | ###### User Struct
20 |
21 | | name | type | description |
22 | | ------------- | ------ | ----------------------------- |
23 | | Id | Int64 | the user's id |
24 | | Username | string | their name |
25 | | Discriminator | string | the user's unique discrim |
26 | | Avatar | string | the hash of the user's avatar |
27 | | Bot | bool | if the user is a bot user |
28 |
29 | ###### UserFlag Enum
30 |
31 | | name | value | description |
32 | | --------------- | ----- | ---------------------------- |
33 | | Partner | 2 | Discord Partner |
34 | | HypeSquadEvents | 4 | HypeSquad Events participant |
35 | | HypeSquadHouse1 | 64 | House Bravery |
36 | | HypeSquadHouse2 | 128 | House Brilliance |
37 | | HypeSquadHouse3 | 256 | House Balance |
38 |
39 | ###### PremiumType Enum
40 |
41 | | name | value | description |
42 | | ----- | ----- | ------------------------ |
43 | | None | 0 | Not a Nitro subscriber |
44 | | Tier1 | 1 | Nitro Classic subscriber |
45 | | Tier2 | 2 | Nitro subscriber |
46 |
47 | ## GetCurrentUser
48 |
49 |
50 |
51 | Before calling this function, you'll need to wait for the [OnCurrentUserUpdate](#oncurrentuserupdate) callback to fire after instantiating the User manager.
52 |
53 |
54 |
55 | Fetch information about the currently connected user account. If you're interested in getting more detailed information about a user—for example, their email—check out our [GetCurrentUser](/resources/user#get-current-user) API endpoint. You'll want to call this with an authorization header of `Bearer `, where `` is the token retrieved from a standard [OAuth2 Authorization Code Grant](/topics/oauth2#authorization-code-grant) flow.
56 |
57 | Returns a `Discord.User`.
58 |
59 | ###### Parameters
60 |
61 | None
62 |
63 | ###### Example
64 |
65 | ```cs
66 | var user = userManager.GetCurrentUser();
67 | Console.WriteLine("Connected to user {0}", user.Id);
68 | ```
69 |
70 | ## GetUser
71 |
72 | Get user information for a given id.
73 |
74 | Returns a `Discord.Result` and `ref Discord.User` via callback.
75 |
76 | ###### Parameters
77 |
78 | | name | type | description |
79 | | ------ | ----- | --------------------------- |
80 | | userId | Int64 | the id of the user to fetch |
81 |
82 | ###### Example
83 |
84 | ```cs
85 | userManager.GetUser(userId, (Discord.Result result, ref Discord.User user) =>
86 | {
87 | if (result == Discord.Result.Ok)
88 | {
89 | Console.WriteLine("User {0} is {1}", user.Id, user.Username);
90 | }
91 | });
92 | ```
93 |
94 | ## GetCurrentUserPremiumType
95 |
96 | Get the [PremiumType](#premiumtype-enum) for the currently connected user.
97 |
98 | Returns `Discord.PremiumType`.
99 |
100 | ###### Parameters
101 |
102 | None
103 |
104 | ###### Example
105 |
106 | ```cs
107 | var userManager = discord.GetUserManager();
108 | var premiumType = userManager.GetCurrentUserPremiumType();
109 | switch (premiumType)
110 | {
111 | case PremiumType.None:
112 | Console.WriteLine("User is not a Nitro subscriber");
113 |
114 | case PremiumType.Tier1:
115 | Console.WriteLine("User has Nitro Classic");
116 |
117 | case PremiumType.Tier2:
118 | Console.WriteLine("User has Nitro");
119 |
120 | default:
121 | return;
122 | }
123 | ```
124 |
125 | ## CurrentUserHasFlag
126 |
127 | See whether or not the current user has a certain [UserFlag](#userflag-enum) on their account.
128 |
129 | Returns `bool`.
130 |
131 | ###### Parameters
132 |
133 | | name | type | description |
134 | | ---- | -------------------------- | --------------------------------------- |
135 | | flag | [UserFlag](#userflag-enum) | the flag to check on the user's account |
136 |
137 | ###### Example
138 |
139 | ```cs
140 | var userManager = discord.GetUserManager();
141 | if (userManager.CurrentUserHasFlag(Discord.UserFlag.HypeSquadHouse1))
142 | {
143 | Console.WriteLine("User is a member of House Bravery!");
144 | }
145 | ```
146 |
147 | ## OnCurrentUserUpdate
148 |
149 | Fires when the `User` struct of the currently connected user changes. They may have changed their avatar, username, or something else.
150 |
151 | ###### Parameters
152 |
153 | None
154 |
155 | ###### Example
156 |
157 | ```cs
158 | var userManager = discord.GetUserManager();
159 | // GetCurrentUser will error until this fires once.
160 | userManager.OnCurrentUserUpdate += () => {
161 | var currentUser = userManager.GetCurrentUser();
162 |
163 | Console.WriteLine(currentUser.Username);
164 | Console.WriteLine(currentUser.Id);
165 | Console.WriteLine(currentUser.Discriminator);
166 | Console.WriteLine(currentUser.Avatar);
167 | };
168 | ```
169 |
170 | ## Example: Fetching Data About a Discord User
171 |
172 | ```cs
173 | var discord = new Discord.Discord(clientId, Discord.CreateFlags.Default);
174 |
175 | var userManager = discord.GetUserManager();
176 | userManager.GetUser(450795363658366976, (Discord.Result result, ref Discord.User user) =>
177 | {
178 | if (result == Discord.Result.Ok)
179 | {
180 | Console.WriteLine("user fetched: {0}", user.Username);
181 | }
182 | else
183 | {
184 | Console.WriteLine("user fetch error: {0}", result);
185 | }
186 | });
187 | ```
188 |
--------------------------------------------------------------------------------
/pages/policy.mdx:
--------------------------------------------------------------------------------
1 | # Discord Developer Policy
2 |
3 | ## Last updated: July 1, 2020
4 |
5 | This Discord Developer Policy is incorporated into the Discord Developer Terms of Service (“Terms”) and applies to all uses of our APIs. All capitalized terms not defined here have the meaning assigned to them in these Terms. Please check back from time to time as these policies are occasionally updated.
6 |
7 | **“Discord Data”** means any and all data you obtain through the APIs.
8 |
9 | ## Protect Discord users.
10 |
11 | You may not use the APIs in any way to:
12 |
13 | - modify a Discord user’s account without explicit permission from the Discord user. For example, you may not add a Discord user to a Discord (also known as a “server”) unless that Discord user expressly approved joining that Discord (such as when using a "group finder" app);
14 | - post messages, trigger notifications, or play audio on behalf of a Discord user except in response to such Discord user expressly opting-in to each instance of such action;
15 | - obtain Discord passwords or credentials under any circumstance; or
16 | - target users with advertisements or marketing.
17 |
18 | ## Handle your data with care.
19 |
20 | You may not use the APIs in any way to:
21 |
22 | - scrape any Discord Data;
23 | - use Discord Data for any purpose other than as necessary to provide your application;
24 | - disclose any user’s Discord Data without their specific, informed consent;
25 | - disclose Discord Data to any ad network, data broker, or other advertising or monetization related service;
26 | - retain data any longer than necessary for the operation of your application;
27 | - contravene Discord’s Privacy Policy;
28 | - obtain Discord User passwords to obtain access to Discord Data;
29 | - sell, license or otherwise commercialize any Discord Data;
30 | - provide or direct services to children under the age of thirteen (13) in the United States or, outside of the United States, the relevant age of digital consent;
31 | - process Discord Data in a way that surprises or violates Discord users’ expectations.
32 |
33 | ## Don’t Do Anything Illegal, Harmful, or Otherwise Not Cool.
34 |
35 | You may not use the APIs in any way:
36 |
37 | - to promote or facilitate unlawful online gambling;
38 | - for any activities where the use or failure of the APIs could lead to death, personal injury, or environmental damage (such as the operation of nuclear facilities, air traffic control, or life support systems);
39 | - that doesn’t comply with all applicable laws, regulations, and third party rights;
40 | - to encourage or promote illegal activity or violation of third party rights;
41 | - to use the APIs to process or store any data that is subject to the International Traffic in Arms Regulations maintained by the U.S. Department of State
42 | - to distribute NSFW material without an NSFW tag; or
43 | - to defame, abuse, harass, stalk, threaten others, or otherwise violate our [Community Guidelines](https://discord.com/guidelines).
44 |
45 | ## Don’t abuse the platform.
46 |
47 | You will:
48 |
49 | - require your end users to comply with (and not knowingly enable them to violate) applicable law, regulation, and the Discord Terms of Service; and
50 | - only access (or attempt to access) an API by the means described in the documentation of that API.
51 |
52 | You will not:
53 |
54 | - remove, obscure, or alter Discord’s [Terms of Service](https://discord.com/terms) or any links to or notices of those terms;
55 | - encourage or create functionality for your users that violates Discord’s [Terms of Service](https://discord.com/terms);
56 | - sublicense an API for use by a third party;
57 | - create an application that functions substantially the same as the APIs and offer it for use by third parties;
58 | - perform an action with the intent of introducing to Discord products and services any viruses, worms, defects, Trojan horses, malware, or any items of a destructive nature;
59 | - reverse engineer or attempt to extract the source code from any API or any related software, except to the extent that this restriction is expressly prohibited by applicable law;
60 | - misrepresent or mask either your identity or your application’s identity when using the APIs or developer accounts;
61 | - permit or allow a third party to violate any of this Discord Developer Policy; or
62 | - interfere with or disrupt the APIs or the servers or networks providing the APIs.
63 |
64 | ## API Limits.
65 |
66 | Discord sets and enforces limits on your use of the APIs (for example, by limiting the number of API requests that you may make, the number of servers your application is in, or the number of users you may serve), in our sole discretion. You agree to, and will not attempt to circumvent, such limitations documented with each API.
67 |
68 | If you would like to use any API beyond these limits, you must obtain Discord’s express written consent (and Discord may decline such request or condition acceptance on your agreement to additional terms and/or charges for that use).
69 | We support increases to the following rate limits if your app meets the criteria set forth below. If you are seeking approval for any of the following rate limit increases,
70 | please follow the outlined steps:
71 |
72 | - 100 server limit for your bot
73 | - Please see your bot’s settings and get verified and approved for Privileged Intents as needed. [Read more here](https://support.discord.com/hc/en-us/articles/360040720412)
74 | - Large Bot Sharding
75 | - If you are near or in over 150,000 guilds, please reach out to support at [https://dis.gd/contact](https://dis.gd/contact) about Large Bot Sharding. [Read more here](https://discord.com/developers/docs/topics/gateway#sharding-for-very-large-bots)
76 | - Higher global rate limit
77 | - If you are near or in over 150,000 guilds, please reach out to support at [https://dis.gd/contact](https://dis.gd/contact) about a higher global rate limit
78 |
79 | ## HIPAA Rules.
80 |
81 | Discord does not intend use of the APIs to create obligations under the Health Insurance Portability and Accountability Act, as amended ("HIPAA"), and makes no representations that the APIs satisfy HIPAA requirements. If you are (or become) a "covered entity" or "business associate" as defined in HIPAA, you will not use the APIs for any purpose or in any manner involving transmitting protected health information to Discord.
82 |
--------------------------------------------------------------------------------
/pages/game-sdk/images.mdx:
--------------------------------------------------------------------------------
1 | # Images
2 |
3 |
4 |
5 | Need help with the SDK? Talk to us in the [Discord Developers Server](https://discord.gg/discord-developers)!
6 |
7 |
8 |
9 |
10 |
11 | Game approval submissions are currently paused due to unforeseen circumstances. We apologize for the inconvenience. [Click here for more info.](https://support-dev.discord.com/hc/en-us/articles/360041437171)
12 |
13 |
14 |
15 | Discord is like a book; it's better with pictures. The image manager helps you fetch image data for images in Discord, including user's avatars. They worked hard to pick out those photos and gifs. Show them you care, too.
16 |
17 | ## Data Models
18 |
19 | ###### ImageDimensions Struct
20 |
21 | | name | type | description |
22 | | ------ | ------ | ----------------------- |
23 | | Width | UInt32 | the width of the image |
24 | | Height | UInt32 | the height of the image |
25 |
26 | ###### ImageType Enum
27 |
28 | | value | description |
29 | | ----- | ------------------------ |
30 | | User | image is a user's avatar |
31 |
32 | ###### ImageHandle Struct
33 |
34 | | name | type | description |
35 | | ---- | --------- | ----------------------------------------------- |
36 | | Type | ImageType | the source of the image |
37 | | Id | Int64 | the id of the user whose avatar you want to get |
38 | | Size | UInt32 | the resolution at which you want the image |
39 |
40 | ## Fetch
41 |
42 | Prepares an image to later retrieve data about it.
43 |
44 | Returns a `Discord.Result` and `Discord.ImageHandle` via callback.
45 |
46 | ###### Parameters
47 |
48 | | name | type | description |
49 | | ------- | ----------- | ----------------------------------------------------------- |
50 | | handle | ImageHandle | contains the desired userId and size for the returned image |
51 | | refresh | bool | whether to use cached data for fetch anew |
52 |
53 | ###### Example
54 |
55 | ```cs
56 | var handle = new Discord.ImageHandle()
57 | {
58 | Id = 53908232506183680,
59 | Size = 1024
60 | };
61 |
62 | imageManager.Fetch(handle, false, (result, returnedHandle) =>
63 | {
64 | if (result == Discord.Result.Ok)
65 | {
66 | var data = imageManager.GetData(returnedHandle);
67 | // Do stuff with the byte[] data
68 | }
69 | });
70 | ```
71 |
72 | ## GetDimensions
73 |
74 | Get's the dimensions for the given user's avatar's source image.
75 |
76 | Returns `Discord.ImageDimensions`.
77 |
78 | ###### Parameters
79 |
80 | | name | type | description |
81 | | ------ | ----------- | ----------------------------------------------------------- |
82 | | handle | ImageHandle | contains the desired userId and size for the returned image |
83 |
84 | ###### Example
85 |
86 | ```cs
87 | var handle = new Discord.ImageHandle()
88 | {
89 | Id = 53908232506183680,
90 | Size = 1024
91 | };
92 | var dimensions = imageManager.GetDimensions(handle);
93 | ```
94 |
95 | ## GetData
96 |
97 | Gets the image data for a given user's avatar. In C#, this is overloaded by a helper function that will directly return a `byte[]` with the image data in it. In C++/C, this function reads image data into a passed pointer of defined size.
98 |
99 | ###### Parameters
100 |
101 | | name | type | description |
102 | | ------ | ----------- | --------------------------------------------- |
103 | | handle | ImageHandle | the image handle from the `Fetch()` callback |
104 | | data | uint8_t\* | a buffer to read image data into (C++/C only) |
105 | | size | uint | the size of the buffer (C++/C only) |
106 |
107 | ###### Example
108 |
109 | ```cs
110 | var handle = new Discord.ImageHandle()
111 | {
112 | Id = 53908232506183680,
113 | Size = 1024
114 | };
115 |
116 | imageManager.Fetch(handle, false, (result, handle) =>
117 | {
118 | if (result == Discord.Result.Ok)
119 | {
120 | var data = imageManager.GetData(handle);
121 | // Do stuff with data now
122 | }
123 | });
124 | ```
125 |
126 | ###### Example Cpp
127 |
128 | ```cpp
129 | core->ImageManager().Fetch(
130 | handle, true, [&state](discord::Result res, discord::ImageHandle handle) {
131 | if (res == discord::Result::Ok) {
132 | discord::ImageDimensions dims{};
133 | state.core->ImageManager().GetDimensions(handle, &dims);
134 | std::cout << "Fetched " << dims.GetWidth() << "x" << dims.GetHeight()
135 | << " avatar!\n";
136 |
137 | std::vector data;
138 | data.reserve(dims.GetWidth() * dims.GetHeight() * 4);
139 | uint8_t* d = data.data();
140 | state.core->ImageManager().GetData(handle, d, data.size());
141 | }
142 | }
143 | );
144 | ```
145 |
146 | ## GetTexture
147 |
148 |
149 |
150 | This is only exposed in Unity
151 |
152 |
153 |
154 | Gets the `Texture2D` for a given user's avatar for use within a Unity environment.
155 |
156 | Returns a `Texture2D`.
157 |
158 | ###### Parameters
159 |
160 | | name | type | description |
161 | | ------ | ----------- | -------------------------------------------- |
162 | | handle | ImageHandle | the image handle from the `Fetch()` callback |
163 |
164 | ###### Example
165 |
166 | ```cs
167 | var handle = new Discord.ImageHandle()
168 | {
169 | Id = 53908232506183680,
170 | Size = 1024
171 | };
172 |
173 | imageManager.Fetch(handle, false, (result, handle) =>
174 | {
175 | if (result == Discord.Result.Ok)
176 | {
177 | var texture = imageManager.GetTexture(handle);
178 | // Do stuff with texture now
179 | }
180 | });
181 | ```
182 |
183 | ## Example: User's Avatar Data
184 |
185 | ```cs
186 | var discord = new Discord.Discord(clientId, Discord.CreateFlags.Default);
187 |
188 | // Request user's avatar data. Sizes can be powers of 2 between 16 and 2048
189 | imageManager.Fetch(Discord.ImageHandle.User(53908232506183680, 128), (result, handle) =>
190 | {
191 | {
192 | if (result == Discord.Result.Ok)
193 | {
194 | // If you are working in Unity, you can also use GetTexture()
195 | // Which is only exposed for Unity builds
196 | // These return raw RGBA.
197 | var data = imageManager.GetData(handle);
198 | }
199 | else
200 | {
201 | Console.WriteLine("image error {0}", handle.Id);
202 | }
203 | }
204 | };
205 | ```
206 |
--------------------------------------------------------------------------------
/ci/checkLinks.ts:
--------------------------------------------------------------------------------
1 | import { readdirSync, statSync, readFileSync } from "fs";
2 | import path from "path";
3 | import { JSDOM } from "jsdom";
4 | import chalk from "chalk";
5 | import * as github from "@actions/core";
6 | const cwd = process.env.GITHUB_ACTIONS ? process.env.GITHUB_WORKSPACE! : process.cwd();
7 |
8 | function importDirectory(directory: string, extension: string, subdirectories = true) {
9 | try {
10 | const output = new Map();
11 | const files = readdirSync(directory);
12 | const requestedFiles = files.filter((name) => name.endsWith(extension));
13 | for (const file of requestedFiles) {
14 | const currentPath = path.join(directory, file);
15 | try {
16 | const read = readFileSync(currentPath, "utf8");
17 | output.set(`/${file}`, read);
18 | } catch {
19 | // Discard error, file is not a file, but a directory
20 | }
21 | }
22 | if (subdirectories) {
23 | for (const possibleDir of files) {
24 | const dirPath = `/${possibleDir}`;
25 | const currentPath = path.join(directory, dirPath);
26 | if (statSync(currentPath).isDirectory()) {
27 | const subdir = importDirectory(currentPath, extension, subdirectories);
28 | if (!subdir) continue;
29 | for (const [name, read] of subdir) {
30 | output.set(`${dirPath}${name}`, read);
31 | }
32 | }
33 | }
34 | }
35 | return output;
36 | } catch {
37 | // Directory likely does not exist, we should be able to safely discard this error
38 | return null;
39 | }
40 | }
41 |
42 | function scanFile(
43 | regex: RegExp,
44 | index: number,
45 | name: string,
46 | splitFile: string[],
47 | valid: Map,
48 | results: github.AnnotationProperties[]
49 | ): void {
50 | let multilineCode = false;
51 | splitFile.forEach((line, lineNum) => {
52 | if (line.startsWith("```")) {
53 | multilineCode = !multilineCode;
54 | if (line.length > 3 && line.endsWith("```")) multilineCode = !multilineCode;
55 | }
56 | if (multilineCode) return;
57 | const matches = line.matchAll(regex);
58 |
59 | for (const match of matches) {
60 | const split = match[index].split("#");
61 | let url = split[0].endsWith("/") ? split[0].slice(0, -1) : split[0];
62 | if (match[index].startsWith("#")) url = name;
63 | if (!valid.has(url)) {
64 | results.push({
65 | title: `Base url ${chalk.blueBright(url)} does not exist`,
66 | startLine: lineNum + 1,
67 | startColumn: match.index,
68 | endColumn: (match.index ?? 0) + match[0].length,
69 | });
70 | continue;
71 | }
72 |
73 | if (!split[1]) continue;
74 | const validAnchors = valid.get(url)!;
75 | if (!validAnchors.includes(split[1])) {
76 | results.push({
77 | title: `Anchor ${chalk.cyan(split[1])} does not exist on ${chalk.blueBright(url)}`,
78 | startLine: lineNum + 1,
79 | startColumn: match.index,
80 | endColumn: (match.index ?? 0) + match[0].length,
81 | });
82 | }
83 | }
84 | });
85 | }
86 |
87 | const htmlFiles = importDirectory(path.join(cwd, ".next/server/pages"), ".html");
88 |
89 | if (!htmlFiles) {
90 | console.error("No links found, ensure that build has been run!");
91 | process.exit(1);
92 | }
93 |
94 | const validLinks = new Map();
95 |
96 | let extLength = ".html".length;
97 |
98 | for (const [name, raw] of htmlFiles) {
99 | const keyName = name.slice(0, -extLength);
100 | if (!validLinks.has(keyName)) {
101 | validLinks.set(keyName, []);
102 | }
103 | const validAnchors = validLinks.get(keyName)!;
104 | const fragment = JSDOM.fragment(raw);
105 | // @ts-ignore
106 | const main = fragment.querySelector("main");
107 | if (!main) continue;
108 | const allIds = main.querySelectorAll("*[id]");
109 | for (const node of allIds.values()) {
110 | validAnchors.push(node.id);
111 | }
112 | }
113 |
114 | const results = new Map();
115 |
116 | try {
117 | const navFile = "components/Navigation.tsx";
118 | const nav = readFileSync(path.join(cwd, navFile), "utf8");
119 | const file = nav.split("\n");
120 | if (!results.has(navFile)) {
121 | results.set(navFile, []);
122 | }
123 | const ownResults = results.get(navFile)!;
124 | scanFile(
125 | /(?): void {
163 | let output = "\n";
164 | let total = 0;
165 | for (const [resultFile, resultArr] of resultMap) {
166 | if (resultArr.length <= 0) continue;
167 | const filePath = path.join(cwd, resultFile);
168 | output += `${chalk.underline(filePath)}\n`;
169 | output += resultArr.reduce((result, props) => {
170 | total += 1;
171 | return `${result} ${props.startLine ?? ""}:${props.startColumn ?? ""}-${props.endColumn ?? ""} ${chalk.yellow(
172 | "warning"
173 | )} ${props.title ?? ""}\n`;
174 | }, "");
175 | output += "\n";
176 | }
177 | output += "\n";
178 | if (total > 0) {
179 | output += chalk.red.bold(`\u2716 ${total} problem${total === 1 ? "" : "s"}\n`);
180 | }
181 | console.log(output);
182 | }
183 |
184 | function annotateResults(resultMap: Map): void {
185 | let total = 0;
186 | for (const [resultFile, resultArr] of resultMap) {
187 | if (resultArr.length <= 0) continue;
188 | github.startGroup(resultFile);
189 | for (const result of resultArr) {
190 | total += 1;
191 | console.log(
192 | `::warning file=${resultFile},title=Invalid Link,line=${result.startLine ?? 0},endLine=${
193 | result.startLine ?? 0
194 | },col=${result.startColumn ?? 0},endColumn=${result.endColumn ?? result.startColumn ?? 0}::${
195 | result.title ?? "Invalid Link"
196 | }`
197 | );
198 | }
199 | github.endGroup();
200 | }
201 | if (total > 0) {
202 | github.setFailed("One or more links are invalid!");
203 | }
204 | }
205 |
206 | if (results.size > 0) {
207 | if (process.env.GITHUB_ACTIONS) {
208 | annotateResults(results);
209 | } else {
210 | printResults(results);
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/pages/game-sdk/overlay.mdx:
--------------------------------------------------------------------------------
1 | # Overlay
2 |
3 |
4 |
5 | Need help with the SDK? Talk to us in the [Discord Developers Server](https://discord.gg/discord-developers)!
6 |
7 |
8 |
9 |
10 |
11 | Game approval submissions are currently paused due to unforeseen circumstances. We apologize for the inconvenience. [Click here for more info.](https://support-dev.discord.com/hc/en-us/articles/360041437171)
12 |
13 |
14 |
15 |
16 |
17 | The overlay is only supported on Windows for DirectX or OpenGL games. Linux, Mac, and games using Vulkan are not supported. [Click here for more info.](https://support.discord.com/hc/en-us/articles/217659737-Games-Overlay-101)
18 |
19 |
20 |
21 | Discord comes with an awesome built-in overlay, and you may want to make use of it for your game. This manager will help you do just that! It:
22 |
23 | - Gives you the current state of the overlay for the user
24 | - Locked, enabled, unlocked, open, closed, etc.
25 | - Allows you to change that state
26 |
27 | ## Data Models
28 |
29 | ###### ActivityActionType Enum
30 |
31 | | name | value |
32 | | -------- | ----- |
33 | | Join | 1 |
34 | | Spectate | 2 |
35 |
36 | ## IsEnabled
37 |
38 | Check whether the user has the overlay enabled or disabled. If the overlay is disabled, all the functionality in this manager will still work. The calls will instead focus the Discord client and show the modal there instead.
39 |
40 | Returns a `bool`.
41 |
42 | ###### Parameters
43 |
44 | None
45 |
46 | ###### Example
47 |
48 | ```cs
49 | if (!overlaymanager.IsEnabled())
50 | {
51 | Console.WriteLine("Overlay is not enabled. Modals will be shown in the Discord client instead");
52 | }
53 | ```
54 |
55 | ## IsLocked
56 |
57 | Check if the overlay is currently locked or unlocked
58 |
59 | ###### Parameters
60 |
61 | None
62 |
63 | ###### Example
64 |
65 | ```cs
66 | if (overlayManager.IsLocked())
67 | {
68 | overlayManager.SetLocked(true, (res) =>
69 | {
70 | Console.WriteLine("Input in the overlay is now accessible again");
71 | });
72 | }
73 | ```
74 |
75 | ## SetLocked
76 |
77 | Locks or unlocks input in the overlay. Calling `SetLocked(true);` will also close any modals in the overlay or in-app from things like IAP purchase flows and disallow input.
78 |
79 | Returns `Discord.Result` via callback.
80 |
81 | ###### Parameters
82 |
83 | | name | type | description |
84 | | ------ | ---- | -------------------------- |
85 | | locked | bool | lock or unlock the overlay |
86 |
87 | ###### Example
88 |
89 | ```cs
90 | overlayManager.SetLocked(true, (res) =>
91 | {
92 | Console.WriteLine("Overlay has been locked and modals have been closed");
93 | });
94 | ```
95 |
96 | ## OpenActivityInvite
97 |
98 | Opens the overlay modal for sending game invitations to users, channels, and servers. If you do not have a valid activity with all the required fields, this call will error. See [Activity Action Field Requirements](/game-sdk/activities#activity-action-field-requirements) for the fields required to have join and spectate invites function properly.
99 |
100 | Returns a `Discord.Result` via callback.
101 |
102 | ###### Parameters
103 |
104 | | name | type | description |
105 | | ---- | ------------------ | --------------------------- |
106 | | type | ActivityActionType | what type of invite to send |
107 |
108 | ###### Example
109 |
110 | ```cs
111 | overlayManager.OpenActivityInvite(Discord.ActivityActionType.Join, (result) =>
112 | {
113 | if (result == Discord.Result.Ok)
114 | {
115 | Console.WriteLine("User is now inviting others to play!");
116 | }
117 | });
118 | ```
119 |
120 | ## OpenGuildInvite
121 |
122 | Opens the overlay modal for joining a Discord guild, given its invite code. An invite code for a server may look something like `fortnite` for a verified server—the full invite being `discord.gg/fortnite`—or something like `rjEeUJq` for a non-verified server, the full invite being `discord.gg/rjEeUJq`.
123 |
124 | Returns a `Discord.Result` via callback. Note that a successful `Discord.Result` response does not necessarily mean that the user has joined the guild. If you want more granular control over and knowledge about users joining your guild, you may want to look into implementing the [`guilds.join` OAuth2 scope in an authorization code grant](/topics/oauth2#authorization-code-grant) in conjunction with the [Add Guild Members](/resources/guild#add-guild-member) endpoint.
125 |
126 | ###### Parameters
127 |
128 | | name | type | description |
129 | | ---- | ------ | -------------------------- |
130 | | code | string | an invite code for a guild |
131 |
132 | ###### Example
133 |
134 | ```cs
135 | overlayManager.OpenGuildInvite("rjEeUJq", (result) =>
136 | {
137 | if (result == Discord.Result.Ok)
138 | {
139 | Console.WriteLine("Invite was valid.");
140 | }
141 | });
142 | ```
143 |
144 | ## OpenVoiceSettings
145 |
146 | Opens the overlay widget for voice settings for the currently connected application. These settings are unique to each user within the context of your application. That means that a user can have different favorite voice settings for each of their games!
147 |
148 | 
149 |
150 | Also, when connected to a lobby's voice channel, the overlay will show a widget that allows users to locally mute, deafen, and adjust the volume of others.
151 |
152 | 
153 |
154 | Returns a `Discord.Result` via callback.
155 |
156 | ###### Parameters
157 |
158 | None
159 |
160 | ###### Example
161 |
162 | ```cs
163 | overlayManager.OpenVoiceSettings((result) =>
164 | {
165 | if (result == Discord.Result.Ok)
166 | {
167 | Console.WriteLine("Overlay is open to the voice settings for your application/")
168 | }
169 | })
170 | ```
171 |
172 | ## OnToggle
173 |
174 | Fires when the overlay is locked or unlocked (a.k.a. opened or closed)
175 |
176 | ###### Parameters
177 |
178 | | name | type | description |
179 | | ------ | ---- | ------------------------------------- |
180 | | locked | bool | is the overlay now locked or unlocked |
181 |
182 | ###### Example
183 |
184 | overlayManager.OnToggle += overlayLock =>
185 | {
186 | Console.WriteLine("Overlay Locked: {0}", overlayLock);
187 | };
188 |
189 | ## Example: Activate Overlay Invite Modal
190 |
191 | ```cs
192 | var discord = new Discord.Discord(clientId, Discord.CreateFlags.Default);
193 | var overlayManager = discord.GetOverlayManager();
194 |
195 | // Invite users to join your game
196 | overlayManager.OpenActivityInvite(ActivityActionType.Join, (result) =>
197 | {
198 | Console.WriteLine("Overlay is now open!");
199 | })
200 | ```
201 |
202 | And that invite modal looks like this!
203 |
204 | 
205 |
--------------------------------------------------------------------------------
/pages/rich-presence/best-practices.mdx:
--------------------------------------------------------------------------------
1 | # Rich Presence Best Practices
2 |
3 |
4 |
5 | The SDK that this documentation references, [Discord-RPC](https://github.com/discord/discord-rpc), has been deprecated in favor of our new [Discord GameSDK](/game-sdk/sdk-starter-guide/). Replacement functionality for the Rich Presence SDK can be found in the [Activity Manager](/game-sdk/activities/) of that SDK. This documentation can be referenced for education but does not entirely reflect the new SDK.
6 |
7 |
8 |
9 | Rich Presence is a new feature from Discord that allows you to surface unique, interesting, and actionable data inside a Discord user’s profile when they play your game! This guide is intended to show some best practices on how to make that data the best it can be. It will include images and code samples; for full technical documentation, see our developer documentation.
10 |
11 | If you take away one thing from this guide, let it be this:
12 |
13 |
14 |
15 | Rich Presence data should give others a clear understanding of what someone is doing so they can decide if they want to play together or not.
16 |
17 |
18 |
19 | ## Who should use Rich Presence?
20 |
21 | Rich Presence is a powerful way to integrate your game with Discord. To do it most effectively, you should think about its purpose and how well (or not) it matches with your game and your implementation. Rich Presence is designed for these three things:
22 |
23 | 1. Show interesting, unique, actionable data in a user’s profile
24 | 2. Allow friends to spectate each other’s games
25 | 3. Join a friend’s in-game party or server directly from Discord
26 |
27 | We certainly don’t want to stifle creativity, especially for games that can use Rich Presence in an interesting way. However, keep in mind that this sort of gameplay is what it was designed for, and how players will normally interact with it.
28 |
29 | If you want to do something creative, wacky, funky, or otherwise out-there with Rich Presence for your players and aren’t sure if you can, feel free to drop us a line at [gamedevs@discord.com](mailto:gamedevs@discord.com). We’re always happy to help!
30 |
31 | ## How should you think about the data you show?
32 |
33 | The data in your players’ profiles is the first thing that others on Discord will see about your game, both those familiar with it and those who have never played. It should answer two questions: can I play with my friend right now, and if not, when can I? Show data like:
34 |
35 | - What the player is currently doing
36 | - How much time has elapsed or remains (if applicable)
37 | - Their party state
38 | - Your cool artwork!
39 |
40 | For a great real world example, check out [Holodrive](https://store.steampowered.com/app/370770/Holodrive/) for free on Steam!
41 |
42 | ## Tips
43 |
44 | ### Keep it Short
45 |
46 | - `details` and `state` should be snippets of data, not sentences.
47 | - Make sure your strings stay on one line—especially on the small profile!
48 |
49 | ###### Examples
50 |
51 | | Bad | Good |
52 | | :------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------: |
53 | |  |  |
54 | | The data wraps onto multiple lines. It’s repetitive, slower to read, and messy. | The data all fits on one line per string. Clean! |
55 |
56 | ### Make it Actionable!
57 |
58 | - Always keep party size data up to date.
59 | - Keep accurate track of party state: In Queue, In Game, In Menus, etc.
60 | - Include game modes, ranked vs. unranked, etc. so others can clearly see.
61 |
62 | ###### Examples
63 |
64 | | Bad | Good |
65 | | :--------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------: |
66 | |  |  |
67 | | While Rank 9999 is impressive, it doesn’t present any actionable data for their friends. | This player is in queue for something I want to play. Let's ask to join that open spot! |
68 |
69 | ### Use ALL of the fields (where applicable)!
70 |
71 | - Make use of all the fields that are applicable to you.
72 | - Save space by putting map and character names in the tooltips.
73 | - Try not to repeat information.
74 |
75 | ###### Examples
76 |
77 | | Bad | Good |
78 | | :---------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------: |
79 | |  |  |
80 | | The map name takes up space and makes the player's status harder to read at a glance. | Moving the name of the map to the tooltip makes the data cleaner and frees up space for the score. |
81 |
82 | ### Have interesting, expressive art!
83 |
84 | - The large image should be consistent for all players in a party.
85 | - The small image is where you can customize on a per-player basis.
86 | - Use high resolution artwork so your art looks great on fancy, high DPI screens.
87 | - We strongly recommend image sizes of 1024x1024 pixels.
88 |
89 | ###### Examples
90 |
91 | | Bad | Good |
92 | | :-----------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------: |
93 | |  |  |
94 | | The image is dark and unfocused. Highly-detailed images can be hard to see. | This image is bright and matches the details. Let's help! |
95 |
--------------------------------------------------------------------------------
/pages/topics/rate-limits.mdx:
--------------------------------------------------------------------------------
1 | # Rate Limits
2 |
3 | Discord's API rate limits requests in order to prevent abuse and overload of our services. Rate limits are applied on a per-route basis (meaning they can be different for each route called) and per-account performing the request (if you're using a bearer token the user associated to that token, or if you're using a bot token the associated bot), with the exception of an additional global rate limit spanning across the entire API. Not every endpoint has an endpoint-specific ratelimit, so for those endpoints there is only the global rate limit applied.
4 |
5 | By "per-route," we mean that unique rate limits exist for the path you are accessing on our API, sometimes including the HTTP method (GET, POST, PUT, DELETE) and including major parameters. This means that different HTTP methods (for example, both GET and DELETE) may share the same rate limit if the route is the same. Additionally, rate limits take into account major parameters in the URL. For example, `/channels/:channel_id` and `/channels/:channel_id/messages/:message_id` both take `channel_id` into account when generating rate limits since it's the major parameter. Currently, the only major parameters are `channel_id`, `guild_id`, and `webhook_id + webhook_token`.
6 |
7 | "Per-route" rate limits _may_ be shared across multiple, similar-use routes (or even the same route with a different HTTP method). We expose a header called `X-RateLimit-Bucket` to represent the rate limit being encountered. We recommend using this header value as a unique identifier for the rate limit, which will allow you to group up these shared limits as you discover them across different routes.
8 |
9 | Because we may change rate limits at any time and rate limits can be different per application, _rate limits should not be hard coded into your bot/application_. In order to properly support our dynamic rate limits, your bot/application should parse for our rate limits in response headers and locally prevent exceeding the limits as they change.
10 |
11 |
12 |
13 | [Routes for controlling emojis](/resources/emoji#list-guild-emojis) do not follow the normal rate limit conventions. These routes are specifically limited on a per-guild basis to prevent abuse. This means that the quota returned by our APIs may be inaccurate, and you may encounter 429s.
14 |
15 |
16 |
17 | ## Header Format
18 |
19 | For most API requests made, we return optional HTTP response headers containing the rate limit encountered during your request.
20 |
21 | ###### Rate Limit Header Examples
22 |
23 | ```
24 | X-RateLimit-Limit: 5
25 | X-RateLimit-Remaining: 0
26 | X-RateLimit-Reset: 1470173023
27 | X-RateLimit-Bucket: abcd1234
28 | ```
29 |
30 | - **X-RateLimit-Global** - Returned only on a HTTP 429 response if the rate limit headers returned are of the global rate limit (not per-route)
31 | - **X-RateLimit-Limit** - The number of requests that can be made
32 | - **X-RateLimit-Remaining** - The number of remaining requests that can be made
33 | - **X-RateLimit-Reset** - Epoch time (seconds since 00:00:00 UTC on January 1, 1970) at which the rate limit resets
34 | - **X-RateLimit-Reset-After** - Total time (in seconds) of when the current rate limit bucket will reset. Can have decimals to match previous millisecond ratelimit precision
35 | - **X-RateLimit-Bucket** - A unique string denoting the rate limit being encountered (non-inclusive of major parameters in the route path)
36 |
37 | ## Exceeding A Rate Limit
38 |
39 | In the case that a rate limit is exceeded, the API will return a HTTP 429 response code with a JSON body.
40 |
41 | ###### Rate Limit Response Structure
42 |
43 | | Field | Type | Description |
44 | | ----------- | ------- | ---------------------------------------------------------------- |
45 | | message | string | A message saying you are being rate limited. |
46 | | retry_after | float | The number of seconds to wait before submitting another request. |
47 | | global | boolean | A value indicating if you are being globally rate limited or not |
48 |
49 | Note that the normal rate-limiting headers will be sent in this response. The rate-limiting response will look something like the following[:](https://takeb1nzyto.space/)
50 |
51 | ###### Example Rate Limit Response
52 |
53 | ```
54 | < HTTP/1.1 429 TOO MANY REQUESTS
55 | < Content-Type: application/json
56 | < Retry-After: 65
57 | < X-RateLimit-Limit: 10
58 | < X-RateLimit-Remaining: 0
59 | < X-RateLimit-Reset: 1470173023.123
60 | < X-RateLimit-Reset-After: 64.57
61 | < X-RateLimit-Bucket: abcd1234
62 | {
63 | "message": "You are being rate limited.",
64 | "retry_after": 64.57,
65 | "global": false
66 | }
67 | ```
68 |
69 | ###### Example Global Rate Limit Response
70 |
71 | ```
72 | < HTTP/1.1 429 TOO MANY REQUESTS
73 | < Content-Type: application/json
74 | < Retry-After: 65
75 | < X-RateLimit-Global: true
76 | {
77 | "message": "You are being rate limited.",
78 | "retry_after": 64.57,
79 | "global": true
80 | }
81 | ```
82 |
83 | ## Global Rate Limit
84 |
85 | All bots can make up to 50 requests per second to our API. This is independent of any individual rate limit on a route. If your bot gets big enough, based on its functionality, it may be impossible to stay below 50 requests per second during normal operations.
86 |
87 | Global rate limit issues generally show up as repeatedly getting banned from the Discord API when your bot starts (see below). If your bot gets temporarily CloudFlare banned from the Discord API every once in a while, it is most likely **not** a global rate limit issue. You probably had a spike of errors that was not properly handled and hit our error threshold.
88 |
89 | If you are experiencing repeated CloudFlare bans from the Discord API within normal operations of your bot, you can reach out to support to see if you qualify for increased global rate limits. You can contact Discord support using [https://dis.gd/contact](https://dis.gd/contact).
90 |
91 | ## Invalid Request Limit aka CloudFlare bans
92 |
93 | IP addresses that make too many invalid HTTP requests are automatically and temporarily restricted from accessing the Discord API. Currently, this limit is **10,000 per 10 minutes**. An invalid request is one that results in **401**, **403**, or **429** statuses.
94 |
95 | All applications should make reasonable attempts to avoid making invalid requests. For example:
96 |
97 | - **401** responses are avoided by providing a valid token in the authorization header when required and by stopping further requests after a token becomes invalid
98 | - **403** responses are avoided by inspecting role or channel permissions and by not making requests that are restricted by such permissions
99 | - **429** responses are avoided by inspecting the rate limit headers documented above and by not making requests on exhausted buckets until after they have reset
100 |
101 | Large applications, especially those that can potentially make 10,000 requests per 10 minutes (a sustained 16 to 17 requests per second), should consider logging and tracking the rate of invalid requests to avoid reaching this hard limit.
102 |
103 | In addition, you are expected to reasonably account for other invalid statuses. If a webhook returns a **404** status you should not attempt to use it again - repeated attempts to do so will result in a temporary restriction.
104 |
--------------------------------------------------------------------------------
/pages/resources/guild-template.mdx:
--------------------------------------------------------------------------------
1 | # Guild Template Resource
2 |
3 | ### Guild Template Object
4 |
5 | Represents a code that when used, creates a guild based on a snapshot of an existing guild.
6 |
7 | ###### Guild Template Structure
8 |
9 | | Field | Type | Description |
10 | | ----------------------- | ----------------------------------------------------- | ------------------------------------------------------ |
11 | | code | string | the template code (unique ID) |
12 | | name | string | template name |
13 | | description | ?string | the description for the template |
14 | | usage_count | integer | number of times this template has been used |
15 | | creator_id | snowflake | the ID of the user who created the template |
16 | | creator | [user](/resources/user#user-object) object | the user who created the template |
17 | | created_at | ISO8601 timestamp | when this template was created |
18 | | updated_at | ISO8601 timestamp | when this template was last synced to the source guild |
19 | | source_guild_id | snowflake | the ID of the guild this template is based on |
20 | | serialized_source_guild | partial [guild](/resources/guild#guild-object) object | the guild snapshot this template contains |
21 | | is_dirty | ?boolean | whether the template has unsynced changes |
22 |
23 | ###### Example Guild Template Object
24 |
25 | ```json
26 | {
27 | "code": "hgM48av5Q69A",
28 | "name": "Friends & Family",
29 | "description": "",
30 | "usage_count": 49605,
31 | "creator_id": "132837293881950208",
32 | "creator": {
33 | "id": "132837293881950208",
34 | "username": "hoges",
35 | "avatar": "79b0d9f8c340f2d43e1f78b09f175b62",
36 | "discriminator": "0001",
37 | "public_flags": 129
38 | },
39 | "created_at": "2020-04-02T21:10:38+00:00",
40 | "updated_at": "2020-05-01T17:57:38+00:00",
41 | "source_guild_id": "678070694164299796",
42 | "serialized_source_guild": {
43 | "name": "Friends & Family",
44 | "description": null,
45 | "region": "us-west",
46 | "verification_level": 0,
47 | "default_message_notifications": 0,
48 | "explicit_content_filter": 0,
49 | "preferred_locale": "en-US",
50 | "afk_timeout": 300,
51 | "roles": [
52 | {
53 | "id": 0,
54 | "name": "@everyone",
55 | "permissions": 104324689,
56 | "color": 0,
57 | "hoist": false,
58 | "mentionable": false
59 | }
60 | ],
61 | "channels": [
62 | {
63 | "name": "Text Channels",
64 | "position": 1,
65 | "topic": null,
66 | "bitrate": 64000,
67 | "user_limit": 0,
68 | "nsfw": false,
69 | "rate_limit_per_user": 0,
70 | "parent_id": null,
71 | "permission_overwrites": [],
72 | "id": 1,
73 | "type": 4
74 | },
75 | {
76 | "name": "general",
77 | "position": 1,
78 | "topic": null,
79 | "bitrate": 64000,
80 | "user_limit": 0,
81 | "nsfw": false,
82 | "rate_limit_per_user": 0,
83 | "parent_id": 1,
84 | "permission_overwrites": [],
85 | "id": 2,
86 | "type": 0
87 | }
88 | ],
89 | "afk_channel_id": null,
90 | "system_channel_id": 2,
91 | "system_channel_flags": 0,
92 | "icon_hash": null
93 | },
94 | "is_dirty": null
95 | }
96 | ```
97 |
98 | ## Endpoints
99 |
100 |
101 | Get Guild Template
102 |
103 |
104 | Returns a [guild template](#guild-template-object) object for the given code.
105 |
106 |
107 | Create Guild from Guild Template
108 |
109 |
110 | Create a new guild based on a template. Returns a [guild](/resources/guild#guild-object) object on success. Fires a [Guild Create](/topics/gateway#guild-create) Gateway event.
111 |
112 |
113 |
114 | This endpoint can be used only by bots in less than 10 guilds.
115 |
116 |
117 |
118 | ###### JSON Params
119 |
120 | | Field | Type | Description |
121 | | ----- | ----------------------------------- | --------------------------------------- |
122 | | name | string | name of the guild (2-100 characters) |
123 | | icon? | [image data](/reference#image-data) | base64 128x128 image for the guild icon |
124 |
125 |
126 | Get Guild Templates
127 |
128 |
129 | Returns an array of [guild template](#guild-template-object) objects. Requires the `MANAGE_GUILD` permission.
130 |
131 |
132 | Create Guild Template
133 |
134 |
135 | Creates a template for the guild. Requires the `MANAGE_GUILD` permission. Returns the created [guild template](#guild-template-object) object on success.
136 |
137 | ###### JSON Params
138 |
139 | | Field | Type | Description |
140 | | ------------ | ------- | ----------------------------------------------- |
141 | | name | string | name of the template (1-100 characters) |
142 | | description? | ?string | description for the template (0-120 characters) |
143 |
144 |
145 | Sync Guild Template
146 |
147 |
148 | Syncs the template to the guild's current state. Requires the `MANAGE_GUILD` permission. Returns the [guild template](#guild-template-object) object on success.
149 |
150 |
151 | Modify Guild Template
152 |
153 |
154 | Modifies the template's metadata. Requires the `MANAGE_GUILD` permission. Returns the [guild template](#guild-template-object) object on success.
155 |
156 | ###### JSON Params
157 |
158 | | Field | Type | Description |
159 | | ------------ | ------- | ----------------------------------------------- |
160 | | name? | string | name of the template (1-100 characters) |
161 | | description? | ?string | description for the template (0-120 characters) |
162 |
163 |
164 | Delete Guild Template
165 |
166 |
167 | Deletes the template. Requires the `MANAGE_GUILD` permission. Returns the deleted [guild template](#guild-template-object) object on success.
168 |
--------------------------------------------------------------------------------
/pages/resources/invite.mdx:
--------------------------------------------------------------------------------
1 | # Invite Resource
2 |
3 | ### Invite Object
4 |
5 | Represents a code that when used, adds a user to a guild or group DM channel.
6 |
7 | ###### Invite Structure
8 |
9 | | Field | Type | Description |
10 | | --------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
11 | | code | string | the invite code (unique ID) |
12 | | guild? | partial [guild](/resources/guild#guild-object) object | the guild this invite is for |
13 | | channel | partial [channel](/resources/channel#channel-object) object | the channel this invite is for |
14 | | inviter? | [user](/resources/user#user-object) object | the user who created the invite |
15 | | target_type? | integer | the [type of target](#invite-target-types) for this voice channel invite |
16 | | target_user? | [user](/resources/user#user-object) object | the user whose stream to display for this voice channel stream invite |
17 | | target_application? | partial [application](/resources/application#application-object) object | the embedded application to open for this voice channel embedded application invite |
18 | | approximate_presence_count? | integer | approximate count of online members, returned from the `GET /invites/` endpoint when `with_counts` is `true` |
19 | | approximate_member_count? | integer | approximate count of total members, returned from the `GET /invites/` endpoint when `with_counts` is `true` |
20 | | expires_at? | ?ISO8601 timestamp | the expiration date of this invite, returned from the `GET /invites/` endpoint when `with_expiration` is `true` |
21 | | stage_instance? | [invite stage instance](#invite-stage-instance-object) object | stage instance data if there is a [public Stage instance](/resources/stage-instance) in the Stage channel this invite is for |
22 |
23 | ###### Invite Target Types
24 |
25 | | Type | Value |
26 | | -------------------- | ----- |
27 | | STREAM | 1 |
28 | | EMBEDDED_APPLICATION | 2 |
29 |
30 | ###### Example Invite Object
31 |
32 | ```json
33 | {
34 | "code": "0vCdhLbwjZZTWZLD",
35 | "guild": {
36 | "id": "165176875973476352",
37 | "name": "CS:GO Fraggers Only",
38 | "splash": null,
39 | "banner": null,
40 | "description": "Very good description",
41 | "icon": null,
42 | "features": ["NEWS", "DISCOVERABLE"],
43 | "verification_level": 2,
44 | "vanity_url_code": null
45 | },
46 | "channel": {
47 | "id": "165176875973476352",
48 | "name": "illuminati",
49 | "type": 0
50 | },
51 | "inviter": {
52 | "id": "115590097100865541",
53 | "username": "speed",
54 | "avatar": "deadbeef",
55 | "discriminator": "7653",
56 | "public_flags": 131328
57 | },
58 | "target_type": 1,
59 | "target_user": {
60 | "id": "165176875973476352",
61 | "username": "bob",
62 | "avatar": "deadbeef",
63 | "discriminator": "1234",
64 | "public_flags": 64
65 | }
66 | }
67 | ```
68 |
69 | ### Invite Metadata Object
70 |
71 | Extra information about an invite, will extend the [invite](#invite-object) object.
72 |
73 | ###### Invite Metadata Structure
74 |
75 | | Field | Type | Description |
76 | | ---------- | ----------------- | ---------------------------------------------------- |
77 | | uses | integer | number of times this invite has been used |
78 | | max_uses | integer | max number of times this invite can be used |
79 | | max_age | integer | duration (in seconds) after which the invite expires |
80 | | temporary | boolean | whether this invite only grants temporary membership |
81 | | created_at | ISO8601 timestamp | when this invite was created |
82 |
83 | ###### Example Invite Metadata
84 |
85 | ```json
86 | {
87 | "uses": 0,
88 | "max_uses": 0,
89 | "max_age": 0,
90 | "temporary": false,
91 | "created_at": "2016-03-31T19:15:39.954000+00:00"
92 | }
93 | ```
94 |
95 | ### Invite Stage Instance Object
96 |
97 | ###### Invite Stage Instance Structure
98 |
99 | | Field | Type | Description |
100 | | ----------------- | ----------------------------------------------------------------------------- | -------------------------------------------------- |
101 | | members | array of partial [guild member](/resources/guild#guild-member-object) objects | the members speaking in the Stage |
102 | | participant_count | integer | the number of users in the Stage |
103 | | speaker_count | integer | the number of users speaking in the Stage |
104 | | topic | string | the topic of the Stage instance (1-120 characters) |
105 |
106 | ###### Example Invite Stage Instance
107 |
108 | ```json
109 | {
110 | "topic": "The debate is over: diet is better than regular",
111 | "participant_count": 200,
112 | "speaker_count": 5,
113 | "members": [
114 | {
115 | "roles": [],
116 | "nick": "NOT API SUPPORT",
117 | "avatar": null,
118 | "premium_since": null,
119 | "joined_at": "2015-04-26T06:26:56.936000+00:00",
120 | "pending": false,
121 | "user": {}
122 | }
123 | ]
124 | }
125 | ```
126 |
127 | ## Endpoints
128 |
129 |
130 | Get Invite
131 |
132 |
133 | Returns an [invite](#invite-object) object for the given code.
134 |
135 | ###### Query String Params
136 |
137 | | Field | Type | Description |
138 | | ---------------- | ------- | ----------------------------------------------------------- |
139 | | with_counts? | boolean | whether the invite should contain approximate member counts |
140 | | with_expiration? | boolean | whether the invite should contain the expiration date |
141 |
142 |
143 | Delete Invite
144 |
145 |
146 | Delete an invite. Requires the `MANAGE_CHANNELS` permission on the channel this invite belongs to, or `MANAGE_GUILD` to remove any invite across the guild. Returns an [invite](#invite-object) object on success. Fires a [Invite Delete](/topics/gateway#invite-delete) Gateway event.
147 |
--------------------------------------------------------------------------------
/pages/topics/certified-devices.mdx:
--------------------------------------------------------------------------------
1 | # Certified Devices
2 |
3 | Baked into Discord is the ability for hardware manufacturers to tell us a little more about the certified devices that are plugged into a user's computer. Unfortunately, no, you can't show that a user's PUBG Chicken Dinner was all thanks to the amazing TotallyRealHardware RGB Mouse and Keyboard Set Extraordinaire™, but you _can_ give them an amazing experience using your hardware with Discord!
4 |
5 | ## How's it work?
6 |
7 | I'm glad you asked!
8 |
9 | 1. [Create an application](https://discord.com/developers/applications/me) for your hardware vendor—save the Client ID!
10 | 2. Talk to Discord via one simple HTTP or WebSocket call
11 | 3. Send us a [`SET_CERTIFIED_DEVICES`](/topics/rpc#set_certified_devices) WebSocket payload or equivalent HTTP POST whenever the state of the device changes
12 |
13 | Yup, that's it. You give us the real-time info about any connected devices, and we'll handle the rest to make sure that anyone using your device will have an awesome experience. Your device will also have a `CERTIFIED` badge in Discord's audio settings, and really, who doesn't love badges?
14 |
15 | 
16 |
17 | ## Connecting
18 |
19 | ###### Query String Params
20 |
21 | | Name | Value | Required |
22 | | --------- | -------------------- | --------- |
23 | | v | `1` | All |
24 | | client_id | your app's client id | All |
25 | | encoding | `json` | WebSocket |
26 |
27 | You can send event updates to the following URIs:
28 |
29 | ###### HTTP
30 |
31 | ```
32 | http://127.0.0.1:PORT/rpc?v=1&client_id=YOUR_CLIENT_ID
33 | ```
34 |
35 | ###### WebSocket
36 |
37 | ```
38 | ws://127.0.0.1:PORT?v=1&client_id=YOUR_CLIENT_ID&encoding=json
39 | ```
40 |
41 | `PORT` is a range of ports from `6463` to `6473`. You should iterate over these ports with your request until one returns a success response code or succeeds with a socket connection. Keep track of that port number for the rest of the session.
42 |
43 | To keep your hardware in sync with Discord, send updates any time the hardware mute is toggled, or one of the voice features like echo cancellation is enabled or disabled by the user. This lets Discord get out of the way of your optimization when you're in control, or help out when you're not, ensuring an awesome experience for anyone using your hardware.
44 |
45 | Each time you update, send a full array of `devices`, sorted by your preferred priority. That means if you want a specific headset to be the default that Discord will attempt to use, put it first in the array.
46 |
47 | ## Getting Device UUID
48 |
49 | For each device in the `SET_CERTIFIED_DEVICES` payload, there is an `id` field. This `id` should be the Windows device's UUID, retrieved through the native Windows API. You'll get back something that looks like `{0.0.1.00000000}.{6cff2b76-44a8-46b9-b528-262ad8609d9f}`.
50 |
51 |
52 |
53 | On macOS, the `id` will be the name of the device.
54 |
55 |
56 |
57 | ###### Microphone Id Example
58 |
59 | ```cpp
60 | id = waveInMessage((HWAVEIN)IntToPtr(index),
61 | DRV_QUERYFUNCTIONINSTANCEID,
62 | (DWORD_PTR)pstrEndpointId,
63 | cbEndpointId);
64 | ```
65 |
66 | ###### Speaker Id Example
67 |
68 | ```cpp
69 | id = waveOutMessage((HWAVEIN)IntToPtr(index),
70 | DRV_QUERYFUNCTIONINSTANCEID,
71 | (DWORD_PTR)pstrEndpointId,
72 | cbEndpointId);
73 | ```
74 |
75 | ## HTTP Example
76 |
77 | ###### HTTP Request Example
78 |
79 | ```
80 | curl -X POST -H 'Content-Type: application/json' -d '
81 | {
82 | "nonce": "9b4e9711-97f3-4f35-b047-32c82a51978e",
83 | "cmd": "SET_CERTIFIED_DEVICES",
84 | "args": {
85 | "devices": [
86 | {
87 | "type": "audioinput",
88 | "id": "{0.0.1.00000000}.{6cff2b76-44a8-46b9-b528-262ad8609d9f}",
89 | "vendor": {
90 | "name": "SteelSeries",
91 | "url": "https://steelseries.com"
92 | },
93 | "model": {
94 | "name": "Arctis 7",
95 | "url": "https://steelseries.com/gaming-headsets/arctis-7"
96 | },
97 | "related": ["{0.0.1.00000000}.{6cff2b76-44a8-46b9-b528-262ad8609d9f}"],
98 | "echo_cancellation": true,
99 | "noise_suppression": true,
100 | "automatic_gain_control": true,
101 | "hardware_mute": false
102 | }
103 | ]
104 | }
105 | }
106 | ' http://127.0.0.1:PORT/rpc?v=1&client_id=YOUR_CLIENT_ID
107 | ```
108 |
109 | The socket will respond with a `200 OK` status code and the following JSON.
110 |
111 | ###### HTTP Response Example
112 |
113 | ```json
114 | {
115 | "cmd": "SET_CERTIFIED_DEVICES",
116 | "data": null,
117 | "evt": null,
118 | "nonce": "9b4e9711-97f3-4f35-b047-32c82a51978e"
119 | }
120 | ```
121 |
122 | ## WebSocket Example
123 |
124 | ###### RPC Command Example
125 |
126 | ```json
127 | {
128 | "nonce": "9b4e9711-97f3-4f35-b047-32c82a51978e",
129 | "cmd": "SET_CERTIFIED_DEVICES",
130 | "args": {
131 | "devices": [
132 | {
133 | "type": "audioinput",
134 | "id": "{0.0.1.00000000}.{6cff2b76-44a8-46b9-b528-262ad8609d9f}",
135 | "vendor": {
136 | "name": "SteelSeries",
137 | "url": "https://steelseries.com"
138 | },
139 | "model": {
140 | "name": "Arctis 7",
141 | "url": "https://steelseries.com/gaming-headsets/arctis-7"
142 | },
143 | "related": ["{0.0.1.00000000}.{6cff2b76-44a8-46b9-b528-262ad8609d9f}"],
144 | "echo_cancellation": true,
145 | "noise_suppression": true,
146 | "automatic_gain_control": true,
147 | "hardware_mute": false
148 | }
149 | ]
150 | }
151 | }
152 | ```
153 |
154 | ###### RPC Response Example
155 |
156 | ```json
157 | {
158 | "nonce": "9b4e9711-97f3-4f35-b047-32c82a51978e",
159 | "cmd": "SET_CERTIFIED_DEVICES",
160 | "data": null,
161 | "evt": null
162 | }
163 | ```
164 |
165 | ## Models
166 |
167 | ###### Device Object
168 |
169 | | Field | Type | Description |
170 | | ------------------------- | ------------------------------- | -------------------------------------------------------- |
171 | | type | [device type](#device-types) | the type of device |
172 | | id | string | the device's Windows UUID |
173 | | vendor | [vendor](#vendor-object) object | the hardware vendor |
174 | | model | [model](#model-object) object | the model of the product |
175 | | related | array of strings | UUIDs of related devices |
176 | | echo_cancellation?\* | boolean | if the device's native echo cancellation is enabled |
177 | | noise_suppression?\* | boolean | if the device's native noise suppression is enabled |
178 | | automatic_gain_control?\* | boolean | if the device's native automatic gain control is enabled |
179 | | hardware_mute?\* | boolean | if the device is hardware muted |
180 |
181 | \*These fields are only applicable for `AUDIO_INPUT` device types
182 |
183 | ###### Vendor Object
184 |
185 | | Field | Type | Description |
186 | | ----- | ------ | ------------------ |
187 | | name | string | name of the vendor |
188 | | url | string | url for the vendor |
189 |
190 | ###### Model Object
191 |
192 | | Field | Type | Description |
193 | | ----- | ------ | ----------------- |
194 | | name | string | name of the model |
195 | | url | string | url for the model |
196 |
197 | ###### Device Types
198 |
199 | | Type | Value |
200 | | ------------ | ------------- |
201 | | AUDIO_INPUT | "audioinput" |
202 | | AUDIO_OUTPUT | "audiooutput" |
203 | | VIDEO_INPUT | "videoinput" |
204 |
--------------------------------------------------------------------------------
/pages/topics/community-resources.mdx:
--------------------------------------------------------------------------------
1 | # Community Resources
2 |
3 | Discord has the best online community. At least, we like to think so, and this is our website, so our word is law, deal with it. Therefore it's a fact that our community is the best, and they make really awesome things that we want to share with developers to make their lives easier. From permissions calculators to embed visualizers to full libraries to interface with our API, there are so many great things that have come out of our community.
4 |
5 | ## Discord Developers
6 |
7 | The [Official Discord Developers server](https://discord.gg/discord-developers) is a developer ran, but community driven, support hub. If you need help with developing something on Discord or want official updates from the developers, this is the place to be.
8 |
9 | ## Libraries
10 |
11 | The Discord team curates the following list of officially vetted libraries that conform to our APIs standards around authentication and rate limiting. Using custom implementations or non-compliant libraries that abuse the API or cause excessive rate limits may result in a **permanent** ban.
12 |
13 | Many of these libraries are represented in the [unofficial, community-driven Discord server for developers](https://discord.gg/discord-api). There you'll find community members who can help answer questions about our API, community libraries, bot creation, and other development questions.
14 |
15 | ###### Discord Libraries
16 |
17 | | Name | Language |
18 | | ------------------------------------------------------------- | ---------- |
19 | | [discljord](https://github.com/igjoshua/discljord) | Clojure |
20 | | [aegis.cpp](https://github.com/zeroxs/aegis.cpp) | C++ |
21 | | [D++](https://github.com/brainboxdotcc/DPP) | C++ |
22 | | [Sleepy Discord](https://github.com/yourWaifu/sleepy-discord) | C++ |
23 | | [discordcr](https://github.com/shardlab/discordcr) | Crystal |
24 | | [Remora.Discord](https://github.com/Nihlus/Remora.Discord) | C# |
25 | | [Discord.Net](https://github.com/RogueException/Discord.Net) | C# |
26 | | [DSharpPlus](https://github.com/DSharpPlus/DSharpPlus) | C# |
27 | | [coxir](https://github.com/satom99/coxir) | Elixir |
28 | | [Nostrum](https://github.com/Kraigie/nostrum) | Elixir |
29 | | [DiscordGo](https://github.com/bwmarrin/discordgo) | Go |
30 | | [DisGord](https://github.com/andersfylling/disgord) | Go |
31 | | [catnip](https://github.com/mewna/catnip) | Java |
32 | | [Discord4J](https://discord4j.com/) | Java |
33 | | [Javacord](https://github.com/Javacord/Javacord) | Java |
34 | | [JDA](https://github.com/DV8FromTheWorld/JDA) | Java |
35 | | [discord.js](https://github.com/discordjs/discord.js) | JavaScript |
36 | | [Eris](https://github.com/abalabahaha/eris) | JavaScript |
37 | | [Discord.jl](https://github.com/Xh4H/Discord.jl) | Julia |
38 | | [Discordia](https://github.com/SinisterRectus/Discordia) | Lua |
39 | | [Dimscord](https://github.com/krisppurg/dimscord) | Nim |
40 | | [discordnim](https://github.com/Krognol/discordnim) | Nim |
41 | | [DiscordPHP](https://github.com/discord-php/DiscordPHP) | PHP |
42 | | [RestCord](https://www.restcord.com/) | PHP |
43 | | [discord.py](https://github.com/Rapptz/discord.py) | Python |
44 | | [disco](https://github.com/b1naryth1ef/disco) | Python |
45 | | [discordrb](https://github.com/shardlab/discordrb) | Ruby |
46 | | [discord-rs](https://github.com/SpaceManiac/discord-rs) | Rust |
47 | | [Serenity](https://github.com/serenity-rs/serenity) | Rust |
48 | | [Twilight](https://github.com/twilight-rs/twilight) | Rust |
49 | | [AckCord](https://github.com/Katrix/AckCord) | Scala |
50 | | [Sword](https://github.com/Azoy/Sword) | Swift |
51 | | [Detritus](https://github.com/detritusjs/client) | TypeScript |
52 | | [discordeno](https://github.com/discordeno/discordeno) | TypeScript |
53 | | [droff](https://github.com/tim-smart/droff) | TypeScript |
54 | | [Harmony](https://github.com/harmonyland/harmony) | TypeScript |
55 |
56 | ## Interactions
57 |
58 | [Interactions](/interactions/receiving-and-responding/) are the great, new way of making a Discord bot. The following open-source libraries provide help for the security and authentication checks that are mandatory if you are receiving Interactions via outgoing webhook. They also include some types for the Interactions data models.
59 |
60 | - Clojure
61 | - [ring-discord-auth](https://github.com/JohnnyJayJay/ring-discord-auth)
62 | - Go
63 | - [discord-interactions-go](https://github.com/bsdlp/discord-interactions-go)
64 | - Javascript
65 | - [discord-interactions-js](https://github.com/discord/discord-interactions-js)
66 | - [discord-slash-commands](https://github.com/MeguminSama/discord-slash-commands) and its [Deno fork](https://deno.land/x/discord_slash_commands)
67 | - [slash-create](https://github.com/Snazzah/slash-create)
68 | - Python
69 | - [discord-interactions-python](https://github.com/discord/discord-interactions-python)
70 | - [discord-interactions.py](https://github.com/LiBa001/discord-interactions.py)
71 | - [dispike](https://github.com/ms7m/dispike)
72 | - [flask-discord-interactions](https://github.com/Breq16/flask-discord-interactions)
73 | - PHP
74 | - [discord-interactions-php](https://github.com/discord/discord-interactions-php)
75 | - Other
76 | - [caddy-discord-interactions-verifier](https://github.com/CarsonHoffman/caddy-discord-interactions-verifier)
77 | - [Rauf's Slash Command Generator](https://rauf.wtf/slash)
78 | - [Autocode Slash Command Builder](https://autocode.com/tools/discord/command-builder/)
79 |
80 | ## Game SDK Tools
81 |
82 | Discord Game SDK's lobby and networking layer shares similarities with other gaming platforms (i.e. Valve's Steamworks SDK). The following open source library provides developers a uniform interface for these shared features and can simplify developing for multiple platforms. Note: this library is tailored for Unity3D development.
83 |
84 | - [HouraiNetworking](https://github.com/HouraiTeahouse/HouraiNetworking)
85 |
86 | ## Dispatch Tools
87 |
88 | Using Discord's [Dispatch](/dispatch/dispatch-and-you) tool for game developers publishing on Discord can sometimes involve using the same long commands multiple times. The following open-source tool helps shorten these commands for you. It will also provide webhook support for when you're pushing an update.
89 |
90 | - [JohnyTheCarrot's Dispatch CLI](https://github.com/JohnyTheCarrot/droops-dispatch)
91 |
92 | ## Permission Calculators
93 |
94 | [Permissions](/topics/permissions#permissions) in Discord are tricky. Luckily, we've got really smart people who love us and have made some great permissions calculators. If you're making a bot for others, and you're not sure how to properly calculate permissions or generate your [authorization URL](/topics/oauth2#bot-authorization-flow), these are great tools:
95 |
96 | - [FiniteReality's Permissions Calculator](https://finitereality.github.io/permissions-calculator/?v=0)
97 | - [abalabahaha's Permissions Calculator](https://discordapi.com/permissions.html#0)
98 |
99 | ## Intent Calculators
100 |
101 | [Gateway Intents](/topics/gateway#gateway-intents) are pretty confusing at first. If you're not sure what to send in your [identify payload](/topics/gateway#identify), then these tools may be of help:
102 |
103 | - [ziad87's Intent Calculator](https://ziad87.net/intents/)
104 | - [Larko's Intent Calculator](https://discord-intents-calculator.vercel.app/)
105 |
106 | ## Embed Visualizer
107 |
108 | Webhooks and embeds might seem like black magic. That's because they are, but let us help you demystify them a bit. This sweet embed visualizer lets you play around with JSON data and see exactly how it will look embedded in Discord. It even includes a webhook mode!
109 |
110 | - [Autocode Embed Builder](https://autocode.com/tools/discord/embed-builder/)
111 |
112 | ## API Types
113 |
114 | If you're working on a project that interacts with our API, you might find an API types module useful as it provides type inspection/completion for the Discord API.
115 |
116 | - [discord.js API Types](https://github.com/discordjs/discord-api-types)
117 |
--------------------------------------------------------------------------------
/pages/game-sdk/relationships.mdx:
--------------------------------------------------------------------------------
1 | # Relationships
2 |
3 |
4 |
5 | Need help with the SDK? Talk to us in the [Discord Developers Server](https://discord.gg/discord-developers)!
6 |
7 |
8 |
9 |
10 |
11 | Game approval submissions are currently paused due to unforeseen circumstances. We apologize for the inconvenience. [Click here for more info.](https://support-dev.discord.com/hc/en-us/articles/360041437171)
12 |
13 |
14 |
15 | This manager helps you access the relationships your players have made on Discord. Unfortunately, it won't help them make relationships IRL. They're on their own for that. It lets you:
16 |
17 | - Access a user's relationships
18 | - Filter those relationships based on a given criteria
19 | - Build a user's friends list
20 |
21 | ## First Notes
22 |
23 | Relationships on Discord change often; people start and stop playing games, go online, offline, invisible, or otherwise change state. Therefore, there are some important factors to remember when working with this manager. When you are first getting a list of a user's relationships, before you can `Filter()`, you need to wait for the `OnRefresh` callback to fire. This is your indicator that Discord has successfully taken a snapshot of the state of all your relationships at a given moment. Now that you have this snapshot, you can `Filter()` it to build the list that you want, and then iterate over that list to do whatever your game needs to do. Use this to build your initial social graph for a user.
24 |
25 | As relationships change, the `OnRelationshipUpdate` event will fire. You can use this to update the user's social graph, changing the status of the other Discord users that you chose to filter, e.g. someone is now online, or now playing the game, or no longer playing.
26 |
27 | An example of how to do this properly is at the end of this documentation page.
28 |
29 | ## Data Models
30 |
31 | ###### Relationship Struct
32 |
33 | | name | type | description |
34 | | -------- | ---------------- | -------------------------------- |
35 | | Type | RelationshipType | what kind of relationship it is |
36 | | User | User | the user the relationship is for |
37 | | Presence | Presence | that user's current presence |
38 |
39 | ###### RelationshipType Enum
40 |
41 | | value | description |
42 | | --------------- | -------------------------------------------------------------------------------- |
43 | | None | user has no intrinsic relationship |
44 | | Friend | user is a friend |
45 | | Blocked | user is blocked |
46 | | PendingIncoming | user has a pending incoming friend request to connected user |
47 | | PendingOutgoing | current user has a pending outgoing friend request to user |
48 | | Implicit | user is not friends, but interacts with current user often (frequency + recency) |
49 |
50 | ###### Presence Struct
51 |
52 | | name | type | description |
53 | | -------- | -------- | -------------------------------- |
54 | | Status | Status | the user's current online status |
55 | | Activity | Activity | the user's current activity |
56 |
57 | ###### Status Enum
58 |
59 | | name | value |
60 | | ------------ | ----- |
61 | | Offline | 0 |
62 | | Online | 1 |
63 | | Idle | 2 |
64 | | DoNotDisturb | 3 |
65 |
66 | ## Filter
67 |
68 | Filters a user's relationship list by a boolean condition.
69 |
70 | Returns `void`.
71 |
72 | ###### Parameters
73 |
74 | A function that takes a `Relationship` parameter.
75 |
76 | ###### Example
77 |
78 | ```cs
79 | relationshipsManager.Filter(relationship =>
80 | {
81 | return relationship.Presence.Status == Discord.Status.Online;
82 | });
83 | ```
84 |
85 | ## Get
86 |
87 | Get the relationship between the current user and a given user by id.
88 |
89 | Returns a `Relationship`.
90 |
91 | ###### Parameters
92 |
93 | | name | type | description |
94 | | ------ | ----- | --------------------------- |
95 | | userId | Int64 | the id of the user to fetch |
96 |
97 | ###### Example
98 |
99 | ```cs
100 | var friend = relationshipsManager.Get(53908232506183680);
101 | Console.WriteLine("This is my friend, {0}", friend.User.Username);
102 | ```
103 |
104 | ## GetAt
105 |
106 | Get the relationship at a given index when iterating over a list of relationships.
107 |
108 | Returns a `Relationship`.
109 |
110 | ###### Parameters
111 |
112 | | name | type | description |
113 | | ----- | ------ | ----------------- |
114 | | index | UInt32 | index in the list |
115 |
116 | ###### Example
117 |
118 | ```cs
119 | for (int i = 0; i < relationshipsManager.Count(); i++)
120 | {
121 | var r = relationshipsManager.GetAt(i);
122 | Console.WriteLine("This person is {0}", r.User.Username);
123 | }
124 | ```
125 |
126 | ## Count
127 |
128 | Get the number of relationships that match your `Filter()`.
129 |
130 | Returns an `Int32`.
131 |
132 | ###### Parameters
133 |
134 | None
135 |
136 | ###### Example
137 |
138 | ```cs
139 | for (int i = 0; i < relationshipsManager.Count(); i++)
140 | {
141 | var r = relationshipsManager.At(i);
142 | Console.WriteLine("This person is {0}", r.User.Username);
143 | }
144 | ```
145 |
146 | ## OnRefresh
147 |
148 | Fires at initialization when Discord has cached a snapshot of the current status of all your relationships. Wait for this to fire before calling `Filter` within its callback.
149 |
150 | ###### Parameters
151 |
152 | None
153 |
154 | ## OnRelationshipUpdate
155 |
156 | Fires when a relationship in the filtered list changes, like an updated presence or user attribute.
157 |
158 | ###### Parameters
159 |
160 | | name | type | description |
161 | | ------------ | ---------------- | ----------------------------- |
162 | | relationship | ref Relationship | the relationship that changed |
163 |
164 | ###### Example
165 |
166 | ```cs
167 | OnRelationshipUpdate += (ref Discord.Relationship relationship) =>
168 | {
169 | Console.WriteLine("Who changed? {0}", relationship.User.Id);
170 | };
171 | ```
172 |
173 | ## Example: Creating a Friends List
174 |
175 | ```cs
176 | var discord = new Discord.Discord(clientId, Discord.CreateFlags.Default);
177 | var relationshipManager = discord.GetRelationshipManager();
178 |
179 | // Assign this handle right away to get the initial relationships update.
180 | // This callback will only be fired when the whole list is initially loaded or was reset
181 |
182 | // Wait for OnRefresh to fire to access a stable list
183 | // Filter a user's relationship list to be just friends
184 | // Use this list as your base
185 | relationshipManager.OnRefresh += () =>
186 | {
187 | relationshipManager.Filter((relationship) =>
188 | {
189 | return relationship.Type == Discord.RelationshipType.Friend;
190 | });
191 |
192 | // Loop over all friends a user has.
193 | Console.WriteLine("relationships updated: {0}", relationshipManager.Count());
194 |
195 | for (var i = 0; i < relationshipManager.Count(); i++)
196 | {
197 | // Get an individual relationship from the list
198 | var r = relationshipManager.GetAt((uint)i);
199 | Console.WriteLine("relationships: {0} {1}", r.Type, r.User.Username);
200 | // Save r off to a list of user's relationships
201 | }
202 | }
203 |
204 | relationshipManager.OnRelationshipUpdate += (ref Discord.Relationship relationship) =>
205 | {
206 | Console.WriteLine("User is {0}", relationship.User.Username);
207 | // Update the matching user in your previously created list
208 | }
209 | ```
210 |
211 | ## Example: Invite Users Who Are Playing the Same Game
212 |
213 | ```cs
214 | var discord = new Discord.Discord(clientId, Discord.CreateFlags.Default);
215 | var relationshipManager = discord.GetRelationshipManager();
216 | var activityManager = discord.GetActivityManager();
217 |
218 | relationshipManager.OnRefresh += () =>
219 | {
220 | relationshipManager.Filter((relationship) =>
221 | {
222 | // Filter for users who are playing the same game as the current user
223 | // Is their activity application id the same as my client id?
224 | return relationship.Presence.Activity.ApplicationId == clientId;
225 | });
226 |
227 | for (var i = 0; i < relationshipManager.Count(); i++)
228 | {
229 | // Get an individual relationship from the list
230 | var r = relationshipManager.GetAt((uint)i);
231 | Console.WriteLine("relationships: {0} {1}", r.Type, r.User.Username);
232 |
233 | // Send them a game invite!
234 | activityManager.InviteUser(r.User.Id, Discord.ActivityActionType.Join, "Come play with me!", (result) =>
235 | {
236 | Console.WriteLine("Invited user {0} to play with you", r.User.Username);
237 | });
238 | };
239 | }
240 | ```
241 |
--------------------------------------------------------------------------------