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.
Sniper for Anigame and Izzi discord bots!

Anigame Sniper Gen-3 Features Inbuilt Spammer Responds to your messages in discord (on/off) Snipes only where you want it to Set latency so that the b

22 Nov 13, 2022
We have made you a wrapper you can't refuse

We have made you a wrapper you can't refuse We have a vibrant community of developers helping each other in our Telegram group. Join us! Stay tuned fo

20.6k Jan 04, 2023
Discord bot to display private leaderboards for Advent of Code.

Advent Of Code Discord Bot Discord bot for displaying Advent of Code private leardboards, as well as custom leaderboards where participants can set th

The Future Gadgets Lab 6 Nov 29, 2022
Download archived malware from ActiveState's source code mirror

malware-archivist (ma) Tool to aid security researchers in dissecting malware. Often, repository maintainers will remove malicious packages entirely f

ActiveState Software 28 Dec 12, 2022
An example of a chatbot with a number-based menu that can be used as a starting point for a project.

NumMenu Bot NumMenu Bot is an example chatbot showing a way to design a number-based menu assistant with Rasa. This type of bot is very useful on plat

Derguene 19 Nov 14, 2022
Yes, it's true :orange_heart: This repository has 346 stars.

Yes, it's true! Inspired by a similar repository from @RealPeha, but implemented using a webhook on AWS Lambda and API Gateway, so it's serverless! If

512 Jan 01, 2023
Example notebooks for working with SageMaker Studio Lab. Sign up for an account at the link below!

SageMaker Studio Lab Sample Notebooks Available today in public preview. If you are looking for a no-cost compute environment to run Jupyter notebooks

Amazon Web Services 304 Jan 01, 2023
THERE IS AN IMPOSTER AMONG US. VOTE HIM OUT BEFORE HE [ R E D A C T E D ].

🛡️ Guardian There is an impostor among us. Can you help us find out who it is? ⚙️ Installation and Usage Make sure to install Tesseract-OCR before ru

Catus Magnus 1 Jan 06, 2022
An Simple Advance Auto Filter Bot Complete Rewritten Version Of Adv-Filter-Bot

Adv Auto Filter Bot V2 This Is Just An Simple Advance Auto Filter Bot Complete Rewritten Version Of Adv-Filter-Bot.. Just Sent Any Text As Query It Wi

0 Dec 18, 2021
A web app via which users can buy and sell stocks using virtual money

finance Virtual Stock Trader. A web app via which users can buy and sell stocks using virtual money. All stock prices are real and provided by IEX. Fe

Kiron Deb 0 Jan 15, 2022
This library is for simplified work with the sms-man.com API

SMSMAN Public API Python This is a lightweight library that works as a connector to Sms-Man public API Installation pip install smsman Documentation h

13 Nov 19, 2022
A youtube search telegram bot.

YouTube-Search-Bot A youtube search telegram bot. Made with Python3 (C) @FayasNoushad Copyright permission under MIT License License - https://github

Fayas Noushad 22 Nov 12, 2022
A zero-dependency Python library for getting the Kubernetes token of a AWS EKS cluster

tokeks A zero-dependency Python library for getting the Kubernetes token of a AWS EKS cluster. No AWS CLI, third-party client or library (boto3, botoc

Chris Karageorgiou Kaneen 6 Nov 04, 2022
Small Python Tracker clone of Electra

Discord Bot Tracker - Python Simply Track your Bots (Status) to get notified when one of those go offline/online. Paste IDs into the config.py files,

Koni 2 Nov 23, 2021
Plataforma para atendimento a outras empresas que necessitam de atendimento técnico.

Plataforma para atendimento a outras empresas que necessitam de atendimento técnico. É possível que os usuarios de empresas parceiras registrem solici

Kelvin Alisson Cantarino 2 Jun 29, 2022
Student-Management-System-in-Python - Student Management System in Python

Student-Management-System-in-Python Student Management System in Python

G.Niruthian 3 Jan 01, 2022
This is a crypto trading bot that scans the Binance Annoucements page for new coins, and places trades on Gateio

gateio-trading-bot-binance-announcements This Gateio x Binance cryptocurrency trading bot scans the Binance Announcements page and picks up on new coi

Andrei 1.2k Jan 01, 2023
Twitter bot code can be found in twitterBotAPI.py

NN Twitter Bot This github repository is BASED and is yanderedev levels of spaghetti Neural net code can be found in alexnet.py. Despite the name, it

167 Dec 19, 2022
A python api to get info on covid-19

A python api to get info on covid-19

roof 2 Sep 18, 2022
ZenML 🙏: MLOps framework to create reproducible ML pipelines for production machine learning.

ZenML is an extensible, open-source MLOps framework to create production-ready machine learning pipelines. It has a simple, flexible syntax, is cloud and tool agnostic, and has interfaces/abstraction

ZenML 2.6k Dec 27, 2022