A "fork" of discord.py library made by Rapptz with implemation of the Discord-Message-Components by mccoderpy
- NOTE:
- This library will be further developed independently of discord.py. New features are also implemented. It is not an extension! The name only comes from the fact that the original purpose of the library was to add support for message components and we haven't found a better name yet.
Read the Documentation here
Open a issue/pull request, join the support server or send me a direct message on Discord: mccuber04#2960
Python 3.5.3 or higher is required.
This library overwrites the original discord.py library (or any other that would be imported using import discord) so to be sure all will work fine first uninstall the original discord.py library if it is installed:
# Linux/macOS
python3 -m pip uninstall discord.py
# Windows
py -3 -m pip uninstall discord.py
Then install this library using:
# Linux/macOS
python3 -m pip install -U discord.py-message-components
# Windows
py -3 -m pip install -U discord.py-message-components
# Linux/macOS
python3 -m pip install -U git+https://github.com/mccoderpy/discord.py-message-components.git@developer
# Windows
py -m pip install -U git+https://github.com/mccoderpy/discord.py-message-components.git@developer
Of course you nead to have git installed on your device. If you need help with this, take a look here
import typing
import discord
from discord.ext import commands
from discord import ActionRow, Button, ButtonStyle
client = commands.Bot(command_prefix=commands.when_mentioned_or('.!'), intents=discord.Intents.all(), case_insensitive=True)
@client.command(name='buttons', description='sends you some nice Buttons')
async def buttons(ctx: commands.Context):
components = [ActionRow(Button(label='Option Nr.1',
custom_id='option1',
emoji="🆒",
style=ButtonStyle.green
),
Button(label='Option Nr.2',
custom_id='option2',
emoji="🆗",
style=ButtonStyle.blurple)),
ActionRow(Button(label='A Other Row',
custom_id='sec_row_1st option',
style=ButtonStyle.red,
emoji='😀'),
Button(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ',
label="This is an Link",
style=ButtonStyle.url,
emoji='🎬'))
]
an_embed = discord.Embed(title='Here are some Button\'s', description='Choose an option', color=discord.Color.random())
msg = await ctx.send(embed=an_embed, components=components)
def _check(i: discord.Interaction, b):
return i.message == msg and i.member == ctx.author
interaction, button = await client.wait_for('button_click', check=_check)
button_id = button.custom_id
# This sends the Discord-API that the interaction has been received and is being "processed"
await interaction.defer()
# if this is not used and you also do not edit the message within 3 seconds as described below,
# Discord will indicate that the interaction has failed.
# If you use interaction.edit instead of interaction.message.edit, you do not have to defer the interaction,
# if your response does not last longer than 3 seconds.
await interaction.edit(embed=an_embed.add_field(name='Choose', value=f'Your Choose was `{button_id}`'),
components=[components[0].disable_all_buttons(), components[1].disable_all_buttons()])
# The Discord API doesn't send an event when you press a link button so we can't "receive" that.
client.run('You Bot-Token here')
Another more complex example where a small embed will be send; you can move a small white ⬜ with the buttons:
pointers = []
class Pointer:
def __init__(self, guild: discord.Guild):
self.guild = guild
self._possition_x = 0
self._possition_y = 0
@property
def possition_x(self):
return self._possition_x
def set_x(self, x: int):
self._possition_x += x
return self._possition_x
@property
def possition_y(self):
return self._possition_y
def set_y(self, y: int):
self._possition_y += y
return self._possition_y
def get_pointer(obj: typing.Union[discord.Guild, int]):
if isinstance(obj, discord.Guild):
for p in pointers:
if p.guild.id == obj.id:
return p
pointers.append(Pointer(obj))
return get_pointer(obj)
elif isinstance(obj, int):
for p in pointers:
if p.guild.id == obj:
return p
guild = client.get_guild(obj)
if guild:
pointers.append(Pointer(guild))
return get_pointer(guild)
return None
def display(x: int, y: int):
base = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
base[y][x] = 1
base.reverse()
return ''.join(f"\n{''.join([str(base[i][w]) for w in range(len(base[i]))]).replace('0', '⬛').replace('1', '⬜')}" for i in range(len(base)))
empty_button = discord.Button(style=discord.ButtonStyle.Secondary, label=" ", custom_id="empty", disabled=True)
def arrow_button():
return discord.Button(style=discord.ButtonStyle.Primary)
@client.command(name="start_game")
async def start_game(ctx: commands.Context):
pointer: Pointer = get_pointer(ctx.guild)
await ctx.send(embed=discord.Embed(title="Little Game",
description=display(x=0, y=0)),
components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
discord.ActionRow(arrow_button().update(disabled=True).set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
arrow_button().set_label('↓').set_custom_id('down').disable_if(pointer.possition_y <= 0),
arrow_button().set_label('→').set_custom_id('right'))
]
)
@client.on_click()
async def up(i: discord.Interaction, button):
pointer: Pointer = get_pointer(interaction.guild)
pointer.set_y(1)
await i.edit(embed=discord.Embed(title="Little Game",
description=display(x=pointer.possition_x, y=pointer.possition_y)),
components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up').disable_if(pointer.possition_y >= 9), empty_button),
discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
arrow_button().set_label('↓').set_custom_id('down'),
arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.possition_x >= 9))]
)
@client.on_click()
async def down(i: discord.Interaction, button):
pointer: Pointer = get_pointer(interaction.guild)
pointer.set_y(-1)
await i.edit(embed=discord.Embed(title="Little Game",
description=display(x=pointer.possition_x, y=pointer.possition_y)),
components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
arrow_button().set_label('↓').set_custom_id('down').disable_if(pointer.possition_y <= 0),
arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.possition_x >= 9))]
)
@client.on_click()
async def right(i: discord.Interaction, button):
pointer: Pointer = get_pointer(interaction.guild)
pointer.set_x(1)
await i.edit(embed=discord.Embed(title="Little Game",
description=display(x=pointer.possition_x, y=pointer.possition_y)),
components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
discord.ActionRow(arrow_button().set_label('←').set_custom_id('left'),
arrow_button().set_label('↓').set_custom_id('down'),
arrow_button().set_label('→').set_custom_id('right').disable_if(pointer.possition_x >= 9))]
)
@client.on_click()
async def left(i: discord.Interaction, button):
pointer: Pointer = get_pointer(interaction.guild)
pointer.set_x(-1)
await i.edit(embed=discord.Embed(title="Little Game",
description=display(x=pointer.possition_x, y=pointer.possition_y)),
components=[discord.ActionRow(empty_button, arrow_button().set_label('↑').set_custom_id('up'), empty_button),
discord.ActionRow(arrow_button().set_label('←').set_custom_id('left').disable_if(pointer.possition_x <= 0),
arrow_button().set_label('↓').set_custom_id('down'),
arrow_button().set_label('→').set_custom_id('right'))]
)
Please take a look at the documentation if you want to see more examples.