Vous pouvez installer la dernière version PYPI de la bibliothèque en faisant:
$ pip install reactionmenu
Ou la version de développement:
$ pip install git+https://github.com/Defxult/reactionmenu
Intention minimale nécessaire
bot = commands . Bot (..., intents = discord . Intents ( messages = True , guilds = True , reactions = True , members = True )) class reactionmenu.ReactionMenu(method: Union[Context, discord.Interaction], /, *, menu_type: MenuType, **kwargs)
Une ReactionMenu est un menu qui utilise des emojis qui sont soit des emojis de guilde personnalisés, soit un emoji normal pour contrôler le processus de pagination. Si vous ne recherchez aucune des fonctionnalités fantaisistes et que vous voulez juste quelque chose de simple, c'est celui à utiliser.
from reactionmenu import ReactionMenu , ReactionButtonCette bibliothèque est livrée avec plusieurs méthodes et options afin de faciliter un menu de réaction Discord. Une fois que vous aurez importé les classes appropriées, vous initialiserez le constructeur comme tel:
menu = ReactionMenu ( method , menu_type = ReactionMenu . TypeEmbed )method ( Union[discord.ext.commands.Context, discord.Interaction] ) Un objet de contexte ou d'interactionmenu_type ( MenuType ) La configuration du menuReactionMenu.TypeEmbed , un menu de pagination intégrale normaleReactionMenu.TypeEmbedDynamic , un menu de pagination intégrée avec des données dynamiquesReactionMenu.TypeText , un menu de pagination de texte uniquement| Nom | Taper | Valeur par défaut | Utilisé pour | Informations |
|---|---|---|---|---|
wrap_in_codeblock | str | None | ReactionMenu.TypeEmbedDynamic | L'identifiant de langue Discord CodeBlock pour envelopper vos données. Exemple: ReactionMenu(ctx, ..., wrap_in_codeblock='py') |
custom_embed | discord.Embed | None | ReactionMenu.TypeEmbedDynamic | ENCHET OBJET À utiliser lors de l'ajout de données avec ReactionMenu.add_row() . Utilisé à des fins de style |
delete_on_timeout | bool | False | All menu types | Supprimez le menu quand il met en temps |
clear_reactions_after | bool | True | All menu types | Supprimer toutes les réactions après le menu |
navigation_speed | str | ReactionMenu.NORMAL | All menu types | Définit si l'utilisateur doit attendre que la réaction soit supprimée par le bot avant de "tourner" la page. Régler la vitesse sur ReactionMenu.FAST le fait pour qu'il n'y ait pas besoin d'attendre (les réactions ne sont pas supprimées à chaque presse) et puisse naviguer plus rapidement |
only_roles | List[discord.Role] | None | All menu types | S'il est défini, seuls les membres avec l'un des rôles donnés sont autorisés à contrôler le menu. Le propriétaire du menu peut toujours contrôler le menu |
timeout | Union[int, float, None] | 60.0 | All menu types | La minuterie pour le moment où le menu époustoufle. Ne peut être None pour aucun délai d'expiration |
show_page_director | bool | True | All menu types | Montré au bas de chaque page intégrée. "Page 1/20" |
name | str | None | All menu types | Un nom que vous pouvez définir pour le menu |
style | str | "Page $/&" | All menu types | Un style de directeur de page personnalisé que vous pouvez sélectionner. "$" représente la page actuelle "et" représente le montant total des pages. Exemple: ReactionMenu(ctx, ..., style='On $ out of &') |
all_can_click | bool | False | All menu types | Sets si tout le monde est autorisé à contrôler lorsque les pages sont «tournées» lorsque les boutons sont cliqués |
delete_interactions | bool | True | All menu types | Supprimez le message rapide par le bot et le message de réponse par l'utilisateur lorsqu'on lui a demandé à quelle page il aimerait aller lors de l'utilisation ReactionButton.Type.GO_TO_PAGE |
rows_requested | int | None | ReactionMenu.TypeEmbedDynamic | La quantité d'informations par ReactionMenu.add_row() que vous souhaitez appliquer à chaque page intégrée |
remove_extra_emojis | bool | False | All menu types | Si True , tous les emojis (réactions) ajoutés au message de menu qui n'ont pas été ajoutés à l'origine au menu seront supprimés |
Selon le menu_type , les pages peuvent être soit un str , discord.Embed , soit une combinaison de content et files (exemple ci-dessous)
menu_type est ReactionMenu.TypeEmbed , utilisez des intégresmenu_type est ReactionMenu.TypeText (menu de texte uniquement) ou ReactionMenu.TypeEmbedDynamic (menu ENCHED UNIQUEMENT), utilisez des chaînes.ReactionMenu.add_page(embed: discord.Embed=MISSING, content: Optional[str]=None, files: Optional[Sequence[discord.File]]=None)ReactionMenu.add_pages(pages: Sequence[Union[discord.Embed, str]])ReactionMenu.add_row(data: str)ReactionMenu.remove_all_pages()ReactionMenu.clear_all_row_data()ReactionMenu.remove_page(page_number: int)ReactionMenu.set_main_pages(*embeds: Embed)ReactionMenu.set_last_pages(*embeds: Embed) # ReactionMenu.TypeEmbed
menu = ReactionMenu ( method , menu_type = ReactionMenu . TypeEmbed )
menu . add_page ( summer_embed )
menu . add_page ( winter_embed )
# ReactionMenu.TypeText
menu = ReactionMenu ( method , menu_type = ReactionMenu . TypeText )
menu . add_page ( content = 'Its so hot!' )
menu . add_page ( content = 'Its so cold!' ) Un menu TypeText est un menu de pagination textuel. Aucune intégration n'est impliquée dans le processus de pagination, seul le texte brut est utilisé.
Avec v3.1.0+ , vous pouvez paginer avec plus qu'une simple intégration ou un texte. Vous pouvez combiner du texte, des intégres, ainsi que des fichiers. Mais selon le menu_type la combinaison peut être limitée. Voici un exemple de menu avec un menu_type de TypeEmbed qui est empilé.
# You can use regular commands as well
@ bot . tree . command ( description = "These are stacked pages" , guild = discord . Object ( id = ...))
async def stacked ( interaction : discord . Interaction ):
menu = ReactionMenu ( interaction , menu_type = ReactionMenu . TypeEmbed )
menu . add_page ( discord . Embed ( title = "My Embed" ), content = "This content is stacked on top of a file" , files = [ discord . File ( "stacked.py" )])
menu . add_page ( discord . Embed ( title = "Hey Wumpos, can you say hi to the person reading this? ?" ))
menu . add_page ( discord . Embed ( title = "Hi, I'm Wumpos!" ), files = [ discord . File ( "wumpos.gif" )])
menu . add_button ( ReactionButton . back ())
menu . add_button ( ReactionButton . next ())
await menu . start () Étant donné que le menu_type est TypeEmbed , il doit toujours y avoir une intégration sur chaque page. Si le menu_type était TypeText , les intégres ne sont pas autorisés et vous serez limité à uniquement en utilisant le paramètre files .
Un menu dynamique est utilisé lorsque vous ne savez pas combien d'informations seront appliquées au menu. Par exemple, si vous deviez demander des informations dans une base de données, ces informations peuvent toujours changer. Vous interrogez quelque chose et vous pourriez obtenir 1 500 résultats, et le prochain peut-être seulement 800. Un menu dynamique élabore toutes ces informations ensemble pour vous et l'ajoute à une page intégrée par des lignes de données. ReactionMenu.add_row() est mieux utilisé dans une sorte d' Iterable où tout peut être en boucle, mais ajoutez uniquement la quantité de données que vous souhaitez à la page de menu.
Remarque: Dans un menu dynamique, toutes les données ajoutées sont placées dans la section description d'une intégration. Si vous choisissez d'utiliser un
custom_embed, tout le texte de la description sera remplacé par les données que vous ajoutez
ReactionMenu.add_row(data: str)ReactionMenu.clear_all_row_data()ReactionMenu.set_main_pages(*embeds: Embed)ReactionMenu.set_last_pages(*embeds: Embed)rows_requested - La quantité de lignes que vous souhaitez sur chaque page Embed avant de créer une nouvelle pageReactionMenu(..., rows_requested=5)custom_embed - Une intégration que vous avez créée pour utiliser comme pages d'intégration. Utilisé pour votre menu esthétiqueReactionMenu(..., custom_embed=red_embed)wrap_in_codeblock - L'identifiant de la langue lors de l'enveloppe de vos données dans un Discord CodeBlock.ReactionMenu(..., wrap_in_codeblock='py') menu = ReactionMenu ( ctx , menu_type = ReactionMenu . TypeEmbedDynamic , rows_requested = 5 )
for data in database . request ( 'SELECT * FROM customers' ):
menu . add_row ( data ) Vous pouvez supprimer toutes les données que vous avez ajoutées à un menu en utilisant menu.clear_all_row_data()
Lorsque vous utilisez un menu dynamique, les seules pages intégrées que vous voyez proviennent des données que vous avez ajoutées. Mais si vous souhaitez afficher plus de pages autres que les données, vous pouvez utiliser des méthodes ReactionMenu.set_main_pages() et ReactionMenu.set_last_pages() . En définissant la (s) page (s) principale (s), les intégres que vous définissez seront les premières intégres affichés au démarrage du menu. La définition des dernières page (s) sont les dernières intégres affichées
menu . set_main_pages ( welcome_embed , announcement_embed )
for data in get_information ():
menu . add_row ( data )
menu . set_last_pages ( additional_info_embed )
# NOTE: setting main/last pages can be set in any orderLes boutons / types de boutons sont utilisés lorsque vous souhaitez ajouter une réaction au menu qui fait une certaine fonction. Les boutons et les types de boutons fonctionnent ensemble pour réaliser l'action souhaitée.
class reactionmenu.ReactionButton(*, emoji: str, linked_to: ButtonType, **kwargs)
emoji ( str ) l'emoji que vous aimeriez utiliser comme réactionlinked_to ( ReactionButton.Type ) Lorsque la réaction est pressée, c'est ce qui détermine ce qu'il fera| Nom | Taper | Valeur par défaut | Utilisé pour |
|---|---|---|---|
embed | discord.Embed | None | Lorsque la réaction est pressée, accédez à l'intégration spécifiée |
name | str | None | Le nom du bouton |
details | Informations ci-dessous | None | Attribue la fonction et ses arguments à appeler lorsqu'une ReactionButton avec ReactionButton.Type.CALLER est pressée |
event | ReactionButton.Event | None | Déterminez quand un bouton doit être supprimé en fonction du nombre de fois où il a été enfoncé |
skip | ReactionButton.Skip | None | Définissez l'action et la quantité de pages à sauter lors de l'utilisation d'un linked_to de ReactionButton.Type.SKIP . Par exemple, en utilisant ce type de bouton, en définissant l'action sur "+" et le montant 3. Si vous êtes sur "Page 1/20", l'appuyer sur ce bouton vous amènera à "page 4/20" |
| Propriété | Type de retour | Informations |
|---|---|---|
clicked_by | Set[discord.Member] | Les membres qui ont cliqué sur le bouton |
total_clicks | int | Quantité de clics sur le bouton |
last_clicked | Optional[datetime.datetime] | L'heure dans UTC pour quand le bouton a été cliqué pour la dernière fois |
menu | Optional[ReactionMenu] | Le menu au bouton est fixé |
ReactionMenu.add_button(button: ReactionButton)ReactionMenu.remove_all_buttons()ReactionMenu.remove_button(button: ReactionButton)ReactionMenu.get_button(identity: Union[str, int], *, search_by='name')ReactionButton.set_caller_details(func: Callable[..., None], *args, **kwargs)| Taper | Informations |
|---|---|
ReactionButton.Type.NEXT_PAGE | Accédez à la page suivante de la session de menu |
ReactionButton.Type.PREVIOUS_PAGE | Accédez à la page précédente dans la session de menu |
ReactionButton.Type.GO_TO_FIRST_PAGE | Accédez à la première page de la session de menu |
ReactionButton.Type.GO_TO_LAST_PAGE | Accédez à la dernière page de la session de menu |
ReactionButton.Type.GO_TO_PAGE | Vous invite à saisir la page que vous souhaitez aller |
ReactionButton.Type.END_SESSION | Arrête la session et supprime le message du menu |
ReactionButton.Type.CUSTOM_EMBED | Utilisé séparément des boutons de navigation. Une fois pressé, accédez à l'intégration spécifiée |
ReactionButton.Type.CALLER | Utilisé lors de la spécification de la fonction à appeler et ses arguments lorsque le bouton est enfoncé |
ReactionButton.Type.SKIP | Utilisé pour paginer à travers plusieurs pages en un seul bouton Appuyez sur |
Vous pouvez ajouter des boutons (réactions) au menu à l'aide d'un ReactionButton . Vous trouverez ci-dessous des exemples sur la façon d'utiliser chaque ButtonType .
Remarque: ReactionButtons avec
ReactionButton.Type.CALLERest un peu différent, il y a donc une section dédiée expliquant comment elles fonctionnent et comment les mettre en œuvre plus loin ci-dessous
menu = ReactionMenu (...)
# first and last pages
fpb = ReactionButton ( emoji = '⏪' , linked_to = ReactionButton . Type . GO_TO_FIRST_PAGE )
lpb = ReactionButton ( emoji = '⏩' , linked_to = ReactionButton . Type . GO_TO_LAST_PAGE )
# go to page
gtpb = ReactionButton ( emoji = '?' , linked_to = ReactionButton . Type . GO_TO_PAGE )
# end session
esb = ReactionButton ( emoji = '⏹️' , linked_to = ReactionButton . Type . END_SESSION )
# custom embed
ceb = ReactionButton ( emoji = '?' , linked_to = ReactionButton . Type . CUSTOM_EMBED , embed = discord . Embed ( title = 'Hello' ))
# skip button
sb = ReactionButton ( emoji = '5️⃣' , linked_to = ReactionButton . Type . SKIP , skip = ReactionButton . Skip ( action = '+' , amount = 5 ))
menu . add_button ( fpb )
... Supprimez tous les boutons avec menu.remove_all_buttons() . Vous pouvez également supprimer un bouton individuel en utilisant son nom si vous l'avez réglé, ou l'objet de bouton lui-même avec menu.remove_button()
Les boutons ReactionButton.Type.CALLER sont utilisés pour implémenter vos propres fonctionnalités dans le menu. Peut-être que vous souhaitez ajouter un bouton qui crée un canal de texte, envoie un message ou ajouter quelque chose à une base de données, quel qu'il soit. Afin de travailler avec ReactionButton.Type.CALLER , utilisez la méthode de classe ci-dessous.
ReactionButton.set_caller_details(func: Callable[..., None], *args, **kwargs) Cette méthode de classe est utilisée pour configurer une fonction et ses arguments qui sont appelés plus tard lorsque le bouton est enfoncé. Le constructeur ReactionButton a les details de Kwarg, et c'est ce que vous utiliserez avec .set_caller_details() pour attribuer les valeurs nécessaires. Certains exemples sont ci-dessous sur la façon de mettre en œuvre correctement ReactionButton.Type.CALLER
@ bot . command ()
async def user ( ctx , name , * , message ):
await ctx . send ( f"Hi { name } ! { message } . We're glad you're here!" )
def car ( year , make , model ):
print ( f"I have a { year } { make } { model } " )
ub = ReactionButton ( emoji = '' , linked_to = ReactionButton . Type . CALLER , details = ReactionButton . set_caller_details ( user , ctx , 'Defxult' , message = 'Welcome to the server' ))
cb = ReactionButton ( emoji = '?' , linked_to = ReactionButton . Type . CALLER , details = ReactionButton . set_caller_details ( car , 2021 , 'Ford' , 'Mustang' ))Remarque: la fonction que vous transmettez ne doit rien retourner. Les fonctions d'appel avec
ReactionButton.Type.CALLERne stockent ni ne traitent rien de renvoyé par cette fonction
La classe ReactionButton est livrée avec une méthodes d'usine set (méthodes de classe) qui renvoie un ReactionButton avec des paramètres définis selon leur linked_to .
ReactionButton.back()emoji : "linked_to : ReactionButton.Type.PREVIOUS_PAGEReactionButton.next()emoji : "linked_to : ReactionButton.Type.NEXT_PAGEReactionButton.go_to_first_page()emoji : "⏪"linked_to : ReactionButton.Type.GO_TO_FIRST_PAGEReactionButton.go_to_last_page()emoji : "⏩"linked_to : ReactionButton.Type.GO_TO_LAST_PAGEReactionButton.go_to_page()emoji : "?"linked_to : ReactionButton.Type.GO_TO_PAGEReactionButton.end_session()emoji : "⏹️"linked_to : ReactionButton.Type.END_SESSIONReactionButton.all()list de ReactionButton dans l'ordre suivant.go_to_first_page() .back() .next() .go_to_last_page() .go_to_page() .end_session()ReactionButton.generate_skip(emoji: str, action: str, amount: int)emoji : <emoji>linked_to : ReactionButton.Type.SKIPskip : ReactionButton.Skip(<action>, <amount>)Si vous le souhaitez, vous pouvez limiter la quantité de menus de réaction qui peuvent être actifs en même temps par "guilde", "membre" ou "canal"
ReactionMenu.set_sessions_limit(limit: int, per='guild', message='Too many active menus. Wait for other menus to be finished.')ReactionMenu.remove_limit()Exemple:
@ bot . command ()
async def limit ( ctx ):
ReactionMenu . set_sessions_limit ( 3 , per = 'member' , message = 'Sessions are limited to 3 per member' )Avec l'exemple ci-dessus, seuls 3 menus peuvent être actifs à la fois pour chaque membre, et s'ils essaient d'en créer plus avant la fin de leurs autres menu, ils recevront un message d'erreur disant que "les sessions sont limitées à 3 par membre".
Vous pouvez définir une ReactionButton pour être supprimée lorsqu'il a été pressé un certain nombre de fois
class ReactionButton.Event(event_type: str, value: int)
event_type ( str ) L'action à prendre. La seule option disponible est "supprimer"value ( int ) Le montant défini pour l'événement spécifié. Doit être> = 1. Si la valeur est <= 0, elle est implicitement définie sur 1Exemple:
menu = ReactionMenu ( ctx , ...)
# remove a button after 10 clicks
button = ReactionButton (..., event = ReactionButton . Event ( 'remove' , 10 ))
menu . add_button ( button )Remarque: Pas idéal pour les boutons avec un
linked_todeReactionButton.Type.END_SESSION
Les relais de menu sont des fonctions qui sont appelées chaque fois qu'un bouton en dehors d'un menu est enfoncé. Il est considéré comme une extension d'une ReactionButton avec un linked_to de ReactionButton.Type.CALLER . Contrairement aux boutons de l'appelant qui ne fournit aucun détail sur les interactions dans le menu, les relais font.
ReactionMenu.set_relay(func: Callable[[NamedTuple], None], *, only: Optional[List[ReactionButton]]=None)ReactionMenu.remove_relay() Lors de la création d'une fonction pour votre relais, cette fonction doit contenir un seul argument positionnel. Lorsqu'un bouton est enfoncé, un objet RelayPayload (un tuple nommé) est transmis à cette fonction. Les attributs de RelayPayload sont:
member ( discord.Member ) La personne qui a appuyé sur le boutonbutton ( ReactionButton ) le bouton qui a été appuyéExemple:
async def enter_giveaway ( payload ):
member = payload . member
channel = payload . button . menu . message . channel
await channel . send ( f" { member . mention } , you've entered the giveaway!" )
menu = ReactionMenu ( ctx , ...)
menu . set_relay ( enter_giveaway ) La méthode set_relay est livrée avec le only paramètre. Si ce paramètre None , tous les boutons pressés seront relayés. Vous pouvez fournir une list de boutons à ce paramètre afin que seules les pressions sur le bouton à partir de ces boutons spécifiés soient relayés.
def example ( payload ):
...
menu = ReactionMenu ( ctx , ...)
back_button = ReactionButton . back ()
next_button = ReactionButton . next ()
menu . set_relay ( example , only = [ back_button ])await ReactionMenu.start(*, send_to=None, reply=False)await ReactionMenu.stop(*, delete_menu_message=False, clear_reactions=False) Lorsque vous démarrez le menu, vous avez la possibilité d'envoyer le menu à un certain canal. Le paramètre send_to est le canal auquel vous souhaitez envoyer le menu. Vous pouvez définir send_to comme nom de canal ( str ), ID de canal ( int ) ou canal ( discord.TextChannel / discord.Thread ). Exemple:
menu = ReactionMenu (...)
# channel name
await menu . start ( send_to = 'bot-commands' )
# channel ID
await menu . start ( send_to = 1234567890123456 )
# channel object
channel = guild . get_channel ( 1234567890123456 )
await menu . start ( send_to = channel )
# there's no need to specify send_to unless you want the menu to be sent to a different channel
# from the one you're sending the initial message/using the command in. the menu can be started
# in the current channel by omitting the send_to parameter
await menu . start ()Remarque:
send_ton'est pas valide si un menu a été démarré dans DM
Voici une implémentation de base de ReactionMenu que vous pouvez copier et coller pour une démonstration rapide.
import asyncio
import discord
from discord . ext import commands
from reactionmenu import ReactionMenu , ReactionButton
bot = commands . Bot ( command_prefix = '!' , intents = discord . Intents . all ())
async def start_bot ():
async with bot :
await bot . start ( '...' )
@ bot . command ()
async def example ( ctx ):
menu = ReactionMenu ( ctx , menu_type = ReactionMenu . TypeEmbed )
for member in ctx . guild . members :
if member . avatar :
embed = discord . Embed ( description = f'Joined { member . joined_at . strftime ( "%b. %d, %Y" ) } ' )
embed . set_author ( name = member . name , icon_url = member . avatar . url )
menu . add_page ( embed )
menu . add_button ( ReactionButton . back ())
menu . add_button ( ReactionButton . next ())
menu . add_button ( ReactionButton . end_session ())
await menu . start ()
asyncio . run ( start_bot ()) class reactionmenu.ViewMenu(method: Union[Context, discord.Interaction], /, *, menu_type: MenuType, **kwargs)
Un ViewMenu est un menu qui utilise la fonction de boutons Discords. Avec les boutons, vous pouvez les activer et les désactiver, définir une certaine couleur pour eux avec des emojis, avoir des boutons qui envoient des messages cachés et ajouter des hyperliens. Cette bibliothèque offre une gamme plus large de fonctionnalités telles que celles qui ont appuyé sur le bouton, combien de fois il a été enfoncé et plus. Il utilise des vues ( discord.ui.View ) pour implémenter la fonctionnalité des boutons, mais utilise certaines de ses propres méthodes afin de faciliter un menu de pagination de bouton.
from reactionmenu import ViewMenu , ViewButtonmethod ( Union[discord.ext.commands.Context, discord.Interaction] ) Un objet de contexte ou d'interactionmenu_type ( MenuType ) La configuration du menuViewMenu.TypeEmbed , un menu de pagination intégrale normaleViewMenu.TypeEmbedDynamic , un menu de pagination intégrée avec des données dynamiquesViewMenu.TypeText , un menu de pagination de texte uniquement| Nom | Taper | Valeur par défaut | Utilisé pour | Informations |
|---|---|---|---|---|
wrap_in_codeblock | str | None | ViewMenu.TypeEmbedDynamic | L'identifiant de langue Discord CodeBlock pour envelopper vos données. Exemple: ViewMenu(ctx, ..., wrap_in_codeblock='py') |
custom_embed | discord.Embed | None | ViewMenu.TypeEmbedDynamic | Embed Object à utiliser lors de l'ajout de données avec ViewMenu.add_row() . Utilisé à des fins de style |
delete_on_timeout | bool | False | All menu types | Supprimez le menu quand il met en temps |
disable_items_on_timeout | bool | True | All menu types | Désactivez les éléments du menu lorsque le menu met à la sortie |
remove_items_on_timeout | bool | False | All menu types | Supprimer les éléments du menu lorsque le menu empêche |
only_roles | List[discord.Role] | None | All menu types | S'il est défini, seuls les membres avec l'un des rôles donnés sont autorisés à contrôler le menu. Le propriétaire du menu peut toujours contrôler le menu |
timeout | Union[int, float, None] | 60.0 | All menu types | La minuterie pour le moment où le menu époustoufle. Ne peut être None pour aucun délai d'expiration |
show_page_director | bool | True | All menu types | Montré au bas de chaque page intégrée. "Page 1/20" |
name | str | None | All menu types | Un nom que vous pouvez définir pour le menu |
style | str | "Page $/&" | All menu types | Un style de directeur de page personnalisé que vous pouvez sélectionner. "$" représente la page actuelle "et" représente le montant total des pages. Exemple: ViewMenu(ctx, ..., style='On $ out of &') |
all_can_click | bool | False | All menu types | Sets si tout le monde est autorisé à contrôler lorsque les pages sont «tournées» lorsque les boutons sont cliqués |
delete_interactions | bool | True | All menu types | Supprimez le message rapide par le bot et le message de réponse par l'utilisateur lorsqu'on lui a demandé quelle page ils aimeraient aller lors de l'utilisation ViewButton.ID_GO_TO_PAGE |
rows_requested | int | None | ViewMenu.TypeEmbedDynamic | La quantité d'informations par ViewMenu.add_row() que vous souhaitez appliquer à chaque page intégrée |
Selon le menu_type , les pages peuvent être une str , discord.Embed , soit une combinaison de content ou files (exemple ci-dessous)
menu_type est ViewMenu.TypeEmbed , utilisez des intégresmenu_type est ViewMenu.TypeText (menu de texte uniquement) ou ViewMenu.TypeEmbedDynamic (menu ENCHED UNIQUEMENT), utilisez des chaînes.ViewMenu.add_page(embed: discord.Embed=MISSING, content: Optional[str]=None, files: Optional[Sequence[discord.File]]=None)ViewMenu.add_pages(pages: Sequence[Union[discord.Embed, str]])ViewMenu.add_row(data: str)ViewMenu.remove_all_pages()ViewMenu.clear_all_row_data()ViewMenu.remove_page(page_number: int)ViewMenu.set_main_pages(*embeds: Embed)ViewMenu.set_last_pages(*embeds: Embed) # ViewMenu.TypeEmbed
menu = ViewMenu ( method , menu_type = ViewMenu . TypeEmbed )
menu . add_page ( summer_embed )
menu . add_page ( winter_embed )
# ViewMenu.TypeText
menu = ViewMenu ( method , menu_type = ViewMenu . TypeText )
menu . add_page ( content = 'Its so hot!' )
menu . add_page ( content = 'Its so cold!' ) Un menu TypeText est un menu de pagination textuel. Aucune intégration n'est impliquée dans le processus de pagination, seul le texte brut est utilisé.
Avec v3.1.0+ , vous pouvez paginer avec plus qu'une simple intégration ou un texte. Vous pouvez combiner du texte, des intégres, ainsi que des fichiers. Mais selon le menu_type la combinaison peut être limitée. Voici un exemple de menu avec un menu_type de TypeEmbed qui est empilé.
# You can use regular commands as well
@ bot . tree . command ( description = "These are stacked pages" , guild = discord . Object ( id = ...))
async def stacked ( interaction : discord . Interaction ):
menu = ViewMenu ( interaction , menu_type = ViewMenu . TypeEmbed )
menu . add_page ( discord . Embed ( title = "My Embed" ), content = "This content is stacked on top of a file" , files = [ discord . File ( "stacked.py" )])
menu . add_page ( discord . Embed ( title = "Hey Wumpos, can you say hi to the person reading this? ?" ))
menu . add_page ( discord . Embed ( title = "Hi, I'm Wumpos!" ), files = [ discord . File ( "wumpos.gif" )])
menu . add_button ( ViewButton . back ())
menu . add_button ( ViewButton . next ())
await menu . start () Étant donné que le menu_type est TypeEmbed , il doit toujours y avoir une intégration sur chaque page. Si le menu_type était TypeText , les intégres ne sont pas autorisés et vous serez limité à uniquement en utilisant le paramètre files .
Un menu dynamique est utilisé lorsque vous ne savez pas combien d'informations seront appliquées au menu. Par exemple, si vous deviez demander des informations dans une base de données, ces informations peuvent toujours changer. Vous interrogez quelque chose et vous pourriez obtenir 1 500 résultats, et le prochain peut-être seulement 800. Un menu dynamique élabore toutes ces informations ensemble pour vous et l'ajoute à une page intégrée par des lignes de données. ViewMenu.add_row() est mieux utilisé dans une sorte d' Iterable où tout peut être en boucle, mais ajoutez uniquement la quantité de données que vous souhaitez à la page de menu.
Remarque: Dans un menu dynamique, toutes les données ajoutées sont placées dans la section description d'une intégration. Si vous choisissez d'utiliser un
custom_embed, tout le texte de la description sera remplacé par les données que vous ajoutez
ViewMenu.add_row(data: str)ViewMenu.clear_all_row_data()ViewMenu.set_main_pages(*embeds: Embed)ViewMenu.set_last_pages(*embeds: Embed)rows_requested - La quantité de lignes que vous souhaitez sur chaque page Embed avant de créer une nouvelle pageViewMenu(..., rows_requested=5)custom_embed - Une intégration que vous avez créée pour utiliser comme pages d'intégration. Utilisé pour votre menu esthétiqueViewMenu(..., custom_embed=red_embed)wrap_in_codeblock - L'identifiant de la langue lors de l'enveloppe de vos données dans un Discord CodeBlock.ViewMenu(..., wrap_in_codeblock='py') menu = ViewMenu ( ctx , menu_type = ViewMenu . TypeEmbedDynamic , rows_requested = 5 )
for data in database . request ( 'SELECT * FROM customers' ):
menu . add_row ( data ) Vous pouvez supprimer toutes les données que vous avez ajoutées à un menu en utilisant menu.clear_all_row_data()
Lorsque vous utilisez un menu dynamique, les seules pages intégrées que vous voyez proviennent des données que vous avez ajoutées. Mais si vous souhaitez afficher plus de pages autres que les données, vous pouvez utiliser des méthodes ViewMenu.set_main_pages() et ViewMenu.set_last_pages() . En définissant la (s) page (s) principale (s), les intégres que vous définissez seront les premières intégres affichés au démarrage du menu. La définition des dernières page (s) sont les dernières intégres affichées
menu . set_main_pages ( welcome_embed , announcement_embed )
for data in get_information ():
menu . add_row ( data )
menu . set_last_pages ( additional_info_embed )
# NOTE: setting main/last pages can be set in any orderLes boutons sont ce que vous utilisez pour interagir avec le menu. Contrairement aux réactions, ils ont l'air plus propres, fournissent moins de problèmes de limite de taux et offrent plus en termes d'interactions. Activer et désactiver les boutons, utiliser des hyperliens Markdown dans ses messages et même envoyer des messages cachés.
ViewMenu.add_button(button: ViewButton)ViewMenu.disable_all_buttons()ViewMenu.disable_button(button: ViewButton)ViewMenu.enable_all_buttons()ViewMenu.enable_button(button: ViewButton)ViewMenu.get_button(identity: str, *, search_by='label')ViewMenu.remove_all_buttons()ViewMenu.remove_button(button: ViewButton)await ViewMenu.refresh_menu_items() class reactionmenu.ViewButton(*, style=discord.ButtonStyle.secondary, label=None, disabled=False, custom_id=None, url=None, emoji=None, followup=None, event=None, **kwargs)
Un ViewButton est une classe qui représente le bouton Discord. C'est une sous-classe de discord.ui.Button .
Voici les règles définies par Discord pour les boutons:
custom_id et ne peuvent pas avoir d' urlurl et ne peuvent pas avoir de custom_idstyle ( discord.ButtonStyle ) Le style boutonlabel ( str ) le texte sur le boutoncustom_id ( str ) un ID pour déterminer l'action de ce bouton. IDS disponibles:ViewButton.ID_NEXT_PAGEViewButton.ID_PREVIOUS_PAGEViewButton.ID_GO_TO_FIRST_PAGEViewButton.ID_GO_TO_LAST_PAGEViewButton.ID_GO_TO_PAGEViewButton.ID_END_SESSIONViewButton.ID_CALLERViewButton.ID_SEND_MESSAGEViewButton.ID_CUSTOM_EMBEDViewButton.ID_SKIPemoji ( Union[str, discord.PartialEmoji] ) Emoji utilisé pour le boutonViewButton(..., emoji='?')ViewButton(..., emoji='<:miscTwitter:705423192818450453>')ViewButton(..., emoji='U000027a1')ViewButton(..., emoji='N{winking face}')url ( str ) URL pour un bouton avec style discord.ButtonStyle.linkdisabled ( bool ) Si le bouton doit être désactivéfollowup ( ViewButton.Followup ) Le message envoyé après la presse du bouton. Uniquement disponible pour les boutons qui ont un custom_id de ViewButton.ID_CALLER ou ViewButton.ID_SEND_MESSAGE . ViewButton.Followup est une classe qui a des paramètres similaires à discord.abc.Messageable.send() , et est utilisé pour contrôler si un message est éphémère, contient un fichier, une intégration, TTS, etc.event ( ViewButton.Event ) Définissez un bouton pour être désactivé ou supprimé lorsqu'il a été appuyé sur une certaine fois | Nom | Taper | Valeur par défaut | Utilisé pour |
|---|---|---|---|
name | str | None | Le nom du bouton |
skip | ViewButton.Skip | None | Définissez l'action et la quantité de pages à sauter lorsque vous utilisez un custom_id de ViewButton.ID_SKIP . Par exemple, la définition de l'action sur "+" et le montant 3. Si vous êtes sur "page 1/20", appuyer sur ce bouton vous amènera à "page 4/20" |
persist | bool | False | Empêche les boutons de liaison d'être désactivés / supprimés lorsque le menu tire ou est arrêté afin qu'ils puissent rester cliquables |
| Propriété | Type de retour | Informations |
|---|---|---|
clicked_by | Set[discord.Member] | Les membres qui ont cliqué sur le bouton |
total_clicks | int | Quantité de clics sur le bouton |
last_clicked | Optional[datetime.datetime] | L'heure dans UTC pour quand le bouton a été cliqué pour la dernière fois |
menu | Optional[ViewMenu] | Le menu au bouton est fixé |
from reactionmenu import ViewMenu , ViewButton
menu = ViewMenu ( ctx , menu_type = ViewMenu . TypeEmbed )
# Link button
link_button = ViewButton ( style = discord . ButtonStyle . link , emoji = '?' , label = 'Link to Google' , url = 'https://google.com' )
menu . add_button ( link_button )
# Skip button
skip = ViewButton ( style = discord . ButtonStyle . primary , label = '+5' , custom_id = ViewButton . ID_SKIP , skip = ViewButton . Skip ( action = '+' , amount = 5 ))
menu . add_button ( skip )
# ViewButton.ID_PREVIOUS_PAGE
back_button = ViewButton ( style = discord . ButtonStyle . primary , label = 'Back' , custom_id = ViewButton . ID_PREVIOUS_PAGE )
menu . add_button ( back_button )
# ViewButton.ID_NEXT_PAGE
next_button = ViewButton ( style = discord . ButtonStyle . secondary , label = 'Next' , custom_id = ViewButton . ID_NEXT_PAGE )
menu . add_button ( next_button )
# All other ViewButton are created the same way as the last 2 EXCEPT
# 1 - ViewButton.ID_CALLER
# 2 - ViewButton.ID_SEND_MESSAGE
# 3 - ViewButton.ID_CUSTOM_EMBED
# ViewButton.ID_CALLER
def say_hello ( name : str ):
print ( 'Hello' , name )
call_followup = ViewButton . Followup ( details = ViewButton . Followup . set_caller_details ( say_hello , 'John' ))
menu . add_button ( ViewButton ( label = 'Say hi' , custom_id = ViewButton . ID_CALLER , followup = call_followup ))
# ViewButton.ID_SEND_MESSAGE
msg_followup = ViewButton . Followup ( 'This message is hidden!' , ephemeral = True )
menu . add_button ( ViewButton ( style = discord . ButtonStyle . green , label = 'Message' , custom_id = ViewButton . ID_SEND_MESSAGE , followup = msg_followup ))
# ViewButton.ID_CUSTOM_EMBED
custom_embed_button = ViewButton ( style = discord . ButtonStyle . blurple , label = 'Social Media Info' , custom_id = ViewButton . ID_CUSTOM_EMBED , followup = ViewButton . Followup ( embed = discord . Embed (...)))Remarque: En ce qui concerne les boutons avec un
custom_iddeViewButton.ID_CALLER,ViewButton.ID_SEND_MESSAGE,ViewButton.ID_CUSTOM_EMBED, ou des boutons de liaison, vous pouvez en ajouter autant que vous le souhaitez aussi longtemps que dans le total de 25 boutons ou moins. Pour tous les autres identifiants de bouton, chaque menu ne peut en avoir qu'un.
Les sélections sont utilisées lorsque vous souhaitez classer les informations dans votre menu. Les sélections ne peuvent être utilisées que lorsque le menu menu_type est TypeEmbed . Vous devez garder à l'esprit que les limitations discrètes du nombre d'éléments d'interface utilisateur (lignes) peuvent être appliqués à chaque message.
Page.from_embeds(embeds: Sequence[Embed])ViewMenu.add_select(select: ViewSelect)ViewMenu.remove_select(select: ViewSelect)ViewMenu.remove_all_selects()ViewMenu.disable_select(select: ViewSelect)ViewMenu.disable_all_selects()ViewMenu.enable_select(select: ViewSelect)ViewMenu.enable_all_selects()ViewMenu.get_select(title: Union[str, None])Exemple:
from reactionmenu import ViewMenu , ViewSelect , Page
menu = ViewMenu ( ctx , menu_type = ViewMenu . TypeEmbed )
menu . add_page ( discord . Embed ( title = "A showcase of console video games" , color = discord . Color . blurple ()))
menu . add_select ( ViewSelect ( title = "Console Video Games" , options = {
# NOTE: The discord.SelectOption parameter "default" cannot be set to True
discord . SelectOption ( label = "PlayStation" , emoji = "<:PlayStation:549638412538478602>" ) : [
Page ( embed = discord . Embed ( title = "Ratchet & Clank" , description = ..., color = discord . Color . yellow ()). set_image ( url = ...)),
Page ( embed = discord . Embed ( title = "God of War" , description = ..., color = discord . Color . blue ()). set_image ( url = ...))
],
discord . SelectOption ( label = "Xbox" , emoji = "<:Xbox:501880493285834752>" ) : [
Page ( embed = discord . Embed ( title = "Halo Infinite" , description = ..., color = discord . Color . green ()). set_image ( url = ...)),
Page ( embed = discord . Embed ( title = "Gears of War 4" , description = ..., color = discord . Color . red ()). set_image ( url = ...))
]
}))
menu . add_button ( ViewButton . back ())
menu . add_button ( ViewButton . next ())
await menu . start ()Vous pouvez utiliser ce type de sélection lorsque vous souhaitez utiliser l'interface utilisateur pour sélectionner une page à laquelle aller.
ViewMenu.add_go_to_select(goto: ViewSelect.GoTo)ViewMenu.enable_go_to_select(goto: ViewSelect.GoTo)ViewMenu.enable_all_go_to_selects()ViewMenu.disable_go_to_select(goto: ViewSelect.GoTo)ViewMenu.disable_all_go_to_selects()ViewMenu.remove_go_to_select(goto: ViewSelect.GoTo)ViewMenu.remove_all_go_to_selects() Le paramètre page_numbers pour ViewSelect.GoTo peut être utilisé avec 3 types différents
List[int] Si définie sur une liste d'entiers, ces valeurs spécifiées sont les seules options disponibles lorsque le sélection est cliquépage_numbers=[1, 5, 10]Dict[int, Union[str, discord.Emoji, discord.PartialEmoji]] Vous pouvez utiliser ce type si vous souhaitez utiliser des emojis dans votre sélectionpage_numbers={1 : "?️", 2 : ""}ellipsis Vous pouvez définir une ellipsis littérale pour que la bibliothèque affecte automatiquement tous les numéros de page à la quantité de pages que vous avez ajoutées au menu. Cela peut être utile si vous avez 25 pages ou moinspage_numbers=...Remarque : Définir le paramètre
page_numberssur une ellipsis (...) ne fonctionne que comme prévu si vous avez ajouté le GO à sélectionner après avoir ajouté des pages au menu
@ bot . command ()
async def navigate ( ctx ):
menu = ViewMenu ( ctx , menu_type = ViewMenu . TypeEmbed )
menu . add_page ( discord . Embed ( title = "Twitter" ). set_image ( url = "..." ))
menu . add_page ( discord . Embed ( title = "YouTube" ). set_image ( url = "..." ))
menu . add_page ( discord . Embed ( title = "Discord" ). set_image ( url = "..." ))
# ...
menu . add_go_to_select ( ViewSelect . GoTo ( title = "Go to page..." , page_numbers = ...))
menu . add_button ( ViewButton . back ())
menu . add_button ( ViewButton . next ())
await menu . start ()await ViewMenu.refresh_menu_items()await ViewMenu.update(*, new_pages: Union[List[Union[Embed, str]], None], new_buttons: Union[List[ViewButton], None]) Lorsque le menu est en cours d'exécution, vous pouvez mettre à jour les pages ou les boutons du menu. En utilisant ViewMenu.update() , vous pouvez remplacer les pages et les boutons. L'utilisation ViewMenu.refresh_menu_items() met à jour les boutons que vous avez changés.
@ bot . command ()
async def menu ( ctx ):
menu = ViewMenu (..., name = 'test' )
link_button = ViewButton (..., label = 'Link' )
menu . add_button ( link_button )
menu . add_page (...)
await menu . start ()
@ bot . command ()
async def disable ( ctx ):
menu = ViewMenu . get_session ( 'test' )
link_button = menu [ 0 ]. get_button ( 'Link' , search_by = 'label' )
menu . disable_button ( link_button )
await menu . refresh_menu_items () Si les boutons ne sont pas actualisés avec ViewMenu.refresh_menu_items() , le menu ne sera pas mis à jour lors du modification d'un bouton.
Méthode ViewMenu.update(...) est utilisée lorsque vous souhaitez remplacer tout ou quelques boutons du menu.
menu = ViewMenu (...)
# in a different .command()
await menu . update ( new_pages = [ hello_embed , goodbye_embed ], new_buttons = [ link_button , next_button ])Remarque : Lorsque vous utilisez
ViewMenu.update(...), il n'est pas nécessaire d'utiliserViewMenu.refresh_menu_items()car ils sont mis à jour lors de l'appel de mise à jour.
La classe ViewButton est livrée avec une méthodes d'usine set (méthodes de classe) qui renvoie un ViewButton avec des paramètres définis en fonction de leur custom_id (à l'exclusion des boutons de liaison).
ViewButton.link(label: str, url: str)style : discord.ButtonStyle.linklabel : <label>url : <url>ViewButton.back()style : discord.ButtonStyle.graylabel : "Back"custom_id : ViewButton.ID_PREVIOUS_PAGEViewButton.next()style : discord.ButtonStyle.graylabel : "Suivant"custom_id : ViewButton.ID_NEXT_PAGEViewButton.go_to_first_page()style : discord.ButtonStyle.graylabel : "Première page"custom_id : ViewButton.ID_GO_TO_FIRST_PAGEViewButton.go_to_last_page()style : discord.ButtonStyle.graylabel : "Dernière page"custom_id : ViewButton.ID_GO_TO_LAST_PAGEViewButton.go_to_page()style : discord.ButtonStyle.graylabel : "Sélection des pages"custom_id : ViewButton.ID_GO_TO_PAGEViewButton.end_session()discord.ButtonStyle.grayViewButton.ID_END_SESSIONViewButton.all()list de ViewButton dans l'ordre suivant.go_to_first_page() .back() .next() .go_to_last_page() .go_to_page() .end_session()ViewButton.all_with_emojis()list de ViewButton avec leurs paramètres emoji déjà définis dans l'ordre suivant.go_to_first_page() .back() .next() .go_to_last_page() .go_to_page() .end_session()ViewButton.generate_skip(label: str, action: str, amount: int)style : discord.ButtonStyle.graylabel : <label>custom_id : ViewButton.ID_SKIPskip : ViewButton.Skip(<action>, <amount>) menu = ViewMenu ( ctx , ...)
menu . add_page (...)
menu . add_page (...)
menu . add_button ( ViewButton . back ())
menu . add_button ( ViewButton . next ())
await menu . start () Vous pouvez définir un ViewButton pour être désactivé ou supprimé lorsqu'il a été pressé un certain nombre de fois
class ViewButton.Event(event_type: str, value: int)
event_type ( str ) L'action à prendre. Peut être "désactiver" ou "supprimer"value ( int ) Le montant défini pour l'événement spécifié. Doit être> = 1. Si la valeur est <= 0, elle est implicitement définie sur 1Exemple:
menu = ViewMenu ( ctx , ...)
# disable a button after 5 clicks
button_1 = ViewButton (..., event = ViewButton . Event ( 'disable' , 5 ))
menu . add_button ( button_1 )
# remove a button after 10 clicks
button_2 = ViewButton (..., event = ViewButton . Event ( 'remove' , 10 ))
menu . add_button ( button_2 )Remarque: non valide pour les boutons de liaison. Pas également idéal pour les boutons avec un
custom_iddeViewButton.ID_END_SESSION
Les relais de menu sont des fonctions qui sont appelées chaque fois qu'un bouton en dehors d'un menu est enfoncé. Il est considéré comme une extension d'un ViewButton avec un ID de ViewButton.ID_CALLER . Contrairement aux boutons de l'appelant qui ne fournit aucun détail sur les interactions dans le menu, les relais font.
ViewMenu.set_relay(func: Callable[[NamedTuple], None], *, only: Optional[List[ViewButton]]=None)ViewMenu.remove_relay() Lors de la création d'une fonction pour votre relais, cette fonction doit contenir un seul argument positionnel. Lorsqu'un bouton est enfoncé, un objet RelayPayload (un tuple nommé) est transmis à cette fonction. Les attributs de RelayPayload sont:
member ( discord.Member ) La personne qui a appuyé sur le boutonbutton ( ViewButton ) le bouton appuyéExemple:
async def enter_giveaway ( payload ):
member = payload . member
channel = payload . button . menu . message . channel
await channel . send ( f" { member . mention } , you've entered the giveaway!" )
menu = ViewMenu ( ctx , ...)
menu . set_relay ( enter_giveaway ) La méthode set_relay est livrée avec le only paramètre. Si ce paramètre None , tous les boutons appuyés seront relayés (sauf les boutons de liaison car ils n'envoient pas d'événements d'interaction). Vous pouvez fournir une list de boutons à ce paramètre afin que seules les pressions sur le bouton à partir de ces boutons spécifiés soient relayés.
def example ( payload ):
...
menu = ViewMenu ( ctx , ...)
back_button = ViewButton . back ()
next_button = ViewButton . next ()
menu . set_relay ( example , only = [ back_button ])await ViewMenu.start(*, send_to=None, reply=False)await ViewMenu.stop(*, delete_menu_message=False, remove_buttons=False, disable_buttons=False) Lorsque vous démarrez le menu, vous avez la possibilité d'envoyer le menu à un certain canal. Le paramètre send_to est le canal auquel vous souhaitez envoyer le menu. Vous pouvez définir send_to comme nom de canal ( str ), ID de canal ( int ) ou canal ( discord.TextChannel / discord.Thread ). Exemple:
menu = ViewMenu (...)
# channel name
await menu . start ( send_to = 'bot-commands' )
# channel ID
await menu . start ( send_to = 1234567890123456 )
# channel object
channel = guild . get_channel ( 1234567890123456 )
await menu . start ( send_to = channel )
# there's no need to specify send_to unless you want the menu to be sent to a different channel
# from the one you're sending the initial message/using the command in. the menu can be started
# in the current channel by omitting the send_to parameter
await menu . start ()Remarque:
send_ton'est pas valide si un menu a été démarré dans DM
Une seule option est disponible lors de l'arrêt du menu. Si vous avez plusieurs paramètres comme True , un seul exécutera
delete_menu_message > disable_buttonsdisable_buttons > remove_buttons Voici une implémentation de base de ViewMenu que vous pouvez copier et coller pour une démonstration rapide.
import asyncio
import discord
from discord . ext import commands
from reactionmenu import ViewMenu , ViewButton
bot = commands . Bot ( command_prefix = '!' , intents = discord . Intents . all ())
async def start_bot ():
async with bot :
await bot . start ( '...' )
@ bot . command ()
async def example ( ctx ):
menu = ViewMenu ( ctx , menu_type = ViewMenu . TypeEmbed )
for member in ctx . guild . members :
if member . avatar :
embed = discord . Embed ( description = f'Joined { member . joined_at . strftime ( "%b. %d, %Y" ) } ' )
embed . set_author ( name = member . name , icon_url = member . avatar . url )
menu . add_page ( embed )
menu . add_button ( ViewButton . back ())
menu . add_button ( ViewButton . next ())
menu . add_button ( ViewButton . end_session ())
await menu . start ()
asyncio . run ( start_bot ())