#Setting a command to have reactions

1 messages Β· Page 1 of 1 (latest)

dry dirge
#
async def new_book(self,inter,book_title: str,book_author:str, *,
                    book_description: str):
    await inter.response.defer(ephemeral=True)

    embed = disnake.Embed(
        color = disnake.Colour.random(),
        title = f"{self.bot.user.name}'s Book Notifications",
        description = f"{inter.author.name} Has Suggested A New Book"
    ).add_field(
        name = book_title + " " + book_author,
        value = book_description,
        inline = False
    ).set_thumbnail(url = inter.author.avatar)

    book_channel = disnake.utils.get(inter.guild.text_channels, id=1112524159239589898)

    await book_channel.send(embed=embed)
    return await inter.edit_original_message(f"{inter.author.mention} Your Book Has Been Suggested")
```This is a first time trying to do this sort of situation for me. I'm wanting to adjust this command to where when the embed is sent to the desired channel, it comes with a πŸ‘ and a πŸ‘Ž reaction. The reactions won't do anything, but I've never tried to add reactions to an embed through a command before, so I'm not sure how to proceed from here. Thanks
quiet vessel
#

-d Messageable.send

delicate ospreyBOT
#
await send(content=None, *, tts=False, embed=None, embeds=None, file=None, files=None, stickers=None, delete_after=None, nonce=None, suppress_embeds=None, flags=None, ...)```
This function is a [*coroutine*](https://docs.python.org/3/library/asyncio-task.html#coroutine).

Sends a message to the destination with the content given.

The content must be a type that can convert to a string through `str(content)`.

At least one of `content`, `embed`/`embeds`, `file`/`files`, `stickers`, `components`, or `view` must be provided.

To upload a single file, the `file` parameter should be used with a single [`File`](https://docs.disnake.dev/en/latest/api/messages.html#disnake.File "disnake.File") object. To upload multiple files, the `files` parameter should be used with a [`list`](https://docs.python.org/3/library/stdtypes.html#list "(in Python v3.11)") of [`File`](https://docs.disnake.dev/en/latest/api/messages.html#disnake.File "disnake.File") objects. **Specifying both parameters will lead to an exception**.

To upload a single embed, the `embed` parameter should be used with a single [`Embed`](https://docs.disnake.dev/en/latest/api/messages.html#disnake.Embed "disnake.Embed") object. To upload multiple embeds, the `embeds` parameter should be used with a [`list`](https://docs.python.org/3/library/stdtypes.html#list "(in Python v3.11)") of [`Embed`](https://docs.disnake.dev/en/latest/api/messages.html#disnake.Embed "disnake.Embed") objects. **Specifying both parameters will lead to an exception**.
quiet vessel
#

-d disnake.Message

delicate ospreyBOT
#

class disnake.Message```
Represents a message from Discord.

x == y Checks if two messages are equal.

x != y Checks if two messages are not equal.

hash(x) Returns the message’s hash.
dry dirge
#

ok give me a moment to look at these.

#

so then I would do

msg = await book_channel.send(embed=embed)
msg.add_reaction(":thumbsup:")
msg.add_reaction(":thumbsdown:")
```?
#

I believe I'm reading that right

#

or instead of the strings, it would be the universal emoji

quiet vessel
#

Yup. You can actually copy and paste the emoji πŸ‘ and πŸ‘Ž .

#

Just don't forget await

dry dirge
#
msg = await book_channel.send(embed=embed)
await msg.add_reaction(πŸ‘)
await msg.add_reaction(πŸ‘Ž)
```the only problem I'm getting from this is that the thumbsup line is telling me that I forgot a `(`
quiet vessel
#

you need quotes

dry dirge
#

or that the parenthesis was never closed so should they be string reps?

#

ah gotcha

quiet vessel
#
await message.add_reaction("πŸ‘")
dry dirge
#

haha yeet tyvm!

dull tundraBOT
#
Solved!

Marked the thread as solved. If your question has not been answered, please open a new thread in #1019642966526140566.

dry dirge
# quiet vessel ```py await message.add_reaction("πŸ‘") ```

one more question if that's alright.

@commands.Cog.listener()
async def on_thread_join(self,thread):
    announce_channel = disnake.utils.get(thread.guild.text_channels, id=1112533230483148882)
    book_members = [member for member in thread.guild.members if member.top_role.name == "Book Club Member"]
    book_capts = [member for member in thread.guild.members if member.top_role.name == "Book Club Captain"]

    return await announce_channel.send_message(
        f"{', '.join([m.mention for m in book_capts])}, {', '.join([m.mention for m in book_members])} A New Book Thread Has Been Started." +
        f" Please Click {thread.mention} To View This Thread."
    )
```when running events within a cog, do I need to do the decorator like this
```python
@commands.Cog.listener()
```or does it need to be
```python
@commands.Cog.listener("thread")
```? I'm a little confused with the docs
quiet vessel
#

commands.Cog.listener() is basically bot.listen()
You can pass on the event name on_thread_join as a string, then call your callback function whatever you want, or don't pass anything to it and make sure the function name matches the expected event

dry dirge
#

so how I have it in the code block is appropriate?

quiet vessel
#

And again..

announce_channel = disnake.utils.get(thread.guild.text_channels, id=1112533230483148882)
is inefficient and so much more typing than thread.guild.get_channel(1112533230483148882)

#

It's fine.

dry dirge
#

I know that's a stupid question

quiet vessel
#

No. It relies on cache

dry dirge
#

ok bet. tyvm

dry dirge
# quiet vessel No. It relies on cache

ok so I have to tweak it a little bit so that it only does announcements for book club threads that are created. According to the docs, it would be thread.parent but parent is an Optional(Union[ForumChannel,TextChannel]) so how would I write an early return if the threads parent (forum channel) wasn't "open_books"?

#
if thread.parent[0].name != "open_books":
  pass
```?
#

or would I just call thread.forum_channel.name?

#

and also, if a new "open_book" thread is created via the discord ui, is it going to trigger my cog listener?

#
async def on_thread_join(self,thread):
    # if the new thread does not belong to the open_books forum, pass
    if thread.forum_channel.name != "open_books":
        pass
    
    announce_channel = thread.guild.get_channel(1112533230483148882)

    embed = disnake.Embed(
        color = disnake.Colour.random(),
        title = "A New Book Has Been Created!",
        description = f"Click Here To View This Thread {thread.jump_url}"
    ).add_field(
        name = "Book Name",
        value = thread.name,
        inline = False
    ).add_field(
        name = "Book Details",
        value = thread.starter_message,
        inline = False
    ).add_field(
        name = "Book Genre",
        value = [tag.name for tag in thread.applied_tags]
    )

    return await announce_channel.send_message("@here A New Book Thread Has Been Started.", embed=embed)
```this is what I'm trying to do, but I don't know a couple of things
1) If the thread is created via the discord UI "New Post" button, will it trigger this bot event
2) if I called the thread forum channel name correctly to check which forum it was created in
#

nevermind. I found a work around

quiet vessel
#

on_thread_join is when the bot is added to a thread

dry dirge
#

so it needs to be on_thread_create not join

#

between the command https://pastebin.com/4vkD2SFN and the event https://pastebin.com/F4sKaHZ3, everything works except getting the newly created threads jump url (command) and getting the event to send the announcement when the thread is created. I'm not sure what I'm doing wrong as I'm following the docs when doing this

quiet vessel
#
if thread.category.name != "Book Club":
            pass
#

you'd probably want to return
pass just means, don't do anything and continue through the function

dry dirge
#

ok I changed that, but when the thread is created, it's still not sending the notification

#

unless I need to put the rest of the code in an else statement

quiet vessel
#

You need to look back at the create_thread method.

#

It returns a NamedTuple

Tuple[Thread, Message]
#

so it should look like:

thread, message = await forum_channel.create_thread(...)
dry dirge
#
new_thread, message = await forum_channel.create_thread(
    name = f"{book_title} - {book_author}",
    applied_tags = [tag_to_apply,],
    content = book_description
)
```and I have to unpack it
#

yep lol gotcha. ok so now why isn't the event sending the notification when the thread is created?

quiet vessel
#

and jump_thread is unnecesary.

dry dirge
#

it def is

#

I removed it

quiet vessel
#

because :
1 get_thread take an ID, not a thread object
2. you already have the thread object

dry dirge
#

right. I slipped on that part

quiet vessel
#
return await inter.edit_original_response(f'{inter.author.mention} You new Book Thread has been created. {thread.jump_url}')
dry dirge
#

right.

quiet vessel
#

that should send the message to the user that used the command.

dry dirge
#

correct

quiet vessel
#

So the on_thread_create isn't working?

#

Make sure the bot has access to the forum channel, otherwise has the manage_threads permission

dry dirge
#

it is now except it doesn't like where I'm trying to get the threads first message thread.starter_message. I was doing this because the first message that is sent to the thread is the books description and I'm trying to obtain that message for the announcement embed

quiet vessel
#

thread.starter_message doesn't exist.

dry dirge
#

its supposed to be thread.thread_start_message isn't it

quiet vessel
#

Look at the docs.

#

Those attributes do not exist.

quiet vessel
#

Yeah, that's not part of Thread

dry dirge
#

oh

#

so then how can I get that first message for the books description?

quiet vessel
#

That's to see if a channel message started a thread.

dry dirge
#

use the message history?

quiet vessel
#

not the case for forum threads.

dry dirge
#

ok so then how would I get that first message or is what you're saying is that it's not possible?

quiet vessel
#

You'll have to use thread.history

dry dirge
#

-d thread.last_message

delicate ospreyBOT
#

property last_message```
Gets the last message in this channel from the cache.

The message might not be valid or point to an existing message.

Reliable Fetching

For a slightly more reliable method of fetching the last message, consider using either [`history()`](https://docs.disnake.dev/en/latest/api/channels.html#disnake.Thread.history "disnake.Thread.history") or [`fetch_message()`](https://docs.disnake.dev/en/latest/api/channels.html#disnake.Thread.fetch_message "disnake.Thread.fetch_message") with the [`last_message_id`](https://docs.disnake.dev/en/latest/api/channels.html#disnake.Thread.last_message_id "disnake.Thread.last_message_id") attribute.
dry dirge
#

could I get away with the last message?

quiet vessel
#

last_message was None for me. Same with last_message_id

#

I just tested with last_message, tried to fetch with last_message_id, but the only success was with history()

#
async for message in thread.history(limit=1):
   ...
dry dirge
#

ok so then it would look like

announce_channel = thread.guild.get_channel()
message_history = await thread.history(limit=None).flatten()

embed.add_field(
  name = "Book Details",
  value = message_history[0],
  inline = False
)
```right?
quiet vessel
#

that would be value=Message

#

I'd suggest setting the limit to 1.

#

But realistically..

why not just have the announcement in the command callback where you already have the thread, message, and tags.

dry dirge
#

I mean. you're not wrong. I didn't think of that honestly. I was just thinking about expanding the bot past commands by using events.

quiet vessel
#

They're all utilities to use when you need them, but if you don't need them, no sense in making it more complicated than it needs to be.

#

simple as taking the function you created for on_thread_create, adjusting it and then calling it from the command callback.