First pass at documentation reform.
40
docs/_static/style.css
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
body {
|
||||
font-family: Georgia, 'Hiragino Mincho Pro', serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
code.descname, code.descclassname {
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
code.descname {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
pre, * pre {
|
||||
padding: 7px 0 7px 30px !important;
|
||||
margin: 15px 0 !important;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
div.warning {
|
||||
background-color: #ffe6cc;
|
||||
border: 1px solid #ffd5aa;
|
||||
}
|
||||
|
||||
/* don't link-ify the FAQ page */
|
||||
a.toc-backref {
|
||||
text-decoration: none;
|
||||
color: #3E4349;
|
||||
}
|
||||
|
||||
code.xref {
|
||||
background-color: #ecf0f3;
|
||||
border-bottom: 1px dotted #222;
|
||||
}
|
||||
415
docs/api.rst
@@ -79,21 +79,22 @@ overriding the specific events. For example: ::
|
||||
import discord
|
||||
|
||||
class MyClient(discord.Client):
|
||||
async def on_message(self, message):
|
||||
if message.author != self.user:
|
||||
return
|
||||
|
||||
@asyncio.coroutine
|
||||
def on_message(self, message):
|
||||
yield from self.send_message(message.channel, 'Hello World!')
|
||||
if message.content.startswith('$hello'):
|
||||
await message.channel.send('Hello World!')
|
||||
|
||||
|
||||
If an event handler raises an exception, :func:`on_error` will be called
|
||||
to handle it, which defaults to print a traceback and ignore the exception.
|
||||
to handle it, which defaults to print a traceback and ignoring the exception.
|
||||
|
||||
.. warning::
|
||||
|
||||
All the events must be a |corourl|_. If they aren't, then you might get unexpected
|
||||
errors. In order to turn a function into a coroutine they must either be decorated
|
||||
with ``@asyncio.coroutine`` or in Python 3.5+ be defined using the ``async def``
|
||||
declaration.
|
||||
errors. In order to turn a function into a coroutine they must either be ``async def``
|
||||
functions or in 3.4 decorated with ``@asyncio.coroutine``.
|
||||
|
||||
The following two functions are examples of coroutine functions: ::
|
||||
|
||||
@@ -104,14 +105,6 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
||||
def on_ready():
|
||||
pass
|
||||
|
||||
Since this can be a potentially common mistake, there is a helper
|
||||
decorator, :meth:`Client.async_event` to convert a basic function
|
||||
into a coroutine and an event at the same time. Note that it is
|
||||
not necessary if you use ``async def``.
|
||||
|
||||
.. versionadded:: 0.7.0
|
||||
Subclassing to listen to events.
|
||||
|
||||
.. function:: on_connect()
|
||||
|
||||
Called when the client has successfully connected to Discord. This is not
|
||||
@@ -164,48 +157,71 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
||||
:param kwargs: The keyword arguments for the event that raised the
|
||||
execption.
|
||||
|
||||
.. function:: on_message(message)
|
||||
|
||||
Called when a message is created and sent to a guild.
|
||||
|
||||
:param message: A :class:`Message` of the current message.
|
||||
|
||||
.. function:: on_socket_raw_receive(msg)
|
||||
|
||||
Called whenever a message is received from the websocket, before
|
||||
it's processed.This event is always dispatched when a message is
|
||||
Called whenever a message is received from the WebSocket, before
|
||||
it's processed. This event is always dispatched when a message is
|
||||
received and the passed data is not processed in any way.
|
||||
|
||||
This is only really useful for grabbing the websocket stream and
|
||||
This is only really useful for grabbing the WebSocket stream and
|
||||
debugging purposes.
|
||||
|
||||
.. note::
|
||||
|
||||
This is only for the messages received from the client
|
||||
websocket. The voice websocket will not trigger this event.
|
||||
WebSocket. The voice WebSocket will not trigger this event.
|
||||
|
||||
:param msg: The message passed in from the websocket library.
|
||||
:param msg: The message passed in from the WebSocket library.
|
||||
Could be ``bytes`` for a binary message or ``str``
|
||||
for a regular message.
|
||||
|
||||
.. function:: on_socket_raw_send(payload)
|
||||
|
||||
Called whenever a send operation is done on the websocket before the
|
||||
message is sent. The passed parameter is the message that is to
|
||||
sent to the websocket.
|
||||
Called whenever a send operation is done on the WebSocket before the
|
||||
message is sent. The passed parameter is the message that is being
|
||||
sent to the WebSocket.
|
||||
|
||||
This is only really useful for grabbing the websocket stream and
|
||||
This is only really useful for grabbing the WebSocket stream and
|
||||
debugging purposes.
|
||||
|
||||
.. note::
|
||||
|
||||
This is only for the messages received from the client
|
||||
websocket. The voice websocket will not trigger this event.
|
||||
WebSocket. The voice WebSocket will not trigger this event.
|
||||
|
||||
:param payload: The message that is about to be passed on to the
|
||||
websocket library. It can be ``bytes`` to denote a binary
|
||||
WebSocket library. It can be ``bytes`` to denote a binary
|
||||
message or ``str`` to denote a regular text message.
|
||||
|
||||
.. function:: on_typing(channel, user, when)
|
||||
|
||||
Called when someone begins typing a message.
|
||||
|
||||
The ``channel`` parameter can be a :class:`abc.Messageable` instance.
|
||||
Which could either be :class:`TextChannel`, :class:`GroupChannel`, or
|
||||
:class:`DMChannel`.
|
||||
|
||||
If the ``channel`` is a :class:`TextChannel` then the ``user`` parameter
|
||||
is a :class:`Member`, otherwise it is a :class:`User`.
|
||||
|
||||
:param channel: The location where the typing originated from.
|
||||
:param user: The user that started typing.
|
||||
:param when: A ``datetime.datetime`` object representing when typing started.
|
||||
|
||||
.. function:: on_message(message)
|
||||
|
||||
Called when a :class:`Message` is created and sent.
|
||||
|
||||
.. warning::
|
||||
|
||||
Your bot's own messages and private messages are sent through this
|
||||
event. This can lead cases of 'recursion' depending on how your bot was
|
||||
programmed. If you want the bot to not reply to itself, consider
|
||||
checking the user IDs. Note that :class:`~ext.commands.Bot` does not
|
||||
have this problem.
|
||||
|
||||
:param message: A :class:`Message` of the current message.
|
||||
|
||||
.. function:: on_message_delete(message)
|
||||
|
||||
Called when a message is deleted. If the message is not found in the
|
||||
@@ -218,7 +234,7 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
||||
|
||||
.. function:: on_message_edit(before, after)
|
||||
|
||||
Called when a message receives an update event. If the message is not found
|
||||
Called when a :class:`Message` receives an update event. If the message is not found
|
||||
in the :attr:`Client.messages` cache, then these events will not be called.
|
||||
This happens if the message is too old or the client is participating in high
|
||||
traffic guilds. To fix this, increase the ``max_messages`` option of :class:`Client`.
|
||||
@@ -228,7 +244,9 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
||||
- A message has been pinned or unpinned.
|
||||
- The message content has been changed.
|
||||
- The message has received an embed.
|
||||
- For performance reasons, the embed guild does not do this in a "consistent" manner.
|
||||
|
||||
- For performance reasons, the embed server does not do this in a "consistent" manner.
|
||||
|
||||
- A call message has received an update to its participants or ending time.
|
||||
|
||||
:param before: A :class:`Message` of the previous version of the message.
|
||||
@@ -242,7 +260,7 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
||||
|
||||
.. note::
|
||||
|
||||
To get the message being reacted, access it via :attr:`Reaction.message`.
|
||||
To get the :class:`Message` being reacted, access it via :attr:`Reaction.message`.
|
||||
|
||||
:param reaction: A :class:`Reaction` showing the current state of the reaction.
|
||||
:param user: A :class:`User` or :class:`Member` of the user who added the reaction.
|
||||
@@ -269,31 +287,51 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
||||
:param message: The :class:`Message` that had its reactions cleared.
|
||||
:param reactions: A list of :class:`Reaction`\s that were removed.
|
||||
|
||||
.. function:: on_channel_delete(channel)
|
||||
on_channel_create(channel)
|
||||
.. function:: on_private_channel_delete(channel)
|
||||
on_private_channel_create(channel)
|
||||
|
||||
Called whenever a channel is removed or added from a guild.
|
||||
Called whenever a private channel is deleted or created.
|
||||
|
||||
Note that you can get the guild from :attr:`Channel.guild`.
|
||||
:func:`on_channel_create` could also pass in a :class:`PrivateChannel` depending
|
||||
on the value of :attr:`Channel.is_private`.
|
||||
:param channel: The :class:`abc.PrivateChannel` that got created or deleted.
|
||||
|
||||
:param channel: The :class:`Channel` that got added or deleted.
|
||||
.. function:: on_private_channel_update(before, after)
|
||||
|
||||
.. function:: on_channel_update(before, after)
|
||||
Called whenever a private group DM is updated. e.g. changed name or topic.
|
||||
|
||||
Called whenever a channel is updated. e.g. changed name, topic, permissions.
|
||||
:param before: The :class:`GroupChannel` that got updated with the old info.
|
||||
:param after: The :class:`GroupChannel` that got updated with the updated info.
|
||||
|
||||
:param before: The :class:`Channel` that got updated with the old info.
|
||||
:param after: The :class:`Channel` that got updated with the updated info.
|
||||
.. function:: on_private_channel_pins_update(channel, last_pin)
|
||||
|
||||
.. function:: on_channel_pins_update(channel, last_pin)
|
||||
Called whenever a message is pinned or unpinned from a private channel.
|
||||
|
||||
Called whenever a message is pinned or unpinned from a channel.
|
||||
|
||||
:param channel: The :class:`Channel` that had it's pins updated.
|
||||
:param channel: The :class:`abc.PrivateChannel` that had it's pins updated.
|
||||
:param last_pin: A ``datetime.datetime`` object representing when the latest message
|
||||
was pinned or ``None`` if there are no pins.
|
||||
was pinned or ``None`` if there are no pins.
|
||||
|
||||
.. function:: on_guild_channel_delete(channel)
|
||||
on_guild_channel_create(channel)
|
||||
|
||||
Called whenever a guild channel is deleted or created.
|
||||
|
||||
Note that you can get the guild from :attr:`~abc.GuildChannel.guild`.
|
||||
|
||||
:param channel: The :class:`abc.GuildChannel` that got created or deleted.
|
||||
|
||||
.. function:: on_guild_channel_update(before, after)
|
||||
|
||||
Called whenever a guild channel is updated. e.g. changed name, topic, permissions.
|
||||
|
||||
:param before: The :class:`abc.GuildChannel` that got updated with the old info.
|
||||
:param after: The :class:`abc.GuildChannel` that got updated with the updated info.
|
||||
|
||||
.. function:: on_guild_channel_pins_update(channel, last_pin)
|
||||
|
||||
Called whenever a message is pinned or unpinned from a guild channel.
|
||||
|
||||
:param channel: The :class:`abc.GuildChannel` that had it's pins updated.
|
||||
:param last_pin: A ``datetime.datetime`` object representing when the latest message
|
||||
was pinned or ``None`` if there are no pins.
|
||||
|
||||
.. function:: on_member_join(member)
|
||||
on_member_remove(member)
|
||||
@@ -368,10 +406,11 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
||||
:param before: The :class:`Role` that updated with the old info.
|
||||
:param after: The :class:`Role` that updated with the updated info.
|
||||
|
||||
.. function:: on_guild_emojis_update(before, after)
|
||||
.. function:: on_guild_emojis_update(guild, before, after)
|
||||
|
||||
Called when a :class:`Guild` adds or removes :class:`Emoji`.
|
||||
|
||||
:param guild: The :class:`Guild` who got their emojis updated.
|
||||
:param before: A list of :class:`Emoji` before the update.
|
||||
:param after: A list of :class:`Emoji` after the update.
|
||||
|
||||
@@ -383,9 +422,9 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
||||
|
||||
:param guild: The :class:`Guild` that has changed availability.
|
||||
|
||||
.. function:: on_voice_state_update(before, after)
|
||||
.. function:: on_voice_state_update(member, before, after)
|
||||
|
||||
Called when a :class:`Member` changes their voice state.
|
||||
Called when a :class:`Member` changes their :class:`VoiceState`.
|
||||
|
||||
The following, but not limited to, examples illustrate when this event is called:
|
||||
|
||||
@@ -394,35 +433,25 @@ to handle it, which defaults to print a traceback and ignore the exception.
|
||||
- A member is muted or deafened by their own accord.
|
||||
- A member is muted or deafened by a guild administrator.
|
||||
|
||||
:param before: The :class:`Member` whose voice state changed prior to the changes.
|
||||
:param after: The :class:`Member` whose voice state changed after the changes.
|
||||
:param member: The :class:`Member` whose voice states changed.
|
||||
:param before: The :class:`VoiceState` prior to the changes.
|
||||
:param after: The :class:`VoiceState` after to the changes.
|
||||
|
||||
.. function:: on_member_ban(member)
|
||||
.. function:: on_member_ban(guild, user)
|
||||
|
||||
Called when a :class:`Member` gets banned from a :class:`Guild`.
|
||||
Called when user gets banned from a :class:`Guild`.
|
||||
|
||||
You can access the guild that the member got banned from via :attr:`Member.guild`.
|
||||
|
||||
:param member: The member that got banned.
|
||||
:param guild: The :class:`Guild` the user got banned from.
|
||||
:param user: The user that got banned.
|
||||
Can be either :class:`User` or :class:`Member` depending if
|
||||
the user was in the guild or not at the time of removal.
|
||||
|
||||
.. function:: on_member_unban(guild, user)
|
||||
|
||||
Called when a :class:`User` gets unbanned from a :class:`Guild`.
|
||||
|
||||
:param guild: The guild the user got unbanned from.
|
||||
:param user: The user that got unbanned.
|
||||
|
||||
.. function:: on_typing(channel, user, when)
|
||||
|
||||
Called when someone begins typing a message.
|
||||
|
||||
The ``channel`` parameter could either be a :class:`PrivateChannel` or a
|
||||
:class:`Channel`. If ``channel`` is a :class:`PrivateChannel` then the
|
||||
``user`` parameter is a :class:`User`, otherwise it is a :class:`Member`.
|
||||
|
||||
:param channel: The location where the typing originated from.
|
||||
:param user: The user that started typing.
|
||||
:param when: A ``datetime.datetime`` object representing when typing started.
|
||||
:param guild: The :class:`Guild` the user got unbanned from.
|
||||
:param user: The :class:`User` that got unbanned.
|
||||
|
||||
.. function:: on_group_join(channel, user)
|
||||
on_group_remove(channel, user)
|
||||
@@ -1281,15 +1310,15 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
||||
|
||||
.. attribute:: owner
|
||||
|
||||
*Union[:class:`Member`, :class:`User`]`* – The guild's owner. See also :attr:`Guild.owner`
|
||||
Union[:class:`Member`, :class:`User`] – The guild's owner. See also :attr:`Guild.owner`
|
||||
|
||||
.. attribute:: region
|
||||
|
||||
*:class:`GuildRegion`* – The guild's voice region. See also :attr:`Guild.region`.
|
||||
:class:`GuildRegion` – The guild's voice region. See also :attr:`Guild.region`.
|
||||
|
||||
.. attribute:: afk_channel
|
||||
|
||||
*Union[:class:`VoiceChannel`, :class:`Object`]* – The guild's AFK channel.
|
||||
Union[:class:`VoiceChannel`, :class:`Object`] – The guild's AFK channel.
|
||||
|
||||
If this could not be found, then it falls back to a :class:`Object`
|
||||
with the ID being set.
|
||||
@@ -1310,20 +1339,20 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
||||
|
||||
.. attribute:: widget_channel
|
||||
|
||||
*Union[:class:`TextChannel`, :class:`Object`]* – The widget's channel.
|
||||
Union[:class:`TextChannel`, :class:`Object`] – The widget's channel.
|
||||
|
||||
If this could not be found then it falls back to a :class:`Object`
|
||||
with the ID being set.
|
||||
|
||||
.. attribute:: verification_level
|
||||
|
||||
*:class:`VerificationLevel`* – The guild's verification level.
|
||||
:class:`VerificationLevel` – The guild's verification level.
|
||||
|
||||
See also :attr:`Guild.verification_level`.
|
||||
|
||||
.. attribute:: explicit_content_filter
|
||||
|
||||
*:class:`ContentFilter`* – The guild's content filter.
|
||||
:class:`ContentFilter` – The guild's content filter.
|
||||
|
||||
See also :attr:`Guild.explicit_content_filter`.
|
||||
|
||||
@@ -1365,7 +1394,7 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
||||
|
||||
.. attribute:: overwrites
|
||||
|
||||
*List[Tuple[target, :class:`PermissionOverwrite`]]* – A list of
|
||||
List[Tuple[target, :class:`PermissionOverwrite`]] – A list of
|
||||
permission overwrite tuples that represents a target and a
|
||||
:class:`PermissionOverwrite` for said target.
|
||||
|
||||
@@ -1377,7 +1406,7 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
||||
|
||||
.. attribute:: roles
|
||||
|
||||
*List[Union[:class:`Role`, :class:`Object`]]* – A list of roles being added or removed
|
||||
List[Union[:class:`Role`, :class:`Object`]] – A list of roles being added or removed
|
||||
from a member.
|
||||
|
||||
If a role is not found then it is a :class:`Object` with the ID and name being
|
||||
@@ -1403,14 +1432,14 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
||||
|
||||
.. attribute:: permissions
|
||||
|
||||
*:class:`Permissions`* – The permissions of a role.
|
||||
:class:`Permissions` – The permissions of a role.
|
||||
|
||||
See also :attr:`Role.permissions`.
|
||||
|
||||
.. attribute:: colour
|
||||
color
|
||||
|
||||
*:class:`Colour`* – The colour of a role.
|
||||
:class:`Colour` – The colour of a role.
|
||||
|
||||
See also :attr:`Role.colour`
|
||||
|
||||
@@ -1434,14 +1463,14 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
||||
|
||||
.. attribute:: channel
|
||||
|
||||
*Union[:class:`abc.GuildChannel`, :class:`Object`]* – A guild channel.
|
||||
Union[:class:`abc.GuildChannel`, :class:`Object`] – A guild channel.
|
||||
|
||||
If the channel is not found then it is a :class:`Object` with the ID
|
||||
being set. In some cases the channel name is also set.
|
||||
|
||||
.. attribute:: inviter
|
||||
|
||||
*:class:`User`* – The user who created the invite.
|
||||
:class:`User` – The user who created the invite.
|
||||
|
||||
See also :attr:`Invite.inviter`.
|
||||
|
||||
@@ -1472,7 +1501,7 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
||||
.. attribute:: allow
|
||||
deny
|
||||
|
||||
*:class:`Permissions`* – The permissions being allowed or denied.
|
||||
:class:`Permissions` – The permissions being allowed or denied.
|
||||
|
||||
.. attribute:: id
|
||||
|
||||
@@ -1487,43 +1516,72 @@ this goal, it must make use of a couple of data classes that aid in this goal.
|
||||
.. this is currently missing the following keys: reason and application_id
|
||||
I'm not sure how to about porting these
|
||||
|
||||
.. _discord_api_data:
|
||||
.. _discord_api_abcs:
|
||||
|
||||
Data Classes
|
||||
--------------
|
||||
Abstract Base Classes
|
||||
-----------------------
|
||||
|
||||
Some classes are just there to be data containers, this lists them.
|
||||
An abstract base class (also known as an ``abc``) is a class that models can inherit
|
||||
to get their behaviour. The Python implementation of an `abc <https://docs.python.org/3/library/abc.html>`_ is
|
||||
slightly different in that you can register them at run-time. **Abstract base classes cannot be instantiated**.
|
||||
They are mainly there for usage with ``isinstance`` and ``issubclass``\.
|
||||
|
||||
.. note::
|
||||
This library has a module related to abstract base classes, some of which are actually from the ``abc`` standard
|
||||
module, others which are not.
|
||||
|
||||
With the exception of :class:`Object`, :class:`Colour`, and :class:`Permissions` the
|
||||
data classes listed below are **not intended to be created by users** and are also
|
||||
.. autoclass:: discord.abc.Snowflake
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.abc.User
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.abc.PrivateChannel
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.abc.GuildChannel
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.abc.Messageable
|
||||
:members:
|
||||
:exclude-members: history typing
|
||||
|
||||
.. autocomethod:: discord.abc.Messageable.history
|
||||
:async-for:
|
||||
|
||||
.. autocomethod:: discord.abc.Messageable.typing
|
||||
:async-with:
|
||||
|
||||
.. autoclass:: discord.abc.Connectable
|
||||
|
||||
.. _discord_api_models:
|
||||
|
||||
Discord Models
|
||||
---------------
|
||||
|
||||
Models are classes that are received from Discord and are not meant to be created by
|
||||
the user of the library.
|
||||
|
||||
.. danger::
|
||||
|
||||
The classes listed below are **not intended to be created by users** and are also
|
||||
**read-only**.
|
||||
|
||||
For example, this means that you should not make your own :class:`User` instances
|
||||
nor should you modify the :class:`User` instance yourself.
|
||||
|
||||
If you want to get one of these data classes instances they'd have to be through
|
||||
If you want to get one of these model classes instances they'd have to be through
|
||||
the cache, and a common way of doing so is through the :func:`utils.find` function
|
||||
or attributes of data classes that you receive from the events specified in the
|
||||
or attributes of model classes that you receive from the events specified in the
|
||||
:ref:`discord-api-events`.
|
||||
|
||||
.. note::
|
||||
|
||||
.. warning::
|
||||
|
||||
Nearly all data classes here have ``__slots__`` defined which means that it is
|
||||
impossible to have dynamic attributes to the data classes. The only exception
|
||||
to this rule is :class:`Object` which was designed with dynamic attributes in
|
||||
mind.
|
||||
Nearly all classes here have ``__slots__`` defined which means that it is
|
||||
impossible to have dynamic attributes to the data classes.
|
||||
|
||||
More information about ``__slots__`` can be found
|
||||
`in the official python documentation <https://docs.python.org/3/reference/datamodel.html#slots>`_.
|
||||
|
||||
Object
|
||||
~~~~~~~
|
||||
|
||||
.. autoclass:: Object
|
||||
:members:
|
||||
|
||||
ClientUser
|
||||
~~~~~~~~~~~~
|
||||
@@ -1544,6 +1602,13 @@ User
|
||||
.. autoclass:: User
|
||||
:members:
|
||||
:inherited-members:
|
||||
:exclude-members: history typing
|
||||
|
||||
.. autocomethod:: history
|
||||
:async-for:
|
||||
|
||||
.. autocomethod:: typing
|
||||
:async-with:
|
||||
|
||||
Message
|
||||
~~~~~~~
|
||||
@@ -1556,18 +1621,10 @@ Reaction
|
||||
|
||||
.. autoclass:: Reaction
|
||||
:members:
|
||||
:exclude-members: users
|
||||
|
||||
Embed
|
||||
~~~~~~
|
||||
|
||||
.. autoclass:: Embed
|
||||
:members:
|
||||
|
||||
File
|
||||
~~~~~
|
||||
|
||||
.. autoclass:: File
|
||||
:members:
|
||||
.. autocomethod:: users
|
||||
:async-for:
|
||||
|
||||
CallMessage
|
||||
~~~~~~~~~~~~
|
||||
@@ -1586,6 +1643,10 @@ Guild
|
||||
|
||||
.. autoclass:: Guild
|
||||
:members:
|
||||
:exclude-members: audit_logs
|
||||
|
||||
.. autocomethod:: audit_logs
|
||||
:async-for:
|
||||
|
||||
Member
|
||||
~~~~~~
|
||||
@@ -1593,6 +1654,13 @@ Member
|
||||
.. autoclass:: Member
|
||||
:members:
|
||||
:inherited-members:
|
||||
:exclude-members: history typing
|
||||
|
||||
.. autocomethod:: history
|
||||
:async-for:
|
||||
|
||||
.. autocomethod:: typing
|
||||
:async-with:
|
||||
|
||||
VoiceState
|
||||
~~~~~~~~~~~
|
||||
@@ -1600,18 +1668,6 @@ VoiceState
|
||||
.. autoclass:: VoiceState
|
||||
:members:
|
||||
|
||||
Colour
|
||||
~~~~~~
|
||||
|
||||
.. autoclass:: Colour
|
||||
:members:
|
||||
|
||||
Game
|
||||
~~~~
|
||||
|
||||
.. autoclass:: Game
|
||||
:members:
|
||||
|
||||
Emoji
|
||||
~~~~~
|
||||
|
||||
@@ -1624,25 +1680,19 @@ Role
|
||||
.. autoclass:: Role
|
||||
:members:
|
||||
|
||||
Permissions
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: Permissions
|
||||
:members:
|
||||
|
||||
PermissionOverwrite
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: PermissionOverwrite
|
||||
:members:
|
||||
|
||||
|
||||
TextChannel
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: TextChannel
|
||||
:members:
|
||||
:inherited-members:
|
||||
:exclude-members: history typing
|
||||
|
||||
.. autocomethod:: history
|
||||
:async-for:
|
||||
|
||||
.. autocomethod:: typing
|
||||
:async-with:
|
||||
|
||||
VoiceChannel
|
||||
~~~~~~~~~~~~~
|
||||
@@ -1657,6 +1707,13 @@ DMChannel
|
||||
.. autoclass:: DMChannel
|
||||
:members:
|
||||
:inherited-members:
|
||||
:exclude-members: history typing
|
||||
|
||||
.. autocomethod:: history
|
||||
:async-for:
|
||||
|
||||
.. autocomethod:: typing
|
||||
:async-with:
|
||||
|
||||
GroupChannel
|
||||
~~~~~~~~~~~~
|
||||
@@ -1664,6 +1721,13 @@ GroupChannel
|
||||
.. autoclass:: GroupChannel
|
||||
:members:
|
||||
:inherited-members:
|
||||
:exclude-members: history typing
|
||||
|
||||
.. autocomethod:: history
|
||||
:async-for:
|
||||
|
||||
.. autocomethod:: typing
|
||||
:async-with:
|
||||
|
||||
|
||||
Invite
|
||||
@@ -1672,6 +1736,69 @@ Invite
|
||||
.. autoclass:: Invite
|
||||
:members:
|
||||
|
||||
.. _discord_api_data:
|
||||
|
||||
Data Classes
|
||||
--------------
|
||||
|
||||
Some classes are just there to be data containers, this lists them.
|
||||
|
||||
Unlike :ref:`models <discord_api_models>` you are allowed to create
|
||||
these yourself, even if they can also be used to hold attributes.
|
||||
|
||||
Nearly all classes here have ``__slots__`` defined which means that it is
|
||||
impossible to have dynamic attributes to the data classes.
|
||||
|
||||
The only exception to this rule is :class:`Object`, which is made with
|
||||
dynamic attributes in mind.
|
||||
|
||||
More information about ``__slots__`` can be found
|
||||
`in the official python documentation <https://docs.python.org/3/reference/datamodel.html#slots>`_.
|
||||
|
||||
|
||||
Object
|
||||
~~~~~~~
|
||||
|
||||
.. autoclass:: Object
|
||||
:members:
|
||||
|
||||
Embed
|
||||
~~~~~~
|
||||
|
||||
.. autoclass:: Embed
|
||||
:members:
|
||||
|
||||
File
|
||||
~~~~~
|
||||
|
||||
.. autoclass:: File
|
||||
:members:
|
||||
|
||||
Colour
|
||||
~~~~~~
|
||||
|
||||
.. autoclass:: Colour
|
||||
:members:
|
||||
|
||||
Game
|
||||
~~~~
|
||||
|
||||
.. autoclass:: Game
|
||||
:members:
|
||||
|
||||
Permissions
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: Permissions
|
||||
:members:
|
||||
|
||||
PermissionOverwrite
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: PermissionOverwrite
|
||||
:members:
|
||||
|
||||
|
||||
Exceptions
|
||||
------------
|
||||
|
||||
|
||||
10
docs/conf.py
@@ -34,6 +34,7 @@ sys.path.insert(0, os.path.abspath('..'))
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.extlinks',
|
||||
'sphinxcontrib.asyncio'
|
||||
]
|
||||
|
||||
if on_rtd:
|
||||
@@ -115,7 +116,7 @@ exclude_patterns = ['_build']
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
pygments_style = 'friendly'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
@@ -128,7 +129,7 @@ pygments_style = 'sphinx'
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme = 'alabaster'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
@@ -159,7 +160,7 @@ html_theme = 'sphinx_rtd_theme'
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
# html_static_path = ['_static']
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
@@ -304,3 +305,6 @@ texinfo_documents = [
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
|
||||
def setup(app):
|
||||
app.add_stylesheet('style.css')
|
||||
|
||||
92
docs/discord.rst
Normal file
@@ -0,0 +1,92 @@
|
||||
.. _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://discordapp.com>`_.
|
||||
2. Navigate to the `application page <https://discordapp.com/developers/applications/me>`_
|
||||
3. Click on the "New App" button.
|
||||
|
||||
.. image:: /images/discord_new_app_button.png
|
||||
:alt: The new app button.
|
||||
|
||||
4. Give the application a name and a description if wanted and click "Create App".
|
||||
|
||||
- You can also put an avatar you want your bot to use, don't worry you can change this later.
|
||||
- **Leave the Redirect URI(s) blank** unless are creating a service.
|
||||
|
||||
.. image:: /images/discord_new_app_form.png
|
||||
:alt: The new application form filled in.
|
||||
5. Create a Bot User by clicking on the accompanying button and confirming it.
|
||||
|
||||
.. image:: /images/discord_create_bot_user_button.png
|
||||
:alt: The Create a Bot User 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**.
|
||||
|
||||
.. figure:: /images/discord_finished_bot_user.png
|
||||
|
||||
How the Bot User options should look like for most people.
|
||||
|
||||
7. Click to reveal the token.
|
||||
|
||||
- **This is not the Client Secret**
|
||||
|
||||
.. figure:: /images/discord_reveal_token.png
|
||||
|
||||
How the token reveal button looks like.
|
||||
|
||||
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 your bot.
|
||||
|
||||
First, you must fetch the Client ID of the Bot. You can find this in the Bot's application page.
|
||||
|
||||
.. image:: /images/discord_client_id.png
|
||||
:alt: The Bot's Client ID.
|
||||
|
||||
Copy paste that into the pre-formatted URL:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
https://discordapp.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&scope=bot&permissions=0
|
||||
|
||||
Replace ``YOUR_CLIENT_ID`` with the Client ID we got in the previous step. For example,
|
||||
in the image above our client ID is 312718641634213889 so the resulting URL would be
|
||||
https://discordapp.com/oauth2/authorize?client_id=312718641634213889&scope=bot&permissions=0
|
||||
(note that this bot has been deleted).
|
||||
|
||||
Now you can click the link and invite your bot to any server you have "Manage Server" permissions on.
|
||||
|
||||
Adding Permissions
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the above URL, you might have noticed an interesting bit, the ``permissions=0`` fragment.
|
||||
|
||||
Bot accounts can request specific permissions to be granted upon joining. When the bot joins
|
||||
the guild, they will be granted a managed role that contains the permissions you requested.
|
||||
If the permissions is 0, then no special role is created.
|
||||
|
||||
This ``permissions`` value is calculated based on bit-wise arithmetic. Thankfully, people have
|
||||
created a calculate that makes it easy to calculate the permissions necessary visually.
|
||||
|
||||
- https://discordapi.com/permissions.html
|
||||
- https://finitereality.github.io/permissions/
|
||||
|
||||
Feel free to use whichever is easier for you to grasp.
|
||||
|
||||
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`.
|
||||
197
docs/ext/commands/api.rst
Normal file
@@ -0,0 +1,197 @@
|
||||
.. currentmodule:: discord
|
||||
|
||||
API Reference
|
||||
===============
|
||||
|
||||
The following section outlines the API of discord.py's command extension module.
|
||||
|
||||
Bot
|
||||
----
|
||||
|
||||
.. autoclass:: discord.ext.commands.Bot
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.AutoShardedBot
|
||||
:members:
|
||||
|
||||
Event Reference
|
||||
-----------------
|
||||
|
||||
These events function similar to :ref:`the regular events <discord-api-events>`, except they
|
||||
are custom to the command extension module.
|
||||
|
||||
.. function:: on_command_error(ctx, error)
|
||||
|
||||
An error handler that is called when an error is raised
|
||||
inside a command either through user input error, check
|
||||
failure, or an error in your own code.
|
||||
|
||||
A default one is provided (:meth:`.Bot.on_command_error`).
|
||||
|
||||
:param ctx: The invocation context.
|
||||
:type ctx: :class:`Context`
|
||||
:param error: The error that was raised.
|
||||
:type error: :class:`CommandError` derived
|
||||
|
||||
.. function:: on_command(ctx)
|
||||
|
||||
An event that is called when a command is found and is about to be invoked.
|
||||
|
||||
This event is called regardless of whether the command itself succeeds via
|
||||
error or completes.
|
||||
|
||||
:param ctx: The invocation context.
|
||||
:type ctx: :class:`Context`
|
||||
|
||||
.. function:: on_command_completion(ctx)
|
||||
|
||||
An event that is called when a command has completed its invocation.
|
||||
|
||||
This event is called only if the command succeeded, i.e. all checks have
|
||||
passed and the user input it correctly.
|
||||
|
||||
:param ctx: The invocation context.
|
||||
:type ctx: :class:`Context`
|
||||
|
||||
|
||||
Command
|
||||
--------
|
||||
|
||||
.. autofunction:: discord.ext.commands.command
|
||||
|
||||
.. autofunction:: discord.ext.commands.group
|
||||
|
||||
.. autoclass:: discord.ext.commands.Command
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.Group
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.GroupMixin
|
||||
:members:
|
||||
|
||||
|
||||
Formatters
|
||||
-----------
|
||||
|
||||
.. autoclass:: discord.ext.commands.Paginator
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.HelpFormatter
|
||||
:members:
|
||||
|
||||
Checks
|
||||
-------
|
||||
|
||||
.. autofunction:: discord.ext.commands.check
|
||||
|
||||
.. autofunction:: discord.ext.commands.has_role
|
||||
|
||||
.. autofunction:: discord.ext.commands.has_permissions
|
||||
|
||||
.. autofunction:: discord.ext.commands.has_any_role
|
||||
|
||||
.. autofunction:: discord.ext.commands.bot_has_role
|
||||
|
||||
.. autofunction:: discord.ext.commands.bot_has_permissions
|
||||
|
||||
.. autofunction:: discord.ext.commands.bot_has_any_role
|
||||
|
||||
.. autofunction:: discord.ext.commands.cooldown
|
||||
|
||||
.. autofunction:: discord.ext.commands.guild_only
|
||||
|
||||
.. autofunction:: discord.ext.commands.is_owner
|
||||
|
||||
.. autofunction:: discord.ext.commands.is_nsfw
|
||||
|
||||
Context
|
||||
--------
|
||||
|
||||
.. autoclass:: discord.ext.commands.Context
|
||||
:members:
|
||||
:exclude-members: history typing
|
||||
|
||||
.. autocomethod:: discord.ext.commands.Context.history
|
||||
:async-for:
|
||||
|
||||
.. autocomethod:: discord.ext.commands.Context.typing
|
||||
:async-with:
|
||||
|
||||
Converters
|
||||
------------
|
||||
|
||||
.. autoclass:: discord.ext.commands.Converter
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.MemberConverter
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.UserConverter
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.TextChannelConverter
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.InviteConverter
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.RoleConverter
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.GameConverter
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.ColourConverter
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.VoiceChannelConverter
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.EmojiConverter
|
||||
:members:
|
||||
|
||||
.. autoclass:: discord.ext.commands.clean_content
|
||||
:members:
|
||||
|
||||
Errors
|
||||
-------
|
||||
|
||||
.. autoexception:: discord.ext.commands.CommandError
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.MissingRequiredArgument
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.BadArgument
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.NoPrivateMessage
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.CheckFailure
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.CommandNotFound
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.DisabledCommand
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.CommandInvokeError
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.TooManyArguments
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.UserInputError
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.CommandOnCooldown
|
||||
:members:
|
||||
|
||||
.. autoexception:: discord.ext.commands.NotOwner
|
||||
:members:
|
||||
|
||||
13
docs/ext/commands/index.rst
Normal file
@@ -0,0 +1,13 @@
|
||||
``discord.ext.commands`` -- Bot commands framework
|
||||
====================================================
|
||||
|
||||
``discord.py`` offers a lower level aspect on interacting with Discord. Often times, the library is used for the creation of
|
||||
bots. However this task can be daunting and confusing to get correctly the first time. Many times there comes a repetition in
|
||||
creating a bot command framework that is extensible, flexible, and powerful. For this reason, ``discord.py`` comes with an
|
||||
extension library that handles this for you.
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
api
|
||||
180
docs/faq.rst
@@ -16,7 +16,7 @@ Coroutines
|
||||
Questions regarding coroutines and asyncio belong here.
|
||||
|
||||
I get a SyntaxError around the word ``async``\! What should I do?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This ``SyntaxError`` happens because you're using a Python version lower than 3.5. Python 3.4 uses ``@asyncio.coroutine`` and
|
||||
``yield from`` instead of ``async def`` and ``await``.
|
||||
@@ -52,7 +52,7 @@ Where can I use ``await``\?
|
||||
You can only use ``await`` inside ``async def`` functions and nowhere else.
|
||||
|
||||
What does "blocking" mean?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In asynchronous programming a blocking call is essentially all the parts of the function that are not ``await``. Do not
|
||||
despair however, because not all forms of blocking are bad! Using blocking calls is inevitable, but you must work to make
|
||||
@@ -78,13 +78,14 @@ Consider the following example: ::
|
||||
r = requests.get('http://random.cat/meow')
|
||||
if r.status_code == 200:
|
||||
js = r.json()
|
||||
await client.send_message(channel, js['file'])
|
||||
await channel.send(js['file'])
|
||||
|
||||
# good
|
||||
async with aiohttp.get('http://random.cat/meow') as r:
|
||||
if r.status == 200:
|
||||
js = await r.json()
|
||||
await client.send_message(channel, js['file'])
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get('http://random.cat/meow') as r:
|
||||
if r.status == 200:
|
||||
js = await r.json()
|
||||
await channel.send(js['file'])
|
||||
|
||||
General
|
||||
---------
|
||||
@@ -103,37 +104,41 @@ following: ::
|
||||
How do I send a message to a specific channel?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you have its ID then you can do this in two ways, first is by using :class:`Object`\: ::
|
||||
You must fetch the channel directly and then call the appropriate method. Example: ::
|
||||
|
||||
await client.send_message(discord.Object(id='12324234183172'), 'hello')
|
||||
|
||||
The second way is by calling :meth:`Client.get_channel` directly: ::
|
||||
|
||||
await client.send_message(client.get_channel('12324234183172'), 'hello')
|
||||
|
||||
I'm passing IDs as integers and things are not working!
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the library IDs must be of type ``str`` not of type ``int``. Wrap it in quotes.
|
||||
channel = client.get_channel('12324234183172')
|
||||
await channel.send('hello')
|
||||
|
||||
How do I upload an image?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are two ways of doing it. Both of which involve using :meth:`Client.send_file`.
|
||||
To upload something to Discord you have to use the :class:`File` object.
|
||||
|
||||
The first is by opening the file and passing it directly: ::
|
||||
A :class:`File` accepts two parameters, the file-like object (or file path) and the filename
|
||||
to pass to Discord when uploading.
|
||||
|
||||
with open('my_image.png', 'rb') as f:
|
||||
await client.send_file(channel, f)
|
||||
If you want to upload an image it's as simple as: ::
|
||||
|
||||
The second is by passing the file name directly: ::
|
||||
await channel.send(file=discord.File('my_file.png'))
|
||||
|
||||
If you have a file-like object you can do as follows: ::
|
||||
|
||||
with open('my_file.png', 'rb') as fp:
|
||||
await channel.send(file=discord.File(fp, 'new_filename.png'))
|
||||
|
||||
To upload multiple files, you can use the ``files`` keyword argument instead of ``file``\: ::
|
||||
|
||||
my_files = [
|
||||
discord.File('result.zip'),
|
||||
discord.File('teaser_graph.png'),
|
||||
]
|
||||
await channel.send(files=my_files)
|
||||
|
||||
await client.send_file(channel, 'my_image.png')
|
||||
|
||||
How can I add a reaction to a message?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You use the :meth:`Client.add_reaction` method.
|
||||
You use the :meth:`Message.add_reaction` method.
|
||||
|
||||
If you want to use unicode emoji, you must pass a valid unicode code point in a string. In your code, you can write this in a few different ways:
|
||||
|
||||
@@ -141,16 +146,32 @@ If you want to use unicode emoji, you must pass a valid unicode code point in a
|
||||
- ``'\U0001F44D'``
|
||||
- ``'\N{THUMBS UP SIGN}'``
|
||||
|
||||
In case you want to use emoji that come from a message, you already get their code points in the content without needing to do anything special.
|
||||
You **cannot** send ``':thumbsup:'`` style shorthands.
|
||||
Quick example: ::
|
||||
|
||||
For custom emoji, you should pass an instance of :class:`discord.Emoji`. You can also pass a ``'name:id'`` string, but if you can use said emoji,
|
||||
you should be able to use :meth:`Client.get_all_emojis`/:attr:`Server.emojis` to find the one you're looking for.
|
||||
await message.add_reaction('\N{THUMBS UP SIGN}')
|
||||
|
||||
In case you want to use emoji that come from a message, you already get their code points in the content without needing
|
||||
to do anything special. You **cannot** send ``':thumbsup:'`` style shorthands.
|
||||
|
||||
For custom emoji, you should pass an instance of :class:`Emoji`. You can also pass a ``'name:id'`` string, but if you
|
||||
can use said emoji, you should be able to use :meth:`Client.get_emoji` to get an emoji via ID or use :func:`utils.find`/
|
||||
:func:`utils.get` on :attr:`Client.emojis` or :attr:`Guild.emojis` collections.
|
||||
|
||||
Quick example: ::
|
||||
|
||||
# if you have the ID already
|
||||
emoji = client.get_emoji(310177266011340803)
|
||||
await message.add_reaction(emoji)
|
||||
|
||||
# no ID, do a lookup
|
||||
emoji = discord.utils.get(guild.emojis, name='LUL')
|
||||
if emoji:
|
||||
await message.add_reaction(emoji)
|
||||
|
||||
How do I pass a coroutine to the player's "after" function?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A StreamPlayer is just a ``threading.Thread`` object that plays music. As a result it does not execute inside a coroutine.
|
||||
The library's music player launches on a separate thread, ergo it does not execute inside a coroutine.
|
||||
This does not mean that it is not possible to call a coroutine in the ``after`` parameter. To do so you must pass a callable
|
||||
that wraps up a couple of aspects.
|
||||
|
||||
@@ -169,7 +190,7 @@ However, this function returns a ``concurrent.Future`` and to actually call it w
|
||||
this together we can do the following: ::
|
||||
|
||||
def my_after():
|
||||
coro = client.send_message(some_channel, 'Song is done!')
|
||||
coro = some_channel.send('Song is done!')
|
||||
fut = asyncio.run_coroutine_threadsafe(coro, client.loop)
|
||||
try:
|
||||
fut.result()
|
||||
@@ -177,48 +198,44 @@ this together we can do the following: ::
|
||||
# an error happened sending the message
|
||||
pass
|
||||
|
||||
player = await voice.create_ytdl_player(url, after=my_after)
|
||||
player.start()
|
||||
|
||||
Why is my "after" function being called right away?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``after`` keyword argument expects a *function object* to be passed in. Similar to how ``threading.Thread`` expects a
|
||||
callable in its ``target`` keyword argument. This means that the following are invalid:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
player = await voice.create_ytdl_player(url, after=self.foo())
|
||||
other = await voice.create_ytdl_player(url, after=self.bar(10))
|
||||
|
||||
However the following are correct:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
player = await voice.create_ytdl_player(url, after=self.foo)
|
||||
other = await voice.create_ytdl_player(url, after=lambda: self.bar(10))
|
||||
|
||||
Basically, these functions should not be called.
|
||||
|
||||
voice.play(discord.FFmpegPCMAudio(url), after=my_after)
|
||||
|
||||
How do I run something in the background?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
`Check the background_task.py example. <https://github.com/Rapptz/discord.py/blob/master/examples/background_task.py>`_
|
||||
`Check the background_task.py example. <https://github.com/Rapptz/discord.py/blob/rewrite/examples/background_task.py>`_
|
||||
|
||||
How do I get a specific User/Role/Channel/Server?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
How do I get a specific model?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are multiple ways of doing this. If you have a specific entity's ID then you can use
|
||||
There are multiple ways of doing this. If you have a specific model's ID then you can use
|
||||
one of the following functions:
|
||||
|
||||
- :meth:`Client.get_channel`
|
||||
- :meth:`Client.get_server`
|
||||
- :meth:`Server.get_member`
|
||||
- :meth:`Server.get_channel`
|
||||
- :meth:`Client.get_guild`
|
||||
- :meth:`Client.get_user`
|
||||
- :meth:`Client.get_emoji`
|
||||
- :meth:`Guild.get_member`
|
||||
- :meth:`Guild.get_channel`
|
||||
|
||||
The following use an HTTP request:
|
||||
|
||||
- :meth:`abc.Messageable.get_message`
|
||||
- :meth:`Client.get_user_info`
|
||||
|
||||
|
||||
If the functions above do not help you, then use of :func:`utils.find` or :func:`utils.get` would serve some use in finding
|
||||
specific entities. The documentation for those functions provide specific examples.
|
||||
specific models.
|
||||
|
||||
Quick example: ::
|
||||
|
||||
# find a guild by name
|
||||
guild = discord.utils.get(client.guilds, name='My Server')
|
||||
|
||||
# make sure to check if it's found
|
||||
if guild is not None:
|
||||
# find a channel by name
|
||||
channel = discord.utils.get(guild.text_channels, name='cool-channel')
|
||||
|
||||
Commands Extension
|
||||
-------------------
|
||||
@@ -229,10 +246,10 @@ Is there any documentation for this?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Not at the moment. Writing documentation for stuff takes time. A lot of people get by reading the docstrings in the source
|
||||
code. Others get by via asking questions in the `Discord server <https://discord.gg/0SBTUU1wZTXZNJPa>`_. Others look at the
|
||||
code. Others get by via asking questions in the `Discord server <https://discord.gg/discord-api>`_. Others look at the
|
||||
source code of `other existing bots <https://github.com/Rapptz/RoboDanny>`_.
|
||||
|
||||
There is a `basic example <https://github.com/Rapptz/discord.py/blob/master/examples/basic_bot.py>`_ showcasing some
|
||||
There is a `basic example <https://github.com/Rapptz/discord.py/blob/rewrite/examples/basic_bot.py>`_ showcasing some
|
||||
functionality.
|
||||
|
||||
**Documentation is being worked on, it will just take some time to polish it**.
|
||||
@@ -249,42 +266,36 @@ Overriding the default provided ``on_message`` forbids any extra commands from r
|
||||
|
||||
await bot.process_commands(message)
|
||||
|
||||
Can I use ``bot.say`` in other places aside from commands?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
No. They only work inside commands due to the way the magic involved works.
|
||||
|
||||
Why do my arguments require quotes?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In a simple command defined as: ::
|
||||
|
||||
@bot.command()
|
||||
async def echo(message: str):
|
||||
await bot.say(message)
|
||||
async def echo(ctx, message: str):
|
||||
await ctx.send(message)
|
||||
|
||||
Calling it via ``?echo a b c`` will only fetch the first argument and disregard the rest. To fix this you should either call
|
||||
it via ``?echo "a b c"`` or change the signature to have "consume rest" behaviour. Example: ::
|
||||
|
||||
@bot.command()
|
||||
async def echo(*, message: str):
|
||||
await bot.say(message)
|
||||
async def echo(ctx, *, message: str):
|
||||
await ctx.send(message)
|
||||
|
||||
This will allow you to use ``?echo a b c`` without needing the quotes.
|
||||
|
||||
How do I get the original ``message``\?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Ask the command to pass you the invocation context via ``pass_context``. This context will be passed as the first parameter.
|
||||
The :class:`~ext.commands.Context` contains an attribute, :attr:`~ext.commands.Context.message` to get the original
|
||||
message.
|
||||
|
||||
Example: ::
|
||||
|
||||
@bot.command(pass_context=True)
|
||||
@bot.command()
|
||||
async def joined_at(ctx, member: discord.Member = None):
|
||||
if member is None:
|
||||
member = ctx.message.author
|
||||
|
||||
await bot.say('{0} joined at {0.joined_at}'.format(member))
|
||||
member = member or ctx.author
|
||||
await ctx.send('{0} joined at {0.joined_at}'.format(member))
|
||||
|
||||
How do I make a subcommand?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -294,15 +305,14 @@ the group operating as "subcommands". These groups can be arbitrarily nested as
|
||||
|
||||
Example: ::
|
||||
|
||||
@bot.group(pass_context=True)
|
||||
@bot.group()
|
||||
async def git(ctx):
|
||||
if ctx.invoked_subcommand is None:
|
||||
await bot.say('Invalid git command passed...')
|
||||
|
||||
@git.command()
|
||||
async def push(remote: str, branch: str):
|
||||
await bot.say('Pushing to {} {}'.format(remote, branch))
|
||||
|
||||
async def push(ctx, remote: str, branch: str):
|
||||
await ctx.send('Pushing to {} {}'.format(remote, branch))
|
||||
|
||||
This could then be used as ``?git push origin master``.
|
||||
|
||||
|
||||
BIN
docs/images/discord_client_id.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
docs/images/discord_create_bot_user_button.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
docs/images/discord_finished_bot_user.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
docs/images/discord_new_app_button.PNG
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
docs/images/discord_new_app_form.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
docs/images/discord_reveal_token.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
docs/images/snake.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
@@ -3,23 +3,55 @@
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to discord.py's documentation!
|
||||
======================================
|
||||
Welcome to the discord.py documentation
|
||||
=========================================
|
||||
|
||||
Contents:
|
||||
.. image:: /images/snake.png
|
||||
|
||||
discord.py is a modern, easy to use, feature-rich, and async ready API wrapper
|
||||
for Discord.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Modern Pythonic API using ``async``\/``await`` syntax
|
||||
- Sane rate limit handling that prevents 429s
|
||||
- Implements the entirety of the Discord API
|
||||
- Command extension to aid with bot creation
|
||||
- Easy to use with an object oriented design
|
||||
- Optimised for both speed and memory
|
||||
|
||||
Documentation Contents
|
||||
-----------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
logging
|
||||
whats_new
|
||||
intro
|
||||
quickstart
|
||||
migrating
|
||||
logging
|
||||
api
|
||||
faq
|
||||
|
||||
Extensions
|
||||
-----------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
ext/commands/index.rst
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
Additional Information
|
||||
-----------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
discord
|
||||
faq
|
||||
whats_new
|
||||
|
||||
If you still can't find what you're looking for, try in one of the following pages:
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
|
||||
112
docs/intro.rst
Normal file
@@ -0,0 +1,112 @@
|
||||
.. currentmodule:: discord
|
||||
|
||||
.. _intro:
|
||||
|
||||
Introduction
|
||||
==============
|
||||
|
||||
This is the documentation for discord.py, a library for Python to aid
|
||||
in creating applications that utilise the Discord API.
|
||||
|
||||
Prerequisites
|
||||
---------------
|
||||
|
||||
discord.py works with Python 3.4.2 or higher. Support for earlier versions of Python
|
||||
is not provided. Python 2.7 or lower is not supported. Python 3.3 is not supported
|
||||
due to one of the dependencies (``aiohttp``) not supporting Python 3.3.
|
||||
|
||||
|
||||
.. _installing:
|
||||
|
||||
Installing
|
||||
-----------
|
||||
|
||||
You can get the library directly from PyPI: ::
|
||||
|
||||
python3 -m pip install -U discord.py
|
||||
|
||||
If you are using Windows, then the following should be used instead: ::
|
||||
|
||||
py -3 -m pip install -U discord.py
|
||||
|
||||
|
||||
To get voice support, you should use ``discord.py[voice]`` instead of ``discord.py``, e.g. ::
|
||||
|
||||
python3 -m pip install -U discord.py[voice]
|
||||
|
||||
On Linux environments, installing voice requires getting the following dependencies:
|
||||
|
||||
- libffi
|
||||
- libnacl
|
||||
- python3-dev
|
||||
|
||||
For a debian-based system, the following command will help get those dependencies:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ apt install libffi-dev libnacl-dev python3-dev
|
||||
|
||||
Remember to check your permissions!
|
||||
|
||||
Virtual Environments
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes we don't want to pollute our system installs with a library or we want to maintain
|
||||
different versions of a library than the currently system installed one. Or we don't have permissions to
|
||||
install a library along side with the system installed ones. For this purpose, the standard library as
|
||||
of 3.3 comes with a concept called "Virtual Environment" to help maintain these separate versions.
|
||||
|
||||
A more in-depth tutorial is found on `the official documentation. <https://docs.python.org/3/tutorial/venv.html>`_
|
||||
|
||||
However, for the quick and dirty:
|
||||
|
||||
1. Go to your project's working directory:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ cd your-bot-source
|
||||
$ python3 -m venv bot-env
|
||||
|
||||
2. Activate the virtual environment:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ source bot-env/bin/activate
|
||||
|
||||
On Windows you activate it with:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ bot-env\Scripts\activate.bat
|
||||
|
||||
3. Use pip like usual:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ pip install -U discord.py
|
||||
|
||||
Congratulations. You now have a virtual environment all set up without messing with your system installation.
|
||||
|
||||
Basic Concepts
|
||||
---------------
|
||||
|
||||
discord.py revolves around the concept of :ref:`events <discord-api-events>`.
|
||||
An event is something you listen to and then respond to. For example, when a message
|
||||
happens, you will receive an event about it and you can then respond to it.
|
||||
|
||||
A quick example to showcase how events work:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import discord
|
||||
|
||||
class MyClient(discord.Client):
|
||||
async def on_ready(self):
|
||||
print('Logged on as {0}!'.format(self.user))
|
||||
|
||||
async def on_message(self, message):
|
||||
print('Message from {0.author}: {0.content}'.format(message))
|
||||
|
||||
client = MyClient()
|
||||
client.run('my token goes here')
|
||||
|
||||
1153
docs/migrating.rst
322
docs/migrating_to_async.rst
Normal file
@@ -0,0 +1,322 @@
|
||||
: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 ``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:: python
|
||||
|
||||
@client.event
|
||||
def on_message(message):
|
||||
pass
|
||||
|
||||
After:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@client.event
|
||||
@asyncio.coroutine
|
||||
def on_message(message):
|
||||
pass
|
||||
|
||||
Or in Python 3.5+:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@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:: python
|
||||
|
||||
@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:: python
|
||||
|
||||
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:: python
|
||||
|
||||
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 <https://docs.python.org/3/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:: python
|
||||
|
||||
client.send_message(message.channel, 'Hello')
|
||||
|
||||
After:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
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:: python
|
||||
|
||||
if client.servers[0].name == "test":
|
||||
# do something
|
||||
|
||||
Since they are no longer ``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:: python
|
||||
|
||||
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
|
||||
`enumerations <https://docs.python.org/3/library/enum.html>`_ 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:: python
|
||||
|
||||
server.region == 'us-west'
|
||||
member.status == 'online'
|
||||
channel.type == 'text'
|
||||
|
||||
After:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
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:: python
|
||||
|
||||
client.login('token')
|
||||
client.run()
|
||||
|
||||
After:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
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:: python
|
||||
|
||||
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()
|
||||
|
||||
|
||||
|
||||
76
docs/quickstart.rst
Normal file
@@ -0,0 +1,76 @@
|
||||
.. _quickstart:
|
||||
|
||||
.. currentmodule:: discord
|
||||
|
||||
Quickstart
|
||||
============
|
||||
|
||||
This page gives a brief introduction to the library. It assumes you have the library installed,
|
||||
if you don't check the :ref:`installing` portion.
|
||||
|
||||
A Minimal Bot
|
||||
---------------
|
||||
|
||||
Let's make a bot that replies to a specific message and walk you through it.
|
||||
|
||||
It looks something like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import discord
|
||||
|
||||
client = discord.Client()
|
||||
|
||||
@client.event
|
||||
async def on_ready():
|
||||
print('We have logged in as {0.user}'.format(self))
|
||||
|
||||
@client.event
|
||||
async def on_message(message):
|
||||
if message.author == client.user:
|
||||
return
|
||||
|
||||
if message.content.startswith('$hello'):
|
||||
await message.channel.send('Hello!')
|
||||
|
||||
client.run('your token here')
|
||||
|
||||
Let's name this file ``example_bot.py``. Make sure not to name it ``discord.py`` as that'll conflict
|
||||
with the library.
|
||||
|
||||
There's a lot going on here, so let's walk you through it step by step.
|
||||
|
||||
1. The first line just imports the library, if this raises a `ModuleNotFoundError` or `ImportError`
|
||||
then head on over to :ref:`installing` section to properly install.
|
||||
2. Next, we create an instance of a :class:`Client`. This client is our connection to Discord.
|
||||
3. We then use the :meth:`Client.event` decorator to register an event. This library has many events.
|
||||
Since this library is asynchronous, we do things in a "callback" style manner.
|
||||
|
||||
A callback is essentially a function that is called when something happens. In our case,
|
||||
the :func:`on_ready` event is called when the bot has finished logging in and setting things
|
||||
up and the :func:`on_message` event is called when the bot has received a message.
|
||||
4. Since the :func:`on_message` event triggers for *every* message received, we have to make
|
||||
sure that we ignore messages from ourselves. We do this by checking if the :attr:`Message.author`
|
||||
is the same as the :attr:`Client.user`.
|
||||
5. Afterwards, we check if the :class:`Message.content` starts with ``'$hello'``. If it is,
|
||||
then we reply in the channel it was used in with ``'Hello!'``.
|
||||
6. Finally, we run the bot with our login token. If you need help getting your token or creating a bot,
|
||||
look in the :ref:`discord-intro` section.
|
||||
|
||||
|
||||
Now that we've made a bot, we have to *run* the bot. Luckily, this is simple since this is just a
|
||||
Python script, we can run it directly.
|
||||
|
||||
On Windows:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ py -3 example_bot.py
|
||||
|
||||
On other systems:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ python3 example_bot.py
|
||||
|
||||
Now you can try playing around with your basic bot.
|
||||
@@ -2,12 +2,26 @@
|
||||
|
||||
.. _whats_new:
|
||||
|
||||
What's New
|
||||
Changelog
|
||||
============
|
||||
|
||||
This page keeps a detailed human friendly rendering of what's new and changed
|
||||
in specific versions.
|
||||
|
||||
.. _vp0p16p6:
|
||||
|
||||
v0.16.6
|
||||
--------
|
||||
|
||||
Bug Fixes
|
||||
~~~~~~~~~~
|
||||
|
||||
- Fix issue with :meth:`Client.create_server` that made it stop working.
|
||||
- Fix main thread being blocked upon calling ``StreamPlayer.stop``.
|
||||
- Handle HEARTBEAT_ACK and resume gracefully when it occurs.
|
||||
- Fix race condition when pre-emptively rate limiting that caused releasing an already released lock.
|
||||
- Fix invalid state errors when immediately cancelling a coroutine.
|
||||
|
||||
.. _vp0p16p1:
|
||||
|
||||
v0.16.1
|
||||
|
||||