@ -1,96 +0,0 @@ |
|||
:orphan: |
|||
|
|||
.. _discord-intro: |
|||
|
|||
Creating a Bot Account |
|||
======================== |
|||
|
|||
In order to work with the library and the Discord API in general, we must first create a Discord Bot account. |
|||
|
|||
Creating a Bot account is a pretty straightforward process. |
|||
|
|||
1. Make sure you're logged on to the `Discord website <https://discord.com>`_. |
|||
2. Navigate to the `application page <https://discord.com/developers/applications>`_ |
|||
3. Click on the "New Application" button. |
|||
|
|||
.. image:: /images/discord_create_app_button.png |
|||
:alt: The new application button. |
|||
|
|||
4. Give the application a name and click "Create". |
|||
|
|||
.. image:: /images/discord_create_app_form.png |
|||
:alt: The new application form filled in. |
|||
|
|||
5. Create a Bot User by navigating to the "Bot" tab and clicking "Add Bot". |
|||
|
|||
- Click "Yes, do it!" to continue. |
|||
|
|||
.. image:: /images/discord_create_bot_user.png |
|||
:alt: The Add Bot button. |
|||
6. Make sure that **Public Bot** is ticked if you want others to invite your bot. |
|||
|
|||
- You should also make sure that **Require OAuth2 Code Grant** is unchecked unless you |
|||
are developing a service that needs it. If you're unsure, then **leave it unchecked**. |
|||
|
|||
.. image:: /images/discord_bot_user_options.png |
|||
:alt: How the Bot User options should look like for most people. |
|||
|
|||
7. Copy the token using the "Copy" button. |
|||
|
|||
- **This is not the Client Secret at the General Information page.** |
|||
|
|||
.. warning:: |
|||
|
|||
It should be worth noting that this token is essentially your bot's |
|||
password. You should **never** share this with someone else. In doing so, |
|||
someone can log in to your bot and do malicious things, such as leaving |
|||
servers, ban all members inside a server, or pinging everyone maliciously. |
|||
|
|||
The possibilities are endless, so **do not share this token.** |
|||
|
|||
If you accidentally leaked your token, click the "Regenerate" button as soon |
|||
as possible. This revokes your old token and re-generates a new one. |
|||
Now you need to use the new token to login. |
|||
|
|||
And that's it. You now have a bot account and you can login with that token. |
|||
|
|||
.. _discord_invite_bot: |
|||
|
|||
Inviting Your Bot |
|||
------------------- |
|||
|
|||
So you've made a Bot User but it's not actually in any server. |
|||
|
|||
If you want to invite your bot you must create an invite URL for it. |
|||
|
|||
1. Make sure you're logged on to the `Discord website <https://discord.com>`_. |
|||
2. Navigate to the `application page <https://discord.com/developers/applications>`_ |
|||
3. Click on your bot's page. |
|||
4. Go to the "OAuth2" tab. |
|||
|
|||
.. image:: /images/discord_oauth2.png |
|||
:alt: How the OAuth2 page should look like. |
|||
|
|||
5. Tick the "bot" checkbox under "scopes". |
|||
|
|||
.. image:: /images/discord_oauth2_scope.png |
|||
:alt: The scopes checkbox with "bot" ticked. |
|||
|
|||
6. Tick the permissions required for your bot to function under "Bot Permissions". |
|||
|
|||
- Please be aware of the consequences of requiring your bot to have the "Administrator" permission. |
|||
|
|||
- Bot owners must have 2FA enabled for certain actions and permissions when added in servers that have Server-Wide 2FA enabled. Check the `2FA support page <https://support.discord.com/hc/en-us/articles/219576828-Setting-up-Two-Factor-Authentication>`_ for more information. |
|||
|
|||
.. image:: /images/discord_oauth2_perms.png |
|||
:alt: The permission checkboxes with some permissions checked. |
|||
|
|||
7. Now the resulting URL can be used to add your bot to a server. Copy and paste the URL into your browser, choose a server to invite the bot to, and click "Authorize". |
|||
|
|||
|
|||
.. note:: |
|||
|
|||
The person adding the bot needs "Manage Server" permissions to do so. |
|||
|
|||
If you want to generate this URL dynamically at run-time inside your bot and using the |
|||
:class:`discord.Permissions` interface, you can use :func:`discord.utils.oauth_url`. |
Before Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 51 KiB |
@ -1,192 +0,0 @@ |
|||
:orphan: |
|||
|
|||
.. currentmodule:: discord |
|||
.. versionadded:: 1.5 |
|||
.. _intents_primer: |
|||
|
|||
A Primer to Gateway Intents |
|||
============================= |
|||
|
|||
In version 1.5 comes the introduction of :class:`Intents`. This is a radical change in how bots are written. An intent basically allows a bot to subscribe to specific buckets of events. The events that correspond to each intent is documented in the individual attribute of the :class:`Intents` documentation. |
|||
|
|||
These intents are passed to the constructor of :class:`Client` or its subclasses (:class:`AutoShardedClient`, :class:`~.AutoShardedBot`, :class:`~.Bot`) with the ``intents`` argument. |
|||
|
|||
If intents are not passed, then the library defaults to every intent being enabled except the privileged intents, currently :attr:`Intents.members` and :attr:`Intents.presences`. |
|||
|
|||
What intents are needed? |
|||
-------------------------- |
|||
|
|||
The intents that are necessary for your bot can only be dictated by yourself. Each attribute in the :class:`Intents` class documents what :ref:`events <discord-api-events>` it corresponds to and what kind of cache it enables. |
|||
|
|||
For example, if you want a bot that functions without spammy events like presences or typing then we could do the following: |
|||
|
|||
.. code-block:: python3 |
|||
:emphasize-lines: 7,9,10 |
|||
|
|||
import discord |
|||
intents = discord.Intents.default() |
|||
intents.typing = False |
|||
intents.presences = False |
|||
|
|||
# Somewhere else: |
|||
# client = discord.Client(intents=intents) |
|||
# or |
|||
# from discord.ext import commands |
|||
# bot = commands.Bot(command_prefix='!', intents=intents) |
|||
|
|||
Note that this doesn't enable :attr:`Intents.members` since it's a privileged intent. |
|||
|
|||
Another example showing a bot that only deals with messages and guild information: |
|||
|
|||
.. code-block:: python3 |
|||
:emphasize-lines: 7,9,10 |
|||
|
|||
import discord |
|||
intents = discord.Intents(messages=True, guilds=True) |
|||
# If you also want reaction events enable the following: |
|||
# intents.reactions = True |
|||
|
|||
# Somewhere else: |
|||
# client = discord.Client(intents=intents) |
|||
# or |
|||
# from discord.ext import commands |
|||
# bot = commands.Bot(command_prefix='!', intents=intents) |
|||
|
|||
.. _privileged_intents: |
|||
|
|||
Privileged Intents |
|||
--------------------- |
|||
|
|||
With the API change requiring bot authors to specify intents, some intents were restricted further and require more manual steps. These intents are called **privileged intents**. |
|||
|
|||
A privileged intent is one that requires you to go to the developer portal and manually enable it. To enable privileged intents do the following: |
|||
|
|||
1. Make sure you're logged on to the `Discord website <https://discord.com>`_. |
|||
2. Navigate to the `application page <https://discord.com/developers/applications>`_. |
|||
3. Click on the bot you want to enable privileged intents for. |
|||
4. Navigate to the bot tab on the left side of the screen. |
|||
|
|||
.. image:: /images/discord_bot_tab.png |
|||
:alt: The bot tab in the application page. |
|||
|
|||
5. Scroll down to the "Privileged Gateway Intents" section and enable the ones you want. |
|||
|
|||
.. image:: /images/discord_privileged_intents.png |
|||
:alt: The privileged gateway intents selector. |
|||
|
|||
.. warning:: |
|||
|
|||
Enabling privileged intents when your bot is in over 100 guilds requires going through `bot verification <https://support.discord.com/hc/en-us/articles/360040720412>`_. If your bot is already verified and you would like to enable a privileged intent you must go through `Discord support <https://dis.gd/contact>`_ and talk to them about it. |
|||
|
|||
.. note:: |
|||
|
|||
Even if you enable intents through the developer portal, you still have to enable the intents |
|||
through code as well. |
|||
|
|||
Do I need privileged intents? |
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
|
|||
This is a quick checklist to see if you need specific privileged intents. |
|||
|
|||
.. _need_presence_intent: |
|||
|
|||
Presence Intent |
|||
+++++++++++++++++ |
|||
|
|||
- Whether you use :attr:`Member.status` at all to track member statuses. |
|||
- Whether you use :attr:`Member.activity` or :attr:`Member.activities` to check member's activities. |
|||
|
|||
.. _need_members_intent: |
|||
|
|||
Member Intent |
|||
+++++++++++++++ |
|||
|
|||
- Whether you track member joins or member leaves, corresponds to :func:`on_member_join` and :func:`on_member_remove` events. |
|||
- Whether you want to track member updates such as nickname or role changes. |
|||
- Whether you want to track user updates such as usernames, avatars, discriminators, etc. |
|||
- Whether you want to request the guild member list through :meth:`Guild.chunk` or :meth:`Guild.fetch_members`. |
|||
- Whether you want high accuracy member cache under :attr:`Guild.members`. |
|||
|
|||
.. _intents_member_cache: |
|||
|
|||
Member Cache |
|||
------------- |
|||
|
|||
Along with intents, Discord now further restricts the ability to cache members and expects bot authors to cache as little as is necessary. However, to properly maintain a cache the :attr:`Intents.members` intent is required in order to track the members who left and properly evict them. |
|||
|
|||
To aid with member cache where we don't need members to be cached, the library now has a :class:`MemberCacheFlags` flag to control the member cache. The documentation page for the class goes over the specific policies that are possible. |
|||
|
|||
It should be noted that certain things do not need a member cache since Discord will provide full member information if possible. For example: |
|||
|
|||
- :func:`on_message` will have :attr:`Message.author` be a member even if cache is disabled. |
|||
- :func:`on_voice_state_update` will have the ``member`` parameter be a member even if cache is disabled. |
|||
- :func:`on_reaction_add` will have the ``user`` parameter be a member when in a guild even if cache is disabled. |
|||
- :func:`on_raw_reaction_add` will have :attr:`RawReactionActionEvent.member` be a member when in a guild even if cache is disabled. |
|||
- The reaction add events do not contain additional information when in direct messages. This is a Discord limitation. |
|||
- The reaction removal events do not have member information. This is a Discord limitation. |
|||
|
|||
Other events that take a :class:`Member` will require the use of the member cache. If absolute accuracy over the member cache is desirable, then it is advisable to have the :attr:`Intents.members` intent enabled. |
|||
|
|||
.. _retrieving_members: |
|||
|
|||
Retrieving Members |
|||
-------------------- |
|||
|
|||
If the cache is disabled or you disable chunking guilds at startup, we might still need a way to load members. The library offers a few ways to do this: |
|||
|
|||
- :meth:`Guild.query_members` |
|||
- Used to query members by a prefix matching nickname or username. |
|||
- This can also be used to query members by their user ID. |
|||
- This uses the gateway and not the HTTP. |
|||
- :meth:`Guild.chunk` |
|||
- This can be used to fetch the entire member list through the gateway. |
|||
- :meth:`Guild.fetch_member` |
|||
- Used to fetch a member by ID through the HTTP API. |
|||
- :meth:`Guild.fetch_members` |
|||
- used to fetch a large number of members through the HTTP API. |
|||
|
|||
It should be noted that the gateway has a strict rate limit of 120 requests per 60 seconds. |
|||
|
|||
Troubleshooting |
|||
------------------ |
|||
|
|||
Some common issues relating to the mandatory intent change. |
|||
|
|||
Where'd my members go? |
|||
~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
|
|||
Due to an :ref:`API change <intents_member_cache>` Discord is now forcing developers who want member caching to explicitly opt-in to it. This is a Discord mandated change and there is no way to bypass it. In order to get members back you have to explicitly enable the :ref:`members privileged intent <privileged_intents>` and change the :attr:`Intents.members` attribute to true. |
|||
|
|||
For example: |
|||
|
|||
.. code-block:: python3 |
|||
:emphasize-lines: 3,6,8,9 |
|||
|
|||
import discord |
|||
intents = discord.Intents.default() |
|||
intents.members = True |
|||
|
|||
# Somewhere else: |
|||
# client = discord.Client(intents=intents) |
|||
# or |
|||
# from discord.ext import commands |
|||
# bot = commands.Bot(command_prefix='!', intents=intents) |
|||
|
|||
Why does ``on_ready`` take so long to fire? |
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
|
|||
As part of the API change regarding intents, Discord also changed how members are loaded in the beginning. Originally the library could request 75 guilds at once and only request members from guilds that have the :attr:`Guild.large` attribute set to ``True``. With the new intent changes, Discord mandates that we can only send 1 guild per request. This causes a 75x slowdown which is further compounded by the fact that *all* guilds, not just large guilds are being requested. |
|||
|
|||
There are a few solutions to fix this. |
|||
|
|||
The first solution is to request the privileged presences intent along with the privileged members intent and enable both of them. This allows the initial member list to contain online members just like the old gateway. Note that we're still limited to 1 guild per request but the number of guilds we request is significantly reduced. |
|||
|
|||
The second solution is to disable member chunking by setting ``chunk_guilds_at_startup`` to ``False`` when constructing a client. Then, when chunking for a guild is necessary you can use the various techniques to :ref:`retrieve members <retrieving_members>`. |
|||
|
|||
To illustrate the slowdown caused by the API change, take a bot who is in 840 guilds and 95 of these guilds are "large" (over 250 members). |
|||
|
|||
Under the original system this would result in 2 requests to fetch the member list (75 guilds, 20 guilds) roughly taking 60 seconds. With :attr:`Intents.members` but not :attr:`Intents.presences` this requires 840 requests, with a rate limit of 120 requests per 60 seconds means that due to waiting for the rate limit it totals to around 7 minutes of waiting for the rate limit to fetch all the members. With both :attr:`Intents.members` and :attr:`Intents.presences` we mostly get the old behaviour so we're only required to request for the 95 guilds that are large, this is slightly less than our rate limit so it's close to the original timing to fetch the member list. |
|||
|
|||
Unfortunately due to this change being required from Discord there is nothing that the library can do to mitigate this. |
|||
|
|||
If you truly dislike the direction Discord is going with their API, you can contact them via `support <https://dis.gd/contact>`_. |
@ -1,322 +0,0 @@ |
|||
:orphan: |
|||
|
|||
.. currentmodule:: discord |
|||
|
|||
.. _migrating-to-async: |
|||
|
|||
Migrating to v0.10.0 |
|||
====================== |
|||
|
|||
v0.10.0 is one of the biggest breaking changes in the library due to massive |
|||
fundamental changes in how the library operates. |
|||
|
|||
The biggest major change is that the library has dropped support to all versions prior to |
|||
Python 3.4.2. This was made to support :mod:`asyncio`, in which more detail can be seen |
|||
:issue:`in the corresponding issue <50>`. To reiterate this, the implication is that |
|||
**python version 2.7 and 3.3 are no longer supported**. |
|||
|
|||
Below are all the other major changes from v0.9.0 to v0.10.0. |
|||
|
|||
Event Registration |
|||
-------------------- |
|||
|
|||
All events before were registered using :meth:`Client.event`. While this is still |
|||
possible, the events must be decorated with ``@asyncio.coroutine``. |
|||
|
|||
Before: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
@client.event |
|||
def on_message(message): |
|||
pass |
|||
|
|||
After: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
@client.event |
|||
@asyncio.coroutine |
|||
def on_message(message): |
|||
pass |
|||
|
|||
Or in Python 3.5+: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
@client.event |
|||
async def on_message(message): |
|||
pass |
|||
|
|||
Because there is a lot of typing, a utility decorator (:meth:`Client.async_event`) is provided |
|||
for easier registration. For example: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
@client.async_event |
|||
def on_message(message): |
|||
pass |
|||
|
|||
|
|||
Be aware however, that this is still a coroutine and your other functions that are coroutines must |
|||
be decorated with ``@asyncio.coroutine`` or be ``async def``. |
|||
|
|||
Event Changes |
|||
-------------- |
|||
|
|||
Some events in v0.9.0 were considered pretty useless due to having no separate states. The main |
|||
events that were changed were the ``_update`` events since previously they had no context on what |
|||
was changed. |
|||
|
|||
Before: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
def on_channel_update(channel): pass |
|||
def on_member_update(member): pass |
|||
def on_status(member): pass |
|||
def on_server_role_update(role): pass |
|||
def on_voice_state_update(member): pass |
|||
def on_socket_raw_send(payload, is_binary): pass |
|||
|
|||
|
|||
After: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
def on_channel_update(before, after): pass |
|||
def on_member_update(before, after): pass |
|||
def on_server_role_update(before, after): pass |
|||
def on_voice_state_update(before, after): pass |
|||
def on_socket_raw_send(payload): pass |
|||
|
|||
Note that ``on_status`` was removed. If you want its functionality, use :func:`on_member_update`. |
|||
See :ref:`discord-api-events` for more information. Other removed events include ``on_socket_closed``, ``on_socket_receive``, and ``on_socket_opened``. |
|||
|
|||
|
|||
Coroutines |
|||
----------- |
|||
|
|||
The biggest change that the library went through is that almost every function in :class:`Client` |
|||
was changed to be a `coroutine <py:library/asyncio-task.html>`_. Functions |
|||
that are marked as a coroutine in the documentation must be awaited from or yielded from in order |
|||
for the computation to be done. For example... |
|||
|
|||
Before: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
client.send_message(message.channel, 'Hello') |
|||
|
|||
After: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
yield from client.send_message(message.channel, 'Hello') |
|||
|
|||
# or in python 3.5+ |
|||
await client.send_message(message.channel, 'Hello') |
|||
|
|||
In order for you to ``yield from`` or ``await`` a coroutine then your function must be decorated |
|||
with ``@asyncio.coroutine`` or ``async def``. |
|||
|
|||
Iterables |
|||
---------- |
|||
|
|||
For performance reasons, many of the internal data structures were changed into a dictionary to support faster |
|||
lookup. As a consequence, this meant that some lists that were exposed via the API have changed into iterables |
|||
and not sequences. In short, this means that certain attributes now only support iteration and not any of the |
|||
sequence functions. |
|||
|
|||
The affected attributes are as follows: |
|||
|
|||
- :attr:`Client.servers` |
|||
- :attr:`Client.private_channels` |
|||
- :attr:`Server.channels` |
|||
- :attr:`Server.members` |
|||
|
|||
Some examples of previously valid behaviour that is now invalid |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
if client.servers[0].name == "test": |
|||
# do something |
|||
|
|||
Since they are no longer :obj:`list`\s, they no longer support indexing or any operation other than iterating. |
|||
In order to get the old behaviour you should explicitly cast it to a list. |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
servers = list(client.servers) |
|||
# work with servers |
|||
|
|||
.. warning:: |
|||
|
|||
Due to internal changes of the structure, the order you receive the data in |
|||
is not in a guaranteed order. |
|||
|
|||
Enumerations |
|||
------------ |
|||
|
|||
Due to dropping support for versions lower than Python 3.4.2, the library can now use |
|||
:doc:`py:library/enum` in places where it makes sense. |
|||
|
|||
The common places where this was changed was in the server region, member status, and channel type. |
|||
|
|||
Before: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
server.region == 'us-west' |
|||
member.status == 'online' |
|||
channel.type == 'text' |
|||
|
|||
After: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
server.region == discord.ServerRegion.us_west |
|||
member.status = discord.Status.online |
|||
channel.type == discord.ChannelType.text |
|||
|
|||
The main reason for this change was to reduce the use of finicky strings in the API as this |
|||
could give users a false sense of power. More information can be found in the :ref:`discord-api-enums` page. |
|||
|
|||
Properties |
|||
----------- |
|||
|
|||
A lot of function calls that returned constant values were changed into Python properties for ease of use |
|||
in format strings. |
|||
|
|||
The following functions were changed into properties: |
|||
|
|||
+----------------------------------------+--------------------------------------+ |
|||
| Before | After | |
|||
+----------------------------------------+--------------------------------------+ |
|||
| ``User.avatar_url()`` | :attr:`User.avatar_url` | |
|||
+----------------------------------------+--------------------------------------+ |
|||
| ``User.mention()`` | :attr:`User.mention` | |
|||
+----------------------------------------+--------------------------------------+ |
|||
| ``Channel.mention()`` | :attr:`Channel.mention` | |
|||
+----------------------------------------+--------------------------------------+ |
|||
| ``Channel.is_default_channel()`` | :attr:`Channel.is_default` | |
|||
+----------------------------------------+--------------------------------------+ |
|||
| ``Role.is_everyone()`` | :attr:`Role.is_everyone` | |
|||
+----------------------------------------+--------------------------------------+ |
|||
| ``Server.get_default_role()`` | :attr:`Server.default_role` | |
|||
+----------------------------------------+--------------------------------------+ |
|||
| ``Server.icon_url()`` | :attr:`Server.icon_url` | |
|||
+----------------------------------------+--------------------------------------+ |
|||
| ``Server.get_default_channel()`` | :attr:`Server.default_channel` | |
|||
+----------------------------------------+--------------------------------------+ |
|||
| ``Message.get_raw_mentions()`` | :attr:`Message.raw_mentions` | |
|||
+----------------------------------------+--------------------------------------+ |
|||
| ``Message.get_raw_channel_mentions()`` | :attr:`Message.raw_channel_mentions` | |
|||
+----------------------------------------+--------------------------------------+ |
|||
|
|||
Member Management |
|||
------------------- |
|||
|
|||
Functions that involved banning and kicking were changed. |
|||
|
|||
+--------------------------------+--------------------------+ |
|||
| Before | After | |
|||
+--------------------------------+--------------------------+ |
|||
| ``Client.ban(server, user)`` | ``Client.ban(member)`` | |
|||
+--------------------------------+--------------------------+ |
|||
| ``Client.kick(server, user)`` | ``Client.kick(member)`` | |
|||
+--------------------------------+--------------------------+ |
|||
|
|||
.. migrating-renames: |
|||
|
|||
Renamed Functions |
|||
------------------- |
|||
|
|||
Functions have been renamed. |
|||
|
|||
+------------------------------------+-------------------------------------------+ |
|||
| Before | After | |
|||
+------------------------------------+-------------------------------------------+ |
|||
| ``Client.set_channel_permissions`` | :meth:`Client.edit_channel_permissions` | |
|||
+------------------------------------+-------------------------------------------+ |
|||
|
|||
All the :class:`Permissions` related attributes have been renamed and the `can_` prefix has been |
|||
dropped. So for example, ``can_manage_messages`` has become ``manage_messages``. |
|||
|
|||
Forced Keyword Arguments |
|||
------------------------- |
|||
|
|||
Since 3.0+ of Python, we can now force questions to take in forced keyword arguments. A keyword argument is when you |
|||
explicitly specify the name of the variable and assign to it, for example: ``foo(name='test')``. Due to this support, |
|||
some functions in the library were changed to force things to take said keyword arguments. This is to reduce errors of |
|||
knowing the argument order and the issues that could arise from them. |
|||
|
|||
The following parameters are now exclusively keyword arguments: |
|||
|
|||
- :meth:`Client.send_message` |
|||
- ``tts`` |
|||
- :meth:`Client.logs_from` |
|||
- ``before`` |
|||
- ``after`` |
|||
- :meth:`Client.edit_channel_permissions` |
|||
- ``allow`` |
|||
- ``deny`` |
|||
|
|||
In the documentation you can tell if a function parameter is a forced keyword argument if it is after ``\*,`` |
|||
in the function signature. |
|||
|
|||
.. _migrating-running: |
|||
|
|||
Running the Client |
|||
-------------------- |
|||
|
|||
In earlier versions of discord.py, ``client.run()`` was a blocking call to the main thread |
|||
that called it. In v0.10.0 it is still a blocking call but it handles the event loop for you. |
|||
However, in order to do that you must pass in your credentials to :meth:`Client.run`. |
|||
|
|||
Basically, before: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
client.login('token') |
|||
client.run() |
|||
|
|||
After: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
client.run('token') |
|||
|
|||
.. warning:: |
|||
|
|||
Like in the older ``Client.run`` function, the newer one must be the one of |
|||
the last functions to call. This is because the function is **blocking**. Registering |
|||
events or doing anything after :meth:`Client.run` will not execute until the function |
|||
returns. |
|||
|
|||
This is a utility function that abstracts the event loop for you. There's no need for |
|||
the run call to be blocking and out of your control. Indeed, if you want control of the |
|||
event loop then doing so is quite straightforward: |
|||
|
|||
.. code-block:: python3 |
|||
|
|||
import discord |
|||
import asyncio |
|||
|
|||
client = discord.Client() |
|||
|
|||
@asyncio.coroutine |
|||
def main_task(): |
|||
yield from client.login('token') |
|||
yield from client.connect() |
|||
|
|||
loop = asyncio.get_event_loop() |
|||
try: |
|||
loop.run_until_complete(main_task()) |
|||
except: |
|||
loop.run_until_complete(client.logout()) |
|||
finally: |
|||
loop.close() |
|||
|
|||
|
|||
|
@ -0,0 +1,24 @@ |
|||
:orphan: |
|||
|
|||
.. versionadded:: 2.0 |
|||
.. _tokens: |
|||
|
|||
Tokens |
|||
======= |
|||
|
|||
Tokens are how we authenticate with Discord. |
|||
|
|||
Regular (and bot) tokens have this format: |
|||
|
|||
.. image:: /images/token.png |
|||
|
|||
MFA tokens, however, are just the HMAC prefixed with `mfa.` (as far as I know). |
|||
|
|||
How to obtain mine |
|||
------------------- |
|||
To obtain your token from the Discord client, the easiest way is as follows: |
|||
1. Open developer tools (CTRL+SHIFT+I). |
|||
2. Click the Network tab. |
|||
3. Click the XHR tab. |
|||
4. Select a request and click the Headers tab. |
|||
5. Copy-paste the value in the Authorization header. |