A Python wrapper for discord slash-commands, designed to extend discord.py.

Overview

dislash.py

Discord PyPi Python

An extending library for discord.py that allows to build awesome slash-commands.

Star us on GitHub - we do really need your feedback and help!

Installation

Run any of these commands in terminal:

pip install dislash.py
python -m pip install dislash.py

Features

  • Supports automatic registration of slash-commands
  • Supports manual and automatic sharding
  • Convenient decorator-based interface
  • OOP-based slash-command constructor

Examples

💡 This library does require discord.py installed.

Creating a slash-command

In this example registration is automatic. If you want to register slash-commands separately, see examples below.

from discord.ext import commands
from dislash import slash_commands
from dislash.interactions import *

client = commands.Bot(command_prefix="!")
slash = slash_commands.SlashClient(client)
test_guilds = [12345, 98765]

@slash.command(
    name="hello", # Defaults to function name
    description="Says hello",
    guild_ids=test_guilds # If not specified, the command is registered globally
    # Global registration takes more than 1 hour
)
async def hello(inter):
    await inter.reply("Hello!")

client.run("BOT_TOKEN")

Registering a slash-command

This example only shows how to register a slash-command.

from discord.ext import commands
from dislash import slash_commands
from dislash.interactions import *

client = commands.Bot(command_prefix="!")
slash = slash_commands.SlashClient(client)
test_guild_ID = 12345

@slash.event
async def on_ready():
    sc = SlashCommand(
        name="random",
        description="Returns a random number from the given range",
        options=[
            Option(
                name="start",
                description="Enter a number",
                required=True,
                type=Type.INTEGER
            ),
            Option(
                name="end",
                description="Enter a number",
                required=True,
                type=Type.INTEGER
            )
        ]
    )
    await slash.register_global_slash_command(sc)
    # Discord API uploads GLOBAL commands for more than 1 hour
    # That's why I highly recommend .register_guild_slash_command for testing:
    await slash.register_guild_slash_command(test_guild_id, sc)

client.run("BOT_TOKEN")

You should register a slash-command only once in order to make it work. You can always edit it if you want, using .edit_global_slash_command / .edit_guild_slash_command methods.

Responding to a slash-command

It's assumed that you've already registered the command.

from random import randint
from discord.ext import commands
from dislash import slash_commands
from dislash.interactions import *

client = commands.Bot(command_prefix="!")
slash = slash_commands.SlashClient(client)

@slash.command()
async def random(interaction):
    # interaction is instance of `interactions.Interaction`
    # It's pretty much the same as "ctx" from discord.py
    # except  attribute is replaced by 
    a = interaction.data.get_option('start').value
    b = interaction.data.get_option('end').value
    if b < a: a, b = b, a
    await interaction.reply(randint(a, b))

client.run("BOT_TOKEN")

Links

Documentation

PyPi

Our Discord

Comments
  • Use versions for pip packages

    Use versions for pip packages

    As long as you use "latest" without a version, we need to uninstall and reinstall the dislash.py entirely to get the latest features, such as ContextMenus.

    opened by f11y11 4
  • Slash command interaction is expired on arrival

    Slash command interaction is expired on arrival

    When testing a simple slash command using dislash, when i get to the callback that handles the slash command, the interaction is already expired. The code i'm using to test this:

        @slash_commands.command(
            name="maybe_this_works",
            description="testing slash commands",
            guild_ids=[GUILD_ID]
        )
        async def maybe_this_works(self, inter:Interaction):
            logger.debug(inter)
            logger.debug("snowflake time: " + inter.created_at.isoformat())
            logger.debug("current time: " + dt.datetime.utcnow().isoformat())
            logger.debug("is expired: " + str(inter.expired))
            logger.debug("is sent: " + str(inter._sent))
            await inter.reply("hello!")
    

    Output in discord: image Output in logs:

        vote     | maybe_this_works |   47 | DEBUG    | snowflake time: 2021-08-04T15:21:41.611000
        vote     | maybe_this_works |   48 | DEBUG    | current time: 2021-08-04T18:21:41.803420
        vote     | maybe_this_works |   49 | DEBUG    | is expired: True
        vote     | maybe_this_works |   50 | DEBUG    | is sent: False
    

    Result of the logs show that the time being reported by interaction.created_at is not calculated as UTC.

    It seems interaction.expired uses interaction.created_at which in turn uses a dislash.py specific implementation of snowflake_time that does not force the timestamp to be created in UTC+0: https://github.com/EQUENOS/dislash.py/blob/5b6d6b19ec078c914c9110b8c1a6a333145ec785/dislash/interactions/interaction.py#L15-L18 https://github.com/EQUENOS/dislash.py/blob/5b6d6b19ec078c914c9110b8c1a6a333145ec785/dislash/interactions/interaction.py#L98-L110

    This differs from discord.py's implementation, which forces the timestamp to be calculated in UTC+0:

    def snowflake_time(id: int) -> datetime.datetime:
        """
        Parameters
        -----------
        id: :class:`int`
            The snowflake ID.
        Returns
        --------
        :class:`datetime.datetime`
            An aware datetime in UTC representing the creation time of the snowflake.
        """
        timestamp = ((id >> 22) + DISCORD_EPOCH) / 1000
        return datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc)
    

    If I change dislash's function to use either datetime.datetime.utcfromtimestamp, or discord.py's implementation of snowflake_time, the problem goes away and the interaction is no longer considered expired on arrival.

    I can make a pull request to fix that if it would help, I just needed to know which route would you rather use to fix that (change dislash.py's implementation or adopt discord.py's function instead).

    opened by diogoriba 4
  • Unknown Webhook when ApplicationID no equal UserID

    Unknown Webhook when ApplicationID no equal UserID

    I've only messed with Buttons, but I consistently get Unknown Webhook on one bot. Someone else suggested that it is likely due to the Bot's UserID not being the same as the ApplicationID. In this case, that is true. The App was originally personal but was moved to a team, so that is likely when it changed. Maybe I'm missing something, I haven't fully explored everything yet

    Jun 16 02:15:32 python[407319]: Traceback (most recent call last):
    Jun 16 02:15:32 python[407319]:   File "/mnt/discord/red-data/scgc/cogs/CogManager/cogs/rps/rps.py", line 143, in on_rock
    Jun 16 02:15:32 python[407319]:     await inter.reply(type=ResponseType.DeferredUpdateMessage)
    Jun 16 02:15:32 python[407319]:   File "/mnt/discord/red-data/scgc/cogs/Downloader/lib/dislash/interactions/interaction.py", line 204, in reply
    Jun 16 02:15:32 python[407319]:     return await self.fetch_initial_response()
    Jun 16 02:15:32 python[407319]:   File "/mnt/discord/red-data/scgc/cogs/Downloader/lib/dislash/interactions/interaction.py", line 392, in fetch_initial_response
    Jun 16 02:15:32 python[407319]:     data = await self._client.http.request(
    Jun 16 02:15:32 python[407319]:   File "/home/red/envs/scgc/lib/python3.8/site-packages/discord/http.py", line 250, in request
    Jun 16 02:15:32 python[407319]:     raise NotFound(r, data)
    Jun 16 02:15:32 python[407319]: discord.errors.NotFound: 404 Not Found (error code: 10015): Unknown Webhook
    
    bug good first issue 
    opened by yamikaitou 4
  • Slash Command duplicate and wont change name

    Slash Command duplicate and wont change name

    So i tried to made a slash command code:

    #Slash Command
    
    slash=SlashClient(Tango())
    
    @slash.command(
        name="echo",
    	description="Echo word that you specified",
        options=[
            Option("word", "Specify a word that will get send", Type.STRING, required=True)
        ]
    )
    async def echo(inter, *,word):
    	await inter.reply(word, allowed_mentions=discord.AllowedMentions(everyone=False, users=False, roles=False, replied_user=True))
    

    and it work but, i may found or cause a bug. The slash command name is echo and basically echo an argument but, i accidentally duplicate the command. The echo command and its duplicate work fine but if i remove the command, both name still registered in the bot data and the slash command wont change name if i change the function name, and of course cause errors, one of them is "This interaction failed" and "Invalid interaction application command". My question is, how did the command duplicate and how do i remove it from the bot data? slash_command

    opened by TheGenocides 3
  • TypeError: emoji() takes 1 positional argument but 2 were given

    TypeError: emoji() takes 1 positional argument but 2 were given

        @inter_client.slash_command(guild_ids=bonbot_support)
        async def emoji(ctx):
            pass
        @emoji.sub_command(description="steal an emoji with an option to lock it to a role", options=[Option("emoji", "an emoji to steal", OptionType.STRING, required=True),
        Option("role", "A role to lock this emoji to. (User must have this role to use emoji)", OptionType.ROLE)], guild_ids=bonbot_support)
        @slash_commands.guild_only()
        @slash_commands.has_permissions(manage_emojis=True)
        async def steal(self, ctx, emoji, role):
            c = commands.EmojiConverter() # create instance
            emoji_final = await c.convert(emoji) 
            # fetch the emoji asset and read it as bytes.
            emoji_bytes = await emoji_final.read()
    
            emoji_roles = [role]
            await ctx.guild.create_custom_emoji(name=emoji_final.name, image=emoji_bytes, roles=emoji_roles)
            await ctx.send("Created emoji!", ephemeral=True)
    

    I get this error when I run this code, I even added print("number") after every step and it doesn't print anything. Not sure what is happening, I have asked for help in several servers and nobody can figure it out. When I run the same code as a regular command, (removing the components parts) it works flawlessly. Full error: https://mystb.in/UrwPutsGarlic.apache

    opened by eltaylor1104 2
  • TypeError: object of type 'ActionRow' has no len()

    TypeError: object of type 'ActionRow' has no len()

    NOTE: ONLY HAPPENS IN COGS The Code:

    from dislash import *
    @commands.command()
    async def cmd(self,ctx,arg):
    	row = ActionRow(
    		Button(style=ButtonStyle.green, label="My Label Here!!", custom_id="tx")
    	)
    	def check(inter):
    		return inter.author == ctx.author and inter.author.guild_permissions.manage_emojis
    	try:
    		# SOME SHIT HERE!!
    	except:
    		# COUNTER
    
    

    Precise Output in the Terminal:

    File "/MY_DIRS/python/lib/python3.9/site-packages/dislash/application_commands/_modifications/old.py", line 105, in send_with_components
         if len(components) > 5:
    TypeError: object of type 'ActionRow' has no len()
    

    EDIT: Markdown changes

    opened by v1s1t0r999 2
  • Reset Cooldown Doesn't Work

    Reset Cooldown Doesn't Work

    I try to use slash_core.BaseSlashCommand.reset_cooldown(inter) to reset the cooldown. But it shows this error: reset_cooldown() missing 1 required positional argument: 'inter'

    Then I try this: slash_core.BaseSlashCommand.reset_cooldown(self, inter) But it still shows the error: 'SlashCommand' object has no attribute '_buckets'

    opened by LextYi 2
  • Patch to fix decorators in between @slash_commands.command decorator and final function

    Patch to fix decorators in between @slash_commands.command decorator and final function

    Previously if an additional decorator was in between the @slash_commands.command decorator and command function, the provided options would not be unpacked.

    The issue arises from: https://github.com/EQUENOS/dislash.py/blob/ef33dee6b5b95ec77fa4ffd9201e2b689020d108/dislash/slash_commands/slash_core.py#L97-L103 Specifically where __code__ is called. __code__ represents the decorated code, even if functools.wraps is used - and thus the calculated argcount is from the wrapper function - not the internal one. This causes _uses_ui to evaluate to false and params set to be equal to {} as shown here: https://github.com/EQUENOS/dislash.py/blob/ef33dee6b5b95ec77fa4ffd9201e2b689020d108/dislash/slash_commands/slash_core.py#L123-L126 The solution is to use inspect to unwrap the function beforehand (inspect.unwrap(func) so that __code__ correctly points to the code of the actual function

    opened by dob9601 2
  • Allow for decorator chaining when a decorator modifies the kwargs

    Allow for decorator chaining when a decorator modifies the kwargs

    I've got a decorator that adds an additional kwarg to a function and have been using this with the default discord.py framework. This decorator helps integrate django with discord.py by using the user id in the context to fetch the user object from the django database. However, due to the code shown here: https://github.com/EQUENOS/dislash.py/blob/6aa5f28c6c43799d9af089a2b98cf61affb978f7/dislash/slash_commands/slash_core.py#L365-L374 That kwarg never actually reaches the function. Would it be possible to add support for additional custom kwargs by exposing all additional kwargs to the command function?

    opened by dob9601 2
  • Interaction is subscriptable now

    Interaction is subscriptable now

    I haven't tested this yet, but it should work fine. Old syntax:

    inter.get('option_name')
    inter.option_at(1).value
    

    New syntax:

    inter['option_name']
    inter[1]
    
    opened by m1raynee 2
  • ModuleNotFoundError when trying to import dislash

    ModuleNotFoundError when trying to import dislash

    When trying to import dislash.py, a ModuleNotFoundError: No module named 'discord.webhook.async_' is raised.

    Full traceback: Traceback (most recent call last): File "main.py", line 2, in import threading, dislash File "/opt/virtualenvs/python3/lib/python3.8/site-packages/dislash/init.py", line 4, in from .interactions import * File "/opt/virtualenvs/python3/lib/python3.8/site-packages/dislash/interactions/init.py", line 1, in from .interaction import * File "/opt/virtualenvs/python3/lib/python3.8/site-packages/dislash/interactions/interaction.py", line 13, in from discord.webhook.async_ import WebhookMessage ModuleNotFoundError: No module named 'discord.webhook.async_'

    opened by rf20008 1
  • typing mismatch python version

    typing mismatch python version

    dislash/interactions/types.py

    attempts to import TypedDict which was added in 3.8 does not match the python ver requirement in setup.py for python_requires='>=3.6`

    opened by MujyKun 0
  • ERROR IN DOCS

    ERROR IN DOCS

    Here is what I found in the docs of dislash.py

        def check(inter):
            # inter is instance of MessageInteraction
            # read more about it in "Objects and methods" section
            if inter.author == ctx.author
        # Wait for a menu click under the message you've just sent
        inter = await msg.wait_for_dropdown(check)
        # Tell which options you received
        labels = [option.label for option in inter.select_menu.selected_options]
        await inter.reply(f"Your choices: {', '.join(labels)}")
    

    It is noticible that there is no colon after if inter.author ==ctx.author nor the indentation level is equal

    opened by prakarsh17 0
  • Error when I start the server

    Error when I start the server

    I get this error when I start the server. The 1st request doesn't work. When I print the ctx, the channel is None for the 1st request but isn't for the next ones. Then I have this error when I use : await ctx.send(...)

    Ignoring exception in on_socket_response
    Traceback (most recent call last):
      File "/opt/anaconda3/envs/project/lib/python3.9/site-packages/discord/client.py", line 343, in _run_event
        await coro(*args, **kwargs)
      File "/opt/anaconda3/envs/project/lib/python3.9/site-packages/dislash/slash_commands/slash_client.py", line 1050, in _on_socket_response
        await self._process_interaction(payload["d"])
      File "/opt/anaconda3/envs/project/lib/python3.9/site-packages/dislash/slash_commands/slash_client.py", line 1137, in _process_interaction
        raise err
      File "/opt/anaconda3/envs/project/lib/python3.9/site-packages/dislash/slash_commands/slash_client.py", line 1134, in _process_interaction
        await slash_parent.invoke(inter)
      File "opt/anaconda3/envs/project/lib/python3.9/site-packages/dislash/slash_commands/slash_core.py", line 342, in invoke
        raise err
      File "/opt/anaconda3/envs/project/lib/python3.9/site-packages/dislash/slash_commands/slash_core.py", line 338, in invoke
        await self._maybe_cog_call(self._cog, interaction, interaction.data)
      File "/opt/anaconda3/envs/project/lib/python3.9/site-packages/dislash/slash_commands/slash_core.py", line 131, in _maybe_cog_call
        return await self(inter, **params)
      File "/opt/anaconda3/envs/project/lib/python3.9/site-packages/dislash/slash_commands/slash_core.py", line 95, in __call__
        return await self.func(*args, **kwargs)
      File "project/src/main.py", line 473, in add_notif
        await msg.delete()
      File "/opt/anaconda3/envs/project/lib/python3.9/site-packages/discord/message.py", line 1023, in delete
        await self._state.http.delete_message(self.channel.id, self.id)
    AttributeError: 'NoneType' object has no attribute 'id'
    

    I tried with bot.command and it works

    @bot.command(
        name="add_notif"
    )
    

    But not when I use slash.command

    
    @slash.command(
        name="add_notif"
    )
    
    opened by YoanGab 6
Releases(v1.4.8)
Owner
I'm a student of Moscow State University, studying math. I love searching simple solutions of hard problems.
A simple Discord bot wrote with Python. Kizmeow let you track your NFT project and display some useful information

Kizmeow-OpenSea-and-Etherscan-Discord-Bot 中文版 | English Ver A Discord bot wrote with Python. Kizmeow let you track your NFT project and display some u

Xeift 93 Dec 31, 2022
Personal Discord Python Bot based on Discord.py

Personal Discord bot using the discord.py library by Rapptz

2 Dec 14, 2022
Deploy your apps on any Cloud provider in just a few seconds

The simplest way to deploy your apps in the Cloud Deploy your apps on any Cloud providers in just a few seconds ⚡ Qovery Engine is an open-source abst

Qovery 1.9k Dec 26, 2022
Compares and analyzes GCP IAM roles.

gcp-iam-analyzer I wrote this to help in my day to day working in GCP. A lot of the time I am doing role comparisons to see which role has more permis

Jason Dyke 37 Dec 28, 2022
A tool for extracting plain text from Wikipedia dumps

WikiExtractor WikiExtractor.py is a Python script that extracts and cleans text from a Wikipedia database dump. The tool is written in Python and requ

Giuseppe Attardi 3.2k Dec 31, 2022
Bot inspirado no Baidu Antivírus

Baidu Bot Bot inspirado no lendário Baidu Antivírus Informações O programa foi inteiramente feito em Python, sinta-se livre para fazer qualquer altera

Caio Eduardo de Albuquerque Magalhães 1 Dec 18, 2021
Amanda-A next gen powerful telegram group manager bot for manage your groups and have fun with other cool modules.

Amanda-A next gen powerful telegram group manager bot for manage your groups and have fun with other cool modules.

Team Amanda 4 Oct 21, 2022
Simple python program to execute terminal commands on telegram chats directly.

Small python code which can be handy when using telegram and you don't want to use VPS again and again. By configuring the code in your VPS, You can execute commands and get your output within telegr

Veshraj Ghimire 34 Dec 05, 2022
⬇️ Telegram Bot to download TikTok videos without watermark in a snap with Inline mode support.

⬇️ Tokmate - Telegram Bot to download TikTok videos ⛲ Features Superfast and supports all type of TikTok links Download any TikTok videos without mate

Hemanta Pokharel 35 Jan 05, 2023
A modular Telegram Python bot running on python3 with a sqlalchemy, redis, telethon.

GilbertAnimeBot A modular Telegram Python bot running on python3 with a sqlalchemy, redis, telethon. How to setup/deploy. Read these notes carefully b

Kishore 1 Jan 23, 2022
My homeserver setup. Everything managed securely using Portainer.

homeserver-traefik-portainer Features: access all services with free TLS from letsencrypt using your own domain running a side project is super simple

Tomasz Wójcik 44 Jan 03, 2023
Fully asynchronous trace.moe API wrapper

AioMoe Fully asynchronous trace.moe API wrapper Installation You can install the stable version from PyPI: $ pip install aiomoe Or get it from github

2 Jun 26, 2022
stories-matiasucker created by GitHub Classroom

Stories do Instagram Este projeto tem como objetivo desenvolver uma pequena aplicação que simule os efeitos e funcionalidades ao estilo Instagram. A a

1 Dec 20, 2021
A simple chat api that can also work with ipb4 and chatbox+

SimpleChatApi API for chatting that can work on its own or work with Invision Community and Chatbox+. You are also welcome to create frontend for this

Anubhav K. 1 Feb 01, 2022
Telegram bot to clip youtube videos

youtube-clipper-bot Telegram bot to clip youtube videos How to deploy? Create a file called config.env BOT_TOKEN: Provide your bot token generated by

Shivam Jha 11 Dec 10, 2022
Decrypt PSSE layer of PSM Games (on PC)

psse-decrypt Decrypt PSSE layer of PSM Games (on PC) Works on Unity and PSM games, and meets all requirements of: https://github.com/vita-nuova/bounti

Bluzume 32 Oct 11, 2022
Unofficial YooMoney API python library

API Yoomoney - unofficial python library This is an unofficial YooMoney API python library. Summary Introduction Features Installation Quick start Acc

Aleksey Korshuk 136 Dec 30, 2022
BingBot - A bot that will automate searches on bing

bingBot A bot that will automate searches on bing. To install this just download

Lukas 2 Jul 28, 2022
CyberTKR - CyberTK-API

CyberTKR - CyberTK-API

TKR 2 Apr 08, 2022
Telegram bot/scraper to get the latest NUS vacancy reports.

Telegram bot/scraper to get the latest NUS vacancy reports. Stay ahead of the curve and don't get modrekt.

Chee Hong 1 Jan 08, 2022