Added in version 1.5.
Un vistazo a las intenciones del gateway¶
La versión 1.5 viene con la introducción de Intents. Este es un cambio radical en la forma que se escriben los bots. Una intención básicamente permite a tu bot a suscribirse a ciertos eventos del bucket. Los eventos que corresponden a cada intención están documentados en cada atributo individual de Intents.
Estas intenciones son pasadas al constructor de Client, o sus subclases (AutoShardedClient, AutoShardedBot, Bot), con el argumento intents.
Si no pasas ninguna intención, la biblioteca predeterminará a habilitar todas las intenciones, a excepción de las intenciones privilegiadas, actualmente siendo Intents.members, Intents.presences, y Intents.message_content.
¿Qué intenciones se necesitan?¶
Las intenciones que son necesarias para tu bot solo pueden ser dictadas por ti mismo. Cada atributo en la clase Intents documenta a que eventos corresponden y que tipo de caché habilitan.
Por ejemplo, si quieres un bot que funcione sin eventos que son molestos como las presencias o el tipo, entonces podríamos hacer lo siguiente:
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)
Ten en cuenta que esto no habilita Intents.members o Intents.message_content ya que son intenciones privilegiadas.
Otro ejemplo donde se muestra un bot que solo se ocupa de los mensajes e información de servidores:
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)
Intenciones privilegiadas¶
Con el cambio de la API que requiere que los propietarios de los bots especifiquen intenciones, algunas intenciones fueron restringidas aún más y requieren más pasos manuales. Estas intenciones son llamadas intenciones privilegiadas.
Una intención privilegiada es aquella que requiere que vayas al developer portal y la habilites manualmente. Para habilitar una intención privilegiada, haz lo siguiente:
Asegúrate de haber iniciado sesión en el sitio web de Discord.
Navega a la página de aplicaciones.
Haz clic en el bot para que el cual quieres activar las intenciones privilegiadas.
Navega a la pestaña de bot en el lado izquierda de la pantalla.
Desplázate hacia abajo hasta la sección de «Privileged Gateway Intents» y activa los que desees.
Advertencia
Habilitar intenciones privilegiadas cuando tu bot está en más de 100 servidores, requiere pasar por la verificación de bots.
Nota
Incluso si activas las intenciones a través del portal de desarrolladores, todavía tienes que activar las intenciones a través de tu código.
¿Necesito intenciones privilegiadas?¶
Esta es una lista de verificación rápida para ver si necesitas intenciones privilegiadas específicas.
Intención de presencia¶
Si usas
Member.statusen absoluto para seguir los estados de los miembros.Si usas
Member.activityoMember.activity.activitiespara comprobar las actividades de miembros.
Intención de miembros¶
Si deseas registrar las entradas o salidas de miembros, corresponde a los eventos
on_member_join()yon_member_remove().Si deseas realizar un seguimiento de las actualizaciones de los miembros, tales como nick o cambios de rol.
Si desea rastrear actualizaciones de usuarios como nombres de usuario, avatares, discriminadores, etc.
Si quieres solicitar la lista de miembros del servidor a través de
Guild.chunk()oGuild.fetch_members().Si quieres un caché de miembros de alta precisión bajo
Guild.members.
Intención de contenido del mensaje¶
Si tienes un sistema de comandos basado en mensajes usando ext.commands
Si usas el evento
on_message()para cualquier cosa usando contenido de mensajes, tales como moderación automática.Si usas el contenido del mensaje en
on_message_edit(),on_message_delete(),on_raw_message_edit(),on_raw_message_delete().
Nota
El bot todavía puede recibir contenidos de mensajes en sus MD, cuando se lo menciona en los mensajes en servidores, y para sus propios mensajes en servidores.
Caché de miembros¶
Junto con las intenciones, Discord ahora restringe aún más la capacidad de cachear a los miembros y espera que los autores del bot cacheen tan poco como sea necesario. Sin embargo, para mantener correctamente un caché se requiere la intención Intents.members para poder hacer un seguimiento de los miembros que dejaron el servidor y removerlos correctamente.
Para ayudar con el caché de miembros donde no necesitamos que los miembros sean cacheados, la biblioteca ahora tiene una bandera MemberCacheFlags para controlar la caché de miembros. La página de documentación de la clase va más allá de las políticas específicas que son posibles.
Debe tenerse en cuenta que ciertas cosas no necesitan un caché de miembros, ya que Discord proporcionará información completa si es posible. Por ejemplo:
on_message()tendráMessage.authorcomo un miembro incluso si el caché está deshabilitado.on_voice_state_update()tendrá al parámetromembercomo un miembro incluso si el caché está deshabilitado.on_reaction_add()tendrá el parámetrousercomo miembro cuando esté en un servidor incluso si el caché está deshabilitado.on_raw_reaction_add()tendráRawReactionActionEvent.membercomo un miembro cuando esté en un servidor incluso si el caché está deshabilitado.Los eventos de añadir reacciones no contienen información adicional cuando nos encontramos en mensajes directos. Esta es una limitación de Discord.
Los eventos de eliminación de reacciones no contienen información sobre los miembros. Esta es una limitación de Discord.
Otros eventos que acepten un Member requerirán el uso de la caché de miembros. Si la precisión absoluta sobre la caché de miembros es asumible, entonces es recomendable activar la intención Intents.members.
Obteniendo miembros¶
Si el caché está deshabilitado o desactivas el chunking de servidores al inicio, puede que necesitemos una forma de cargar miembros. La biblioteca ofrece algunas maneras de hacer esto:
Guild.query_members()Utilizado para consultar a los miembros por un prefijo que coincida con el nick o nombre de usuario.
Esto también puede ser utilizado para consultar a los miembros por su ID de usuario.
Esto utiliza la gateway y no las peticiones HTTP.
Guild.chunk()Esto se puede utilizar para obtener toda la lista de miembros a través de la gateway.
Guild.fetch_member()Utilizado para obtener un miembro por su ID a través de la API HTTP.
Guild.fetch_members()usado para obtener un gran número de miembros a través de la API HTTP.
Cabe señalar que la gateway tiene un estricto límite de tasa de 120 solicitudes por 60 segundos.
Resolución de problemas¶
Algunas cuestiones comunes relacionadas con el cambio de intenciones obligatorio.
¿A dónde irían mis miembros?¶
Debido a un cambio en la API, Discord ahora está forzando a los desarrolladores que quieren cachear miembros a explícitamente optar por este. Este es un cambio mandificado de Discord y no hay forma de saltarlo. Para recuperar miembros, tienes que habilitar explícitamente las intenciones privilegiadas de miembros y cambiar Intents.members a true.
Por ejemplo:
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)
¿Por qué on_ready tarda tanto en disparar?¶
Como parte del cambio en la API referido a las intenciones, Discord también cambió como los miembros son cargados al inicio. Originalmente, la biblioteca podía solicitar hasta 75 servidores a la vez, y solo solicitar los miembros de aquellos servidores cuyo Guild.large era True. Con este nuevo cambio de las intenciones, Discord dicta que solo podemos solicitar 1 servidor por petición. Esto causa una lentitud de x75, que es aun más contraproducente por el hecho de que todos los servidores, no solo aquellos grandes, están siendo solicitados.
Hay algunas soluciones para arreglar esto.
La primera solución es solicitar la intención de las presencias privilegiadas junto con la intención de los miembros privilegiados y permitir ambas cosas. Esto permite que la lista inicial de miembros contenga miembros en línea como la gateway antigua. Ten en cuenta que todavía estamos limitados a 1 servidor por solicitud, pero el número de servidores que solicitamos se reduce significativamente.
La segunda solución es deshabilitar el chunking de miembros estableciendo chunk_guilds_at_startup a False al construir un cliente. Luego, cuando sea necesario hacer chunking para un servidor, puedes usar las distintas técnicas para obtener recuperar los miembros.
Para ilustrar la desaceleración causada por el cambio de API, toma un bot que está en 840 servidores y 95 de estos servidores son «grandes» (más de 250 miembros).
Bajo el sistema original esto resultaría en 2 solicitudes para obtener la lista de miembros (75 servidores, 20 servidores) aproximadamente tardando 60 segundos. Con Intents.members pero no Intents.presences esto requiere 840 peticiones, con un límite de tasa de 120 solicitudes por 60 segundos. Significa que debido a la espera del límite nos da un total de unos 7 minutos de espera para que el límite obtenga todos los miembros. Con Intents.members y Intents.presences obtenemos principalmente el comportamiento antiguo, así que solo estamos obligados a solicitar los 95 servidores grandes, esto es un poco menor que nuestro límite de tasa, por lo que está cerca del tiempo original para obtener la lista de miembros.
Lamentablemente, debido a este cambio que se requiere de Discord, no hay nada que la biblioteca pueda hacer para mitigar esto.
Si realmente no te gusta la dirección que Discord lleva con su API, puedes contactarlos a través de soporte.