@@ -27,9 +27,12 @@ def __init__(self,
2727 auto_register : bool = False ):
2828 self ._discord = client
2929 self .commands = {}
30+ self .subcommands = {}
3031 self .req = http .SlashCommandRequest ()
3132 self .logger = logging .getLogger ("discord_slash" )
3233 self .auto_register = auto_register
34+ if self .auto_register :
35+ self .logger .warning ("auto_register is NOT implemented! Please manually add commands to Discord API." )
3336 if not isinstance (client , commands .Bot ):
3437 self .logger .info ("Detected discord.Client! Overriding on_socket_response." )
3538 self ._discord .on_socket_response = self .on_socket_response
@@ -41,7 +44,7 @@ def add_slash_command(self,
4144 name : str = None ,
4245 description : str = None ,
4346 auto_convert : dict = None ,
44- guild_id : int = None ,
47+ guild_ids : list = None ,
4548 options : list = None ,
4649 has_subcommands : bool = False ):
4750 """
@@ -51,7 +54,7 @@ def add_slash_command(self,
5154 :param name: Name of the slash command. Default name of the coroutine.
5255 :param description: Description of the slash command. Default ``None``.
5356 :param auto_convert: Dictionary of how to convert option values. Default ``None``.
54- :param guild_id: Guild ID of where the command will be used. Default ``None``, which will be global command.
57+ :param guild_ids: List of Guild ID of where the command will be used. Default ``None``, which will be global command.
5558 :param options: Options of the slash command. This will affect ``auto_convert`` and command data at Discord API. Default ``None``.
5659 :param has_subcommands: Whether it has subcommand. Default ``False``.
5760 :return: ``None``
@@ -60,22 +63,62 @@ def add_slash_command(self,
6063 "func" : cmd ,
6164 "description" : description ,
6265 "auto_convert" : auto_convert ,
63- "guild_id " : guild_id ,
66+ "guild_ids " : guild_ids ,
6467 "api_options" : options ,
6568 "has_subcommands" : has_subcommands
6669 }
6770 self .commands [cmd .__name__ if not name else name ] = _cmd
6871 self .logger .debug (f"Added command `{ cmd .__name__ if not name else name } `" )
6972
70- def add_subcommand (self ,):
71- pass
73+ def add_subcommand (self ,
74+ cmd ,
75+ base ,
76+ subcommand_group = None ,
77+ name = None ,
78+ description : str = None ,
79+ auto_convert : dict = None ,
80+ guild_ids : list = None ):
81+ """
82+ Registers subcommand to SlashCommand.
83+
84+ :param cmd:
85+ :param base:
86+ :param subcommand_group:
87+ :param name:
88+ :param description:
89+ :param auto_convert:
90+ :param guild_ids:
91+ :return:
92+ """
93+ name = cmd .__name__ if not name else name
94+ _cmd = {
95+ "guild_ids" : guild_ids ,
96+ "has_subcommands" : True
97+ }
98+ _sub = {
99+ "func" : cmd ,
100+ "name" : name ,
101+ "description" : description ,
102+ "auto_convert" : auto_convert ,
103+ "guild_ids" : guild_ids ,
104+ }
105+ self .commands [base ] = _cmd
106+ if base not in self .subcommands .keys ():
107+ self .subcommands [base ] = {}
108+ if subcommand_group :
109+ if subcommand_group not in self .subcommands [base ].keys ():
110+ self .subcommands [base ][subcommand_group ] = {}
111+ self .subcommands [base ][subcommand_group ][name ] = _sub
112+ else :
113+ self .subcommands [base ][name ] = _sub
72114
73115 def slash (self ,
74116 * ,
75117 name : str = None ,
76118 description : str = None ,
77119 auto_convert : dict = None ,
78120 guild_id : int = None ,
121+ guild_ids : list = None ,
79122 options : list = None ):
80123 """
81124 Decorator that registers coroutine as a slash command.\n
@@ -115,9 +158,15 @@ async def _pick(ctx, choice1, choice2): # Command with 1 or more args.
115158 :param name: Name of the slash command. Default name of the coroutine.
116159 :param description: Description of the slash command. Default ``None``.
117160 :param auto_convert: Dictionary of how to convert option values. Default ``None``.
118- :param guild_id: Guild ID of where the command will be used. Default ``None``, which will be global command.
161+ :param guild_id: Deprecated. Use ``guild_ids`` instead.
162+ :param guild_ids: Guild ID of where the command will be used. Default ``None``, which will be global command.
119163 :param options: Options of the slash command. This will affect ``auto_convert`` and command data at Discord API. Default ``None``.
120164 """
165+
166+ if guild_id :
167+ self .logger .warning ("`guild_id` is deprecated! `Use guild_ids` instead." )
168+ guild_ids = [guild_id ]
169+
121170 if options :
122171 # Overrides original auto_convert.
123172 auto_convert = {}
@@ -127,7 +176,7 @@ async def _pick(ctx, choice1, choice2): # Command with 1 or more args.
127176 auto_convert [x ["name" ]] = x ["type" ]
128177
129178 def wrapper (cmd ):
130- self .add_slash_command (cmd , name , description , auto_convert , guild_id , options )
179+ self .add_slash_command (cmd , name , description , auto_convert , guild_ids , options )
131180 return cmd
132181 return wrapper
133182
@@ -138,7 +187,7 @@ def subcommand(self,
138187 name = None ,
139188 description : str = None ,
140189 auto_convert : dict = None ,
141- guild_id : int = None ):
190+ guild_ids : int = None ):
142191 """
143192 Decorator that registers subcommand.
144193 Unlike discord.py, you don't need base command.
@@ -159,7 +208,7 @@ async def _group_say(ctx, _str):
159208 :param name: Name of the subcommand. Default name of the coroutine.
160209 :param description: Description of the subcommand. Default ``None``.
161210 :param auto_convert: Dictionary of how to convert option values. Default ``None``.
162- :param guild_id: Guild ID of where the command will be used. Default ``None``, which will be global command.
211+ :param guild_ids: List of guild ID of where the command will be used. Default ``None``, which will be global command.
163212 :return:
164213 """
165214 def wrapper (cmd ):
@@ -220,25 +269,24 @@ async def on_socket_response(self, msg):
220269 if msg ["t" ] != "INTERACTION_CREATE" :
221270 return
222271 to_use = msg ["d" ]
223- print (to_use )
224272 if to_use ["data" ]["name" ] in self .commands .keys ():
225273 selected_cmd = self .commands [to_use ["data" ]["name" ]]
226274 ctx = model .SlashContext (self .req , to_use , self ._discord )
227- if selected_cmd ["guild_id " ]:
228- if selected_cmd [ "guild_id" ] != ctx .guild .id :
275+ if selected_cmd ["guild_ids " ]:
276+ if ctx .guild .id not in selected_cmd [ "guild_ids" ] :
229277 return
230278 if selected_cmd ["has_subcommands" ]:
231- return await self .handle_subcommand (to_use )
279+ return await self .handle_subcommand (ctx , to_use )
232280 args = self .process_options (ctx .guild , to_use ["data" ]["options" ], selected_cmd ["auto_convert" ]) \
233281 if "options" in to_use ["data" ] else []
234282 self .logger .debug (f"Command { to_use ['data' ]['name' ]} invoked." )
235283 await selected_cmd ["func" ](ctx , * args )
236284
237- async def handle_subcommand (self , data : dict ):
285+ async def handle_subcommand (self , ctx : model . SlashContext , data : dict ):
238286 """
239287 Coroutine for handling subcommand.
240288
289+ :param ctx:
241290 :param data:
242- :return:
243291 """
244292 pass
0 commit comments