Skip to content

Commit eef7a84

Browse files
committed
docs: step by step gateway example
1 parent 3419a9f commit eef7a84

File tree

2 files changed

+125
-7
lines changed

2 files changed

+125
-7
lines changed

docs/gateway.rst

Lines changed: 121 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,130 @@ Gateway quickstart
88

99
.. hint::
1010
We recommend that you read the :ref:`Making requests` tutorial before this, as we will not explain HTTP concepts here.
11+
.. hint::
12+
The finished example can be found `here <https://github.com/nextsnake/nextcore/blob/master/examples/gateway/ping_pong.py>`__
13+
.. note::
14+
We will use await at the top level here as its easier to explain. For your own code, please use a async function.
15+
16+
If you want a example of how it can be done in a async function, see the full example.
17+
18+
Setting up
19+
^^^^^^^^^^
20+
.. code-block:: python3
21+
22+
import asyncio
23+
from os import environ
24+
from typing import cast
25+
26+
from discord_typings import MessageData
27+
28+
from nextcore.gateway import ShardManager
29+
from nextcore.http import BotAuthentication, HTTPClient, Route
30+
31+
# Constants
32+
AUTHENTICATION = BotAuthentication(environ["TOKEN"])
33+
34+
Intents
35+
^^^^^^^
36+
Discord uses intents to select what you want to be sent from the gateway to reduce wasted resources
37+
This is done via bitflags.
38+
39+
A list of intents can be found on the `intents page <https://discord.dev/topics/gateway#gateway-intents>`__
40+
41+
In this example we want the message intent, and the message content intent.
42+
43+
.. code-block:: python3
44+
45+
GUILD_MESSAGES_INTENT = 1 << 9
46+
MESSAGE_CONTENT_INTENT = 1 << 15
47+
48+
.. note::
49+
This can also be stored in binary representation
50+
51+
.. code-block:: python3
52+
53+
GUILD_MESSAGES_INTENT = 0b1000000000
54+
MESSAGE_CONTENT_INTENT = 0b1000000000000000
55+
56+
If you want to use multiple intents, you can combine them using bitwise or (``|``)
57+
58+
.. code-block:: python3
59+
60+
INTENTS = GUILD_MESSAGES_INTENT | MESSAGE_CONTENT_INTENT
61+
62+
Now just give it to the :class:`ShardManager`
63+
64+
.. code-block:: python3
65+
66+
http_client = HTTPClient()
67+
shard_manager = ShardManager(AUTHENTICATION, INTENTS, http_client)
68+
69+
.. note::
70+
Discord marks the ``MESSAGE_CONTENT_INTENT`` as "privileged", meaning you have to turn on a switch in the `developer portal <https://discord.com/developers/applications>`__
71+
72+
Creating a listener
73+
^^^^^^^^^^^^^^^^^^^
74+
Lets create a listener for whenever someone sends a message
75+
76+
A list of events can be found on the `Receive events <https://discord.dev/topics/gateway-events#receive-events>`__ page
77+
78+
.. code-block:: python3
79+
80+
@shard_manager.event_dispatcher.listen("MESSAGE_CREATE")
81+
async def on_message(message: MessageData):
82+
# This function will be called every time a message is sent.
83+
84+
Now just check if someone said ``ping`` and respond with ``pong``
85+
86+
.. code-block:: python3
87+
88+
if message["content"] == "ping":
89+
# Send a pong message to respond.
90+
route = Route("POST", "/channels/{channel_id}/messages", channel_id=message["channel_id"])
91+
92+
await http_client.request(
93+
route,
94+
rate_limit_key=AUTHENTICATION.rate_limit_key,
95+
json={"content": "pong"},
96+
headers=AUTHENTICATION.headers,
97+
)
98+
99+
.. hint::
100+
Confused by this? Check out the :ref:`Making requests` tutorial
101+
102+
Connecting to Discord
103+
^^^^^^^^^^^^^^^^^^^^^
104+
.. code-block:: python3
105+
106+
await http_client.setup()
107+
await shard_manager.connect()
108+
109+
.. need absolute ref for HTTPClient as its in the http module
110+
.. warning::
111+
:meth:`HTTPClient.setup() <nextcore.http.HTTPClient.setup>` needs to be called before :meth:`ShardManager.connect`
112+
.. note::
113+
:meth:`ShardManager.connect` will return once every shard has started to connect
114+
115+
Stopping the script from stopping
116+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
117+
Since the :meth:`ShardManager.connect` function returns once every shard has started to connect, the script closes as the main thread has nothing to do.
118+
119+
We can wait for a critical error before closing to fix this.
120+
121+
.. code-block:: python3
122+
123+
(error,) = await shard_manager.dispatcher.wait_for(lambda: True, "critical")
11124
12-
Basic ping-pong example
13-
************************
14-
This will respond with ``pong`` every time someone sends ``ping`` in chat.
125+
raise cast(Exception, error)
15126
16-
.. literalinclude:: ../examples/gateway/ping_pong.py
17-
:lines: 28-
18-
:language: python
127+
.. note::
128+
The weird ``(error, )`` thing is to extract the first element out of the tuple.
19129

130+
Continuing
131+
^^^^^^^^^^
132+
We suggest you look into `interactions & application commands <https://discord.dev/interactions/application-commands>`__ as your next topic.
133+
They allow you to add `buttons <https://discord.dev/interactions/message-components#buttons>`__ and `slash commands <https://discord.dev/interactions/application-commands#slash-commands>`__ and other cool stuff
134+
20135

21136
Gateway reference
22137
-----------------

examples/gateway/ping_pong.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@
3939

4040
# Intents are a way to select what intents Discord should send to you.
4141
# For a list of intents see https://discord.dev/topics/gateway#gateway-intents
42-
INTENTS = 1 << 9 | 1 << 15 # Guild messages and message content intents.
42+
GUILD_MESSAGES_INTENT = 1 << 9
43+
MESSAGE_CONTENT_INTENT = 1 << 15
44+
45+
INTENTS = GUILD_MESSAGES_INTENT | MESSAGE_CONTENT_INTENT # Guild messages and message content intents.
4346

4447

4548
# Create a HTTPClient and a ShardManager.

0 commit comments

Comments
 (0)