nafteam / naff Goto Github PK
View Code? Open in Web Editor NEWA Python API wrapper for Discord
Home Page: https://naff.info
License: MIT License
A Python API wrapper for Discord
Home Page: https://naff.info
License: MIT License
Describe the solution you'd like
Option to send webhooks to thread. docs
Additional information
We already have HTTP support and the execute function support it.
https://github.com/Discord-Snake-Pit/Dis-Snek/blob/69d06dd21c43e23b6d1b5c5e1ad2796ae1e46cea/dis_snek/api/http/http_requests/webhooks.py#L106
I just don't see it ever used.
Current webhook send: https://github.com/Discord-Snake-Pit/Dis-Snek/blob/25bb9683e0f559825f0f6f3294a0cfe916282419/dis_snek/models/discord/webhooks.py#L132
Is your feature request related to a problem? Please describe.
Checks are actually useless as is.
There's no way to get information about which check failed if a command has multiple, and no useful information comes out of them for the sake of error messages
Describe the solution you'd like
Add information about which check failed, and possibly why to CommandCheckFailure
Describe alternatives you've considered
N/A
Additional information
N/A
Describe the bug
A clear and concise description of what the bug is.
ephemeral=True
is passed and the message flag is set, yet the message is not hidden.
To Reproduce
The code you used to produce this bug, must be in a code-block:
Respond to a ComponentContext
with ctx.send("stuff", **ephemeral=True)
**
Expected behaviour
A clear and concise description of what you expected to happen.
A hidden message appears
Additional information
Any other information about the problem.
Is your feature request related to a problem? Please describe.
Message commands are limited, honestly. They have many problems, least of which is the fact that multiple arguments with differing types is a pain and subcommands are basically not happening with them.
Describe the solution you'd like
A system very much like discord.py
's message commands: a nice, mostly sane system to do everything a person would need.
@message_command()
async def command(self, ctx, num: int, user: User):
...
Describe alternatives you've considered
Doing it yourself with the command arguments, which isn't pleasant, speaking from experience.
It's about about time we pointed out molter
exists, but molter
will have to do more and more hacks to get things working as time goes on, and not every new user will know what molter
is.
Additional information
See molter
's #3 for what needs to be done to merge molter
here, which would solve the issue.
Under no circumstances should this issue hold back the beta release. Polls and I have agreed it will not count towards it. It is under the milestone anyways to place a soft-soft deadline on myself.
Is your feature request related to a problem? Please describe.
I'm always frustrated when inconsistency
Describe the solution you'd like
All methods to define application commands should have consistent signatures - same args, same type hinting, same defaults. Functions, decorators, class methods, class inits, all of them. Same goes to slash command options and their definition methods
Tasks:
As mentioned above.
Describe the bug
Embed.footer doesn't work properly.
To Reproduce
from dis_snek import Embed, EmbedFooter
Embed(footer=EmbedFooter()) # will raise an error
Expected behaviour
The signature expects EmbedFooter
or None
but the code only works with dict
(or None
).
Additional information
pip freeze: dis_snek==6.0.0
Requested by @BoredManCodes over discord
Is your feature request related to a problem? Please describe.
As of today, Modal Interactions are official. An announcement was made in the Discord Developers server today.
Describe the solution you'd like
An implementation of Modal Interactions
Describe alternatives you've considered
None
Additional information
See https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-modal
Is your feature request related to a problem? Please describe.
Discord has started to let us test application command localization (slash and context menus)
Describe the solution you'd like
We need an intuitive and efficient way for a developer to provide localization for their application commands.
Additional information
For anyone looking to attempt this, here is the build override (just paste in discord and click):
https://discord.com/__development/link?s=GBxWH9lkrFwWI3HEiYg%2FshrD8kLcqS2NHnJn0rgceNU%3D.eyJ0YXJnZXRCdWlsZE92ZXJyaWRlIjp7ImRpc2NvcmRfd2ViIjp7InR5cGUiOiJicmFuY2giLCJpZCI6ImZlYXR1cmUvd2ViLXNsYXNoLWNvbW1hbmQtbG9jYWxpemF0aW9uIn19LCJyZWxlYXNlQ2hhbm5lbCI6bnVsbCwidmFsaWRGb3JVc2VySWRzIjpbXSwiYWxsb3dMb2dnZWRPdXQiOmZhbHNlLCJleHBpcmVzQXQiOiJXZWQsIDA2IEFwciAyMDIyIDE4OjI2OjUyIEdNVCJ9
And here are the docs: https://discord.com/developers/docs/interactions/application-commands#localization
Is your feature request related to a problem? Please describe.
As of today, Application Command Attachment Options Types are official. An announcement was made in the Discord Developers server today.
Describe the solution you'd like
An implementation of Application Command Attachment Options Types
Describe alternatives you've considered
None
Additional information
See https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-type
Describe the bug
Exception when using EmbedAuthor in Embed constructor
{'code': 50035, 'errors': {'data': {'embeds': {'0': {'author': {'name': {'_errors': [{'code': 'STRING_TYPE_CONVERT', 'message': 'Could not interpret "{\'name\': \'test\'}" as string.'}]}}}}}}, 'message': 'Invalid Form Body'}
To Reproduce
embed = Embed(description="desc", author=EmbedAuthor("test"))
await ctx.send(embed=embed)
Expected behaviour
Be able to use EmbedAuthor in Embed constructor. Typing: Embed author: Optional[EmbedAuthor]
Additional information
Any other information about the problem.
Describe the bug
GuildVoice.position
is not working as it should
To Reproduce
Look at a category channel and compare the positions of the channels. Voice channels are not ordered, text channels are ordered correctly, but start at position = 2
instead of 0/1.
Expected behaviour
GuildVoice.position
reflects the position on discord
Additional information
Discord Link
Describe the bug
A clear and concise description of what the bug is.
User.mutual_guilds is broken since User.user_guilds does not exist
To Reproduce
The code you used to produce this bug, must be in a code-block:
Try to use User.mutual_guilds
Expected behaviour
A clear and concise description of what you expected to happen.
A list of mutual guilds
Additional information
Any other information about the problem.
Too tired to fix myself, this also looks like it may be annoying to fix
Dump of flaws, discussed in contributors channel, found in the event processors. I'll check off each of these as theyre resolved
_on_raw_channel_delete
does not delete channel from cache, it shoud_on_raw_guild_delete
Unresolved attribute reference 'user' for class 'GuildEvents'_on_raw_guild_delete
does not delete guild from cache_on_raw_guild_delete
should iterate through users and remove guild ids from sets in cache.user_guilds_on_raw_guild_delete
event.data.get("id") should be int(event.data.get("id"))._on_raw_guild_ban_add
, _on_raw_guild_ban_remove
should update members obj, or members set in guild or something_on_raw_guild_emojis_update
for the love of god make before and after proper variables, that's unradable_on_raw_message_delete
does not delete message from cache_on_raw_thread_delete
does not delete threads from cachePlease tag this issue in your commits/prs if they fix something here
It's a whole bunch of TypedDicts that let static type checkers better know the contents of the HTTP responses
https://pypi.org/project/discord-typings/
Definitely a nice-to-have
Is your feature request related to a problem? Please describe.
When creating multiple bot instances, only one continues to send heartbeats and remain active.
Describe the solution you'd like
The best solution would be the ability to create as many instances of Snake, and use login() in a task to have them all connect separately.
Describe alternatives you've considered
The alternatives all would require creating separate processes and using pipes or IPC to communicate between instances which is extreme pain.
Is your feature request related to a problem? Please describe.
I'm always frustrated when no callback decorator for modals. In some cases it allows for cleaner code than usage of wait_for_modal
Describe the solution you'd like
Modals should have the same persistent callback system we use for components, including callback decorators.
Describe the bug
I know, weird wording, but the first part is what people run into 90% of the time, while the second is the actual underlying issue.
Anyways, users have recently told us that trying to reply to a message in DMs fails. Furthermore, the error message shows that it's unable to get the DM channel needed in the first place, as it returns None
.
It was reported that this was working fine in earlier versions, so there may be a regression here. I am unsure if this bug appears in the master
branch, but it does for sure in dev
.
To Reproduce
After updating I am getting an error upon DM replies. The repro would be doing something like
```python
@listen()
async def on_message_create(self, event: MessageCreate) -> None:
if not event.message.guild:
await event.message.reply("Pong!")
Expected behaviour
The user to be DMed 'Pong!'
Instead, we get a basic "'NoneType' has no attribute 'send'."
Describe the bug
As far as I can tell, there is no way to actually use permission overwrites to edit permissions on a channel. Getting existing overwrites returns the overwrite, but there is no way to link the overwrite to a user/role as it currently stands.
To Reproduce
# List all overwrites and show the IDs
overwrites = channel._permission_overwrites
overwrites
# Will output false
any(x in guild._role_ids or x in guild._member_ids for x in overwrites.keys())
Expected behaviour
Overwrites should have a clear link to the user/role that they are attached to, as well as a way to actually utilize them in a meaningful way (i.e. channel.edit_permissions(type=OverwriteTypes.ROLE, target=role, deny=Permissions.READ_MESSAGES)
)
Additional information
This isn't so much of a bug as a missing feature, but is also a bug because it is currently impossible to edit permissions afaik.
In reality, it's blocked for less than 0.1 seconds, but that's still unacceptable
Add "delete_after" as an optional param to .send functions, like how its done in d.py. If you want to send temp messages which should be deleted after x amount of seconds the delete_after param would be very convenient. :D.
I would also use float as type like d.py, because its the most accurate.
Quick and easy, I think. As simple and convenient as it sounds like :3.
Describe the bug
Discord will only populate the channel_mentions
key of a message if textual channels that are visible to everyone in a lurkable guild
are in the message. Obviously this isnt ideal and causes confusion as channels are clearly mentioned, but not available in the message object.
Also the default value of message.channel_mentions
is None, it should be []
Categorised as a bug
as this is not user-expected behaviour, however it could be argued that its api-expected behaviour
To Reproduce
If you have acceess to the test guild, look here: https://canary.discord.com/channels/701347683591389185/945763271384891424/945936910793199666
Otherwise, send a message mentioning a channel not everyone can see.
Expected behaviour
All channels mentioned and known by the bot are in this list
Describe the bug
When you set the footer in the embed class you get an erorr.
To Reproduce
The code you used to produce this bug, must be in a code-block:
@dis.message_command("embed")
async def embed(ctx: dis.MessageContext):
await ctx.send(embed=dis.Embed(title="test", description="test", footer="test"))
Expected behaviour
Send the embed
Traceback
Traceback (most recent call last):
File "D:\Dis-Snek\dis_snek\client\client.py", line 1418, in _dispatch_msg_commands
await self._run_message_command(command, context)
File "D:\Dis-Snek\dis_snek\client\client.py", line 1289, in _run_message_command
return await command(ctx)
File "D:\Dis-Snek\dis_snek\models\snek\command.py", line 102, in __call__
await self.call_callback(self.callback, context)
File "D:\Dis-Snek\dis_snek\models\snek\command.py", line 146, in call_callback
return await callback()
File "D:\Dis-Snek\bot.py", line 10, in embed
await ctx.send(embed=dis.Embed(title="test", description="test", footer="test"))
File "<attrs generated init dis_snek.models.discord.embed.Embed>", line 16, in __init__
_setattr('footer', __attr_converter_footer(footer))
File "D:\Dis-Snek\dis_snek\client\utils\converters.py", line 56, in optional_converter
return converter(val)
File "D:\Dis-Snek\dis_snek\client\mixins\serialization.py", line 67, in from_dict
return cls(**cls._filter_kwargs(data, cls._get_init_keys()))
File "D:\Dis-Snek\dis_snek\client\mixins\serialization.py", line 36, in _filter_kwargs
return {k: v for k, v in kwargs_dict.items() if k in keys}
AttributeError: 'str' object has no attribute 'items
Is your feature request related to a problem? Please describe.
I'm always frustrated when ext.Task.create(...)
doesn't work on methods in Scales
Describe the solution you'd like
ext.Task.create(...)
works on methods in Scales
Describe alternatives you've considered
Register scale methods as tasks out of the class (in setup function). It's ugly.
Additional information
Polls pls
Currently, either the coroutine name, or a stirng is used to determine which event to listen for. Support should be added for the actual event objects to be used as arguments for the decorator.
Describe the bug
From jan on discord
To Reproduce
i edited a channels name too fast (like 5 times with 5s in between) and it threw me this
- jan
Is your feature request related to a problem? Please describe.
There is no way to capture errors that occur within the scale.
Describe the solution you'd like
Add a error
decorator for the scale, similar to the per command error decorators
The problem is that it is currently not possible via NAFF to lock or archive threads via components, something which I personally would really appreciate. And since I heard that it is available in the API i'd really appreciate to have that feature in NAFF.
https://didnt-ask.de/wm6xXrEr <-- Screenshot.
Basically I press on a button and the Thread should be locked, which currently is not possible to do.
As said above. I want when I use components to be able to lock or archive or generally manage threads.
No response
No response
Describe the bug
Role colors are formatted backwards both in Role.color.hex
and in Role.color.rgb
, though oddly, embed colors are unaffected
To Reproduce
from dis_snek.models.discord.color import Color
c = Color.from_rgb(255, 0, 0)
print(c.hex)
print(c.r)
Also see https://git.zevaryx.com/stark-industries/j.a.r.v.i.s./-/blob/v2.0/jarvis/cogs/util.py#L131 for code that produced screenshot below
Expected behaviour
The proper colors to be represented
Additional information
Screenshot of the issue (thumbnails are generated from Role.color.rgb
). Top is my stable discord-interaction 3.0.2 bot, bottom is my dis-snek re-write bot.
any
When using slash command options max and mins and you change just max_value
or others the command does not sync
The command should sync with the new min_value
@naff.slash_command("int")
@naff.slash_option(
"int",
"test",
naff.OptionTypes.INTEGER,
min_value=0,
max_value=15, # Just change this value and command wont sync
)
async def test(ctx, string):
await ctx.send(string)
return "test"
No response
No response
Describe the bug
Events are broken
(Only in DM)
To Reproduce
bot = Snake(intents=Intents.ALL, sync_interactions=False, asyncio_debug=True)
The problem is same with MessageReactionAdd
, MessageReactionRemove
both:
@listen(MessageReactionAdd)
async def mra(e: MessageReactionAdd):
print('mra')
and
@listen(MessageReactionRemove)
async def mrr(e: MessageReactionRemove):
print('mrr')
If the message was sent before bot starting:
prints: nothing
logs:
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-45' coro=<ReactionEvents._on_raw_message_reaction_add() done, defined at PATH\dis_snek\api\events\processors\reaction_events.py:18> exception=AttributeError("'NoneType' object has no attribute 'guild'") created at PATH\python310\lib\asyncio\tasks.py:337>
source_traceback: Object created at (most recent call last):
File "PATH\bot.py", line 54, in <module>
bot.start("TOKEN")
File "PATH\dis_snek\client\client.py", line 602, in start
self.loop.run_until_complete(self.login(token))
File "PATH\python310\lib\asyncio\base_events.py", line 628, in run_until_complete
self.run_forever()
File "PATH\python310\lib\asyncio\windows_events.py", line 316, in run_forever
super().run_forever()
File "PATH\python310\lib\asyncio\base_events.py", line 595, in run_forever
self._run_once()
File "PATH\python310\lib\asyncio\base_events.py", line 1873, in _run_once
handle._run()
File "PATH\python310\lib\asyncio\events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "PATH\dis_snek\api\gateway\gateway.py", line 428, in dispatch_event
asyncio.create_task(processor(events.RawGatewayEvent(data, override_name=event_name)))
File "PATH\python310\lib\asyncio\tasks.py", line 337, in create_task
task = loop.create_task(coro)
Traceback (most recent call last):
File "PATH\dis_snek\api\events\processors\reaction_events.py", line 62, in _on_raw_message_reaction_add
message = await self.cache.get_message(event.data.get("channel_id"), event.data.get("message_id"))
File "PATH\dis_snek\client\smart_cache.py", line 283, in get_message
if not message.guild and message.channel.guild:
AttributeError: 'NoneType' object has no attribute 'guild'
Or if after:
prints: nothing
logs:
ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-95' coro=<ReactionEvents._on_raw_message_reaction_add() done, defined at PATH\dis_snek\api\events\processors\reaction_events.py:18> exception=AttributeError("'NoneType' object has no attribute 'id'") created at PATH\python310\lib\asyncio\tasks.py:337>
source_traceback: Object created at (most recent call last):
File "PATH\bot.py", line 54, in <module>
bot.start("TOKEN")
File "PATH\dis_snek\client\client.py", line 602, in start
self.loop.run_until_complete(self.login(token))
File "PATH\python310\lib\asyncio\base_events.py", line 628, in run_until_complete
self.run_forever()
File "PATH\python310\lib\asyncio\windows_events.py", line 316, in run_forever
super().run_forever()
File "PATH\python310\lib\asyncio\base_events.py", line 595, in run_forever
self._run_once()
File "PATH\python310\lib\asyncio\base_events.py", line 1873, in _run_once
handle._run()
File "PATH\python310\lib\asyncio\events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "PATH\dis_snek\api\gateway\gateway.py", line 428, in dispatch_event
asyncio.create_task(processor(events.RawGatewayEvent(data, override_name=event_name)))
File "PATH\python310\lib\asyncio\tasks.py", line 337, in create_task
task = loop.create_task(coro)
Traceback (most recent call last):
File "PATH\dis_snek\api\events\processors\reaction_events.py", line 54, in _on_raw_message_reaction_add
"channel_id": message.channel.id,
AttributeError: 'NoneType' object has no attribute 'id'
Expected behaviour
Methods should be called and no errors raised
Additional information
I've restarted bot many times but, no sense.
In the _on_raw_message_reaction_add
method event data (channel_id
, message_id
) seems to be ok,
I've tried to get the channel and the message in bot on_ready
event, but message is still None
3.10.1 Latest dev
Jan got same bug in https://discord.com/channels/870046872864165888/936614850820452403
Describe the bug
str(emoji) gives <:π:None> when it is a standard emoji
To Reproduce
@listen()
async def on_message_reaction_add(event: MessageReactionAdd):
str(event.emoji)
Expected behaviour
It should return the emoji in a format thats actually usable on discord
Additional information
I am on latest dev.
Discussion can be seen in thread here
Add support for guild audit logs.
( Rewriting that here so it's not forgotten :) )
Is your feature request related to a problem? Please describe.
Accessing the client obj in events in separate files is a pita.
Describe the solution you'd like
Add .bot to all events, namely the BaseEvent class.
Describe alternatives you've considered
Get the protected client obj from for example Member works (Member._client)
Additional information
/
We have create_guild_from_template, but not the classic create_guld
Describe the bug
When grabbing bulk messages from discord they don't actually return the guild id. Since that is missing in the message data you are missing features like message.mention_user
. SInce there is no guild id it may cause errors like:
raceback (most recent call last):
File "C:\Users\BoredMan\GitHub\Inquiry\venv\lib\site-packages\dis_snek\client\client.py", line 1238, in _dispatch_msg_commands
await command(context)
File "C:\Users\BoredMan\GitHub\Inquiry\venv\lib\site-packages\dis_snek\models\snek\command.py", line 101, in __call__
await self.call_callback(self.callback, context)
File "C:\Users\BoredMan\GitHub\Inquiry\venv\lib\site-packages\dis_snek\models\snek\command.py", line 130, in call_callback
return await callback()
File "C:\Users\BoredMan\GitHub\Inquiry\scales\message_commands.py", line 225, in transcript
content = await check_message_mention(message)
File "C:\Users\BoredMan\GitHub\Inquiry\scales\message_commands.py", line 119, in check_message_mention
async for member in msgs.mention_users:
File "C:\Users\BoredMan\GitHub\Inquiry\venv\lib\site-packages\dis_snek\models\discord\message.py", line 229, in mention_users
yield await self._client.cache.get_member(self._guild_id, u_id)
File "C:\Users\BoredMan\GitHub\Inquiry\venv\lib\site-packages\dis_snek\client\smart_cache.py", line 143, in get_member
guild_id = to_snowflake(guild_id)
File "C:\Users\BoredMan\GitHub\Inquiry\venv\lib\site-packages\dis_snek\models\discord\snowflake.py", line 27, in to_snowflake
raise TypeError(
TypeError: ID (snowflake) should be instance of int, str, SnowflakeObject, or support __int__. Got 'None' (<class 'NoneType'>) instead.
To Reproduce
The code you used to produce this bug, must be in a code-block:
Expected behaviour
What should happen instead is we insert the guild id into the message data.
I think https://github.com/Discord-Snake-Pit/Dis-Snek/blob/69d06dd21c43e23b6d1b5c5e1ad2796ae1e46cea/dis_snek/models/discord/channel.py#L232-L233
should be replaced with
Additional information
I am making this issue because I am not sure if this would be the proper way to go about this.
Also: It seems that even with that there are still some that are None
Is your feature request related to a problem? Please describe.
It's important to show everything thats usable
Describe the solution you'd like
Add them before the beta!
Describe alternatives you've considered
Read discord's docs
Additional information
Any other information or screenshots about the feature request.
Describe the bug
its throwing an error when i use embed(image=url) when its an URL without a .png or .jpg ending, polls said the lib should handle that
To Reproduce
embed = Embed(description="test", image=https://cdn1.epicgames.com/offer/615659ff36244d258ef6c6a827e32c5d/Brothers_Port_1200x1600_1200x1600-ee43c7558877b4470f607a0c140ee3d5) await ctx.send(embed=embed)
Expected behaviour
it should add the image to the embed
Additional information
discussed it on the discord server here : https://discord.com/channels/870046872864165888/944892972439310356
latest
When a session is, "Gateway has invalidated session! Reconnecting..."
bot.is_ready
is not set to false and will spam you with all the join things
What should happen during a reconnect is is_ready is set back to false and then true once it is connected
import naff
bot = naff.Client(sync_interactions=True, debug_scope=701347683591389185)
@naff.slash_command(name="trip_reconnect")
async def trip_reconnect(ctx):
await ctx.send("Session invalidated")
await bot.ws.dispatch_opcode(None, naff.WebSocketOPCodes.INVALIDATE_SESSION)
@naff.listen(naff.events.GuildJoin)
async def join(event: naff.events.GuildJoin):
if bot.is_ready:
print("This should not happen within the testing period")
bot.start("token")
No response
I think that this is where is ready should be set back to false
NAFF/naff/api/gateway/websocket.py
Lines 239 to 260 in 13aeb1a
This is relatively easy, I'm just waiting for Voice to get merged before I do it.
Is your feature request related to a problem? Please describe.
Missing icons support
Describe the solution you'd like
Implement it
Describe alternatives you've considered
No any
Additional information
Any other information or screenshots about the feature request.
Describe the bug
Not all .fetch_* instances return None optionally. Some raise not found errors.
Someone needs to go through all methods and make sure the NotFound exception is caught and None is returned everywhere. Currently it's 50/50
This is needed everywhere
try:
return await self.cache.fetch_member(guild_id, user_id)
except NotFound:
return Noneβ
Currently the gateway spawns two tasks to be able to use asyncio.wait()
to receive an event:
This is unnecessary, as only the latter task needs to be re-created really.
__slots__
and initialize it as Nonereceive()
(or if it was the run()
) method check for this task and use it in asyncio.wait()
, if it doesn't exist create it.A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.