25 changed files with 41 additions and 586 deletions
@ -1,62 +0,0 @@ |
|||||
# This example requires the 'message_content' privileged intent to function. |
|
||||
|
|
||||
from discord.ext import commands |
|
||||
|
|
||||
import discord |
|
||||
|
|
||||
|
|
||||
class Bot(commands.Bot): |
|
||||
def __init__(self): |
|
||||
intents = discord.Intents.default() |
|
||||
intents.message_content = True |
|
||||
|
|
||||
super().__init__(command_prefix=commands.when_mentioned_or('$'), intents=intents) |
|
||||
|
|
||||
async def on_ready(self): |
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})') |
|
||||
print('------') |
|
||||
|
|
||||
|
|
||||
# Define a simple View that gives us a confirmation menu |
|
||||
class Confirm(discord.ui.View): |
|
||||
def __init__(self): |
|
||||
super().__init__() |
|
||||
self.value = None |
|
||||
|
|
||||
# When the confirm button is pressed, set the inner value to `True` and |
|
||||
# stop the View from listening to more input. |
|
||||
# We also send the user an ephemeral message that we're confirming their choice. |
|
||||
@discord.ui.button(label='Confirm', style=discord.ButtonStyle.green) |
|
||||
async def confirm(self, button: discord.ui.Button, interaction: discord.Interaction): |
|
||||
await interaction.response.send_message('Confirming', ephemeral=True) |
|
||||
self.value = True |
|
||||
self.stop() |
|
||||
|
|
||||
# This one is similar to the confirmation button except sets the inner value to `False` |
|
||||
@discord.ui.button(label='Cancel', style=discord.ButtonStyle.grey) |
|
||||
async def cancel(self, button: discord.ui.Button, interaction: discord.Interaction): |
|
||||
await interaction.response.send_message('Cancelling', ephemeral=True) |
|
||||
self.value = False |
|
||||
self.stop() |
|
||||
|
|
||||
|
|
||||
bot = Bot() |
|
||||
|
|
||||
|
|
||||
@bot.command() |
|
||||
async def ask(ctx: commands.Context): |
|
||||
"""Asks the user a question to confirm something.""" |
|
||||
# We create the view and assign it to a variable so we can wait for it later. |
|
||||
view = Confirm() |
|
||||
await ctx.send('Do you want to continue?', view=view) |
|
||||
# Wait for the View to stop listening for input... |
|
||||
await view.wait() |
|
||||
if view.value is None: |
|
||||
print('Timed out...') |
|
||||
elif view.value: |
|
||||
print('Confirmed...') |
|
||||
else: |
|
||||
print('Cancelled...') |
|
||||
|
|
||||
|
|
||||
bot.run('token') |
|
@ -1,48 +0,0 @@ |
|||||
# This example requires the 'message_content' privileged intent to function. |
|
||||
|
|
||||
from discord.ext import commands |
|
||||
|
|
||||
import discord |
|
||||
|
|
||||
|
|
||||
class CounterBot(commands.Bot): |
|
||||
def __init__(self): |
|
||||
intents = discord.Intents.default() |
|
||||
intents.message_content = True |
|
||||
|
|
||||
super().__init__(command_prefix=commands.when_mentioned_or('$'), intents=intents) |
|
||||
|
|
||||
async def on_ready(self): |
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})') |
|
||||
print('------') |
|
||||
|
|
||||
|
|
||||
# Define a simple View that gives us a counter button |
|
||||
class Counter(discord.ui.View): |
|
||||
|
|
||||
# Define the actual button |
|
||||
# When pressed, this increments the number displayed until it hits 5. |
|
||||
# When it hits 5, the counter button is disabled and it turns green. |
|
||||
# note: The name of the function does not matter to the library |
|
||||
@discord.ui.button(label='0', style=discord.ButtonStyle.red) |
|
||||
async def count(self, button: discord.ui.Button, interaction: discord.Interaction): |
|
||||
number = int(button.label) if button.label else 0 |
|
||||
if number + 1 >= 5: |
|
||||
button.style = discord.ButtonStyle.green |
|
||||
button.disabled = True |
|
||||
button.label = str(number + 1) |
|
||||
|
|
||||
# Make sure to update the message with our updated selves |
|
||||
await interaction.response.edit_message(view=self) |
|
||||
|
|
||||
|
|
||||
bot = CounterBot() |
|
||||
|
|
||||
|
|
||||
@bot.command() |
|
||||
async def counter(ctx: commands.Context): |
|
||||
"""Starts a counter for pressing.""" |
|
||||
await ctx.send('Press!', view=Counter()) |
|
||||
|
|
||||
|
|
||||
bot.run('token') |
|
@ -1,68 +0,0 @@ |
|||||
# This example requires the 'message_content' privileged intent to function. |
|
||||
|
|
||||
import typing |
|
||||
|
|
||||
import discord |
|
||||
from discord.ext import commands |
|
||||
|
|
||||
# Defines a custom Select containing colour options |
|
||||
# that the user can choose. The callback function |
|
||||
# of this class is called when the user changes their choice |
|
||||
class Dropdown(discord.ui.Select): |
|
||||
def __init__(self): |
|
||||
|
|
||||
# Set the options that will be presented inside the dropdown |
|
||||
options = [ |
|
||||
discord.SelectOption(label='Red', description='Your favourite colour is red', emoji='🟥'), |
|
||||
discord.SelectOption(label='Green', description='Your favourite colour is green', emoji='🟩'), |
|
||||
discord.SelectOption(label='Blue', description='Your favourite colour is blue', emoji='🟦') |
|
||||
] |
|
||||
|
|
||||
# The placeholder is what will be shown when no option is chosen |
|
||||
# The min and max values indicate we can only pick one of the three options |
|
||||
# The options parameter defines the dropdown options. We defined this above |
|
||||
super().__init__(placeholder='Choose your favourite colour...', min_values=1, max_values=1, options=options) |
|
||||
|
|
||||
async def callback(self, interaction: discord.Interaction): |
|
||||
# Use the interaction object to send a response message containing |
|
||||
# the user's favourite colour or choice. The self object refers to the |
|
||||
# Select object, and the values attribute gets a list of the user's |
|
||||
# selected options. We only want the first one. |
|
||||
await interaction.response.send_message(f'Your favourite colour is {self.values[0]}') |
|
||||
|
|
||||
|
|
||||
class DropdownView(discord.ui.View): |
|
||||
def __init__(self): |
|
||||
super().__init__() |
|
||||
|
|
||||
# Adds the dropdown to our view object. |
|
||||
self.add_item(Dropdown()) |
|
||||
|
|
||||
|
|
||||
class Bot(commands.Bot): |
|
||||
def __init__(self): |
|
||||
intents = discord.Intents.default() |
|
||||
intents.message_content = True |
|
||||
|
|
||||
super().__init__(command_prefix=commands.when_mentioned_or('$'), intents=intents) |
|
||||
|
|
||||
async def on_ready(self): |
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})') |
|
||||
print('------') |
|
||||
|
|
||||
|
|
||||
bot = Bot() |
|
||||
|
|
||||
|
|
||||
@bot.command() |
|
||||
async def colour(ctx): |
|
||||
"""Sends a message with our dropdown containing colours""" |
|
||||
|
|
||||
# Create the view containing our dropdown |
|
||||
view = DropdownView() |
|
||||
|
|
||||
# Sending a message containing our view |
|
||||
await ctx.send('Pick your favourite colour:', view=view) |
|
||||
|
|
||||
|
|
||||
bot.run('token') |
|
@ -1,52 +0,0 @@ |
|||||
# This example requires the 'message_content' privileged intent to function. |
|
||||
|
|
||||
from discord.ext import commands |
|
||||
|
|
||||
import discord |
|
||||
|
|
||||
class EphemeralCounterBot(commands.Bot): |
|
||||
def __init__(self): |
|
||||
intents = discord.Intents.default() |
|
||||
intents.message_content = True |
|
||||
|
|
||||
super().__init__(command_prefix=commands.when_mentioned_or('$'), intents=intents) |
|
||||
|
|
||||
async def on_ready(self): |
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})') |
|
||||
print('------') |
|
||||
|
|
||||
# Define a simple View that gives us a counter button |
|
||||
class Counter(discord.ui.View): |
|
||||
|
|
||||
# Define the actual button |
|
||||
# When pressed, this increments the number displayed until it hits 5. |
|
||||
# When it hits 5, the counter button is disabled and it turns green. |
|
||||
# note: The name of the function does not matter to the library |
|
||||
@discord.ui.button(label='0', style=discord.ButtonStyle.red) |
|
||||
async def count(self, button: discord.ui.Button, interaction: discord.Interaction): |
|
||||
number = int(button.label) if button.label else 0 |
|
||||
if number + 1 >= 5: |
|
||||
button.style = discord.ButtonStyle.green |
|
||||
button.disabled = True |
|
||||
button.label = str(number + 1) |
|
||||
|
|
||||
# Make sure to update the message with our updated selves |
|
||||
await interaction.response.edit_message(view=self) |
|
||||
|
|
||||
# Define a View that will give us our own personal counter button |
|
||||
class EphemeralCounter(discord.ui.View): |
|
||||
# When this button is pressed, it will respond with a Counter view that will |
|
||||
# give the button presser their own personal button they can press 5 times. |
|
||||
@discord.ui.button(label='Click', style=discord.ButtonStyle.blurple) |
|
||||
async def receive(self, button: discord.ui.Button, interaction: discord.Interaction): |
|
||||
# ephemeral=True makes the message hidden from everyone except the button presser |
|
||||
await interaction.response.send_message('Enjoy!', view=Counter(), ephemeral=True) |
|
||||
|
|
||||
bot = EphemeralCounterBot() |
|
||||
|
|
||||
@bot.command() |
|
||||
async def counter(ctx: commands.Context): |
|
||||
"""Starts a counter for pressing.""" |
|
||||
await ctx.send('Press!', view=EphemeralCounter()) |
|
||||
|
|
||||
bot.run('token') |
|
@ -1,44 +0,0 @@ |
|||||
# This example requires the 'message_content' privileged intent to function. |
|
||||
|
|
||||
from discord.ext import commands |
|
||||
|
|
||||
import discord |
|
||||
from urllib.parse import quote_plus |
|
||||
|
|
||||
class GoogleBot(commands.Bot): |
|
||||
def __init__(self): |
|
||||
intents = discord.Intents.default() |
|
||||
intents.message_content = True |
|
||||
|
|
||||
super().__init__(command_prefix=commands.when_mentioned_or('$'), intents=intents) |
|
||||
|
|
||||
async def on_ready(self): |
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})') |
|
||||
print('------') |
|
||||
|
|
||||
|
|
||||
# Define a simple View that gives us a google link button. |
|
||||
# We take in `query` as the query that the command author requests for |
|
||||
class Google(discord.ui.View): |
|
||||
def __init__(self, query: str): |
|
||||
super().__init__() |
|
||||
# we need to quote the query string to make a valid url. Discord will raise an error if it isn't valid. |
|
||||
query = quote_plus(query) |
|
||||
url = f'https://www.google.com/search?q={query}' |
|
||||
|
|
||||
# Link buttons cannot be made with the decorator |
|
||||
# Therefore we have to manually create one. |
|
||||
# We add the quoted url to the button, and add the button to the view. |
|
||||
self.add_item(discord.ui.Button(label='Click Here', url=url)) |
|
||||
|
|
||||
|
|
||||
bot = GoogleBot() |
|
||||
|
|
||||
|
|
||||
@bot.command() |
|
||||
async def google(ctx: commands.Context, *, query: str): |
|
||||
"""Returns a google link for a query""" |
|
||||
await ctx.send(f'Google Result for: `{query}`', view=Google(query)) |
|
||||
|
|
||||
|
|
||||
bot.run('token') |
|
@ -1,68 +0,0 @@ |
|||||
# This example requires the 'message_content' privileged intent to function. |
|
||||
|
|
||||
from discord.ext import commands |
|
||||
import discord |
|
||||
|
|
||||
|
|
||||
# Define a simple View that persists between bot restarts |
|
||||
# In order a view to persist between restarts it needs to meet the following conditions: |
|
||||
# 1) The timeout of the View has to be set to None |
|
||||
# 2) Every item in the View has to have a custom_id set |
|
||||
# It is recommended that the custom_id be sufficiently unique to |
|
||||
# prevent conflicts with other buttons the bot sends. |
|
||||
# For this example the custom_id is prefixed with the name of the bot. |
|
||||
# Note that custom_ids can only be up to 100 characters long. |
|
||||
class PersistentView(discord.ui.View): |
|
||||
def __init__(self): |
|
||||
super().__init__(timeout=None) |
|
||||
|
|
||||
@discord.ui.button(label='Green', style=discord.ButtonStyle.green, custom_id='persistent_view:green') |
|
||||
async def green(self, button: discord.ui.Button, interaction: discord.Interaction): |
|
||||
await interaction.response.send_message('This is green.', ephemeral=True) |
|
||||
|
|
||||
@discord.ui.button(label='Red', style=discord.ButtonStyle.red, custom_id='persistent_view:red') |
|
||||
async def red(self, button: discord.ui.Button, interaction: discord.Interaction): |
|
||||
await interaction.response.send_message('This is red.', ephemeral=True) |
|
||||
|
|
||||
@discord.ui.button(label='Grey', style=discord.ButtonStyle.grey, custom_id='persistent_view:grey') |
|
||||
async def grey(self, button: discord.ui.Button, interaction: discord.Interaction): |
|
||||
await interaction.response.send_message('This is grey.', ephemeral=True) |
|
||||
|
|
||||
|
|
||||
class PersistentViewBot(commands.Bot): |
|
||||
def __init__(self): |
|
||||
intents = discord.Intents.default() |
|
||||
intents.message_content = True |
|
||||
|
|
||||
super().__init__(command_prefix=commands.when_mentioned_or('$'), intents=intents) |
|
||||
self.persistent_views_added = False |
|
||||
|
|
||||
async def on_ready(self): |
|
||||
if not self.persistent_views_added: |
|
||||
# Register the persistent view for listening here. |
|
||||
# Note that this does not send the view to any message. |
|
||||
# In order to do this you need to first send a message with the View, which is shown below. |
|
||||
# If you have the message_id you can also pass it as a keyword argument, but for this example |
|
||||
# we don't have one. |
|
||||
self.add_view(PersistentView()) |
|
||||
self.persistent_views_added = True |
|
||||
|
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})') |
|
||||
print('------') |
|
||||
|
|
||||
|
|
||||
bot = PersistentViewBot() |
|
||||
|
|
||||
|
|
||||
@bot.command() |
|
||||
@commands.is_owner() |
|
||||
async def prepare(ctx: commands.Context): |
|
||||
"""Starts a persistent view.""" |
|
||||
# In order for a persistent view to be listened to, it needs to be sent to an actual message. |
|
||||
# Call this method once just to store it somewhere. |
|
||||
# In a more complicated program you might fetch the message_id from a database for use later. |
|
||||
# However this is outside of the scope of this simple example. |
|
||||
await ctx.send("What's your favourite colour?", view=PersistentView()) |
|
||||
|
|
||||
|
|
||||
bot.run('token') |
|
@ -1,144 +0,0 @@ |
|||||
# This example requires the 'message_content' privileged intent to function. |
|
||||
|
|
||||
from typing import List |
|
||||
from discord.ext import commands |
|
||||
import discord |
|
||||
|
|
||||
# Defines a custom button that contains the logic of the game. |
|
||||
# The ['TicTacToe'] bit is for type hinting purposes to tell your IDE or linter |
|
||||
# what the type of `self.view` is. It is not required. |
|
||||
class TicTacToeButton(discord.ui.Button['TicTacToe']): |
|
||||
def __init__(self, x: int, y: int): |
|
||||
# A label is required, but we don't need one so a zero-width space is used |
|
||||
# The row parameter tells the View which row to place the button under. |
|
||||
# A View can only contain up to 5 rows -- each row can only have 5 buttons. |
|
||||
# Since a Tic Tac Toe grid is 3x3 that means we have 3 rows and 3 columns. |
|
||||
super().__init__(style=discord.ButtonStyle.secondary, label='\u200b', row=y) |
|
||||
self.x = x |
|
||||
self.y = y |
|
||||
|
|
||||
# This function is called whenever this particular button is pressed |
|
||||
# This is part of the "meat" of the game logic |
|
||||
async def callback(self, interaction: discord.Interaction): |
|
||||
assert self.view is not None |
|
||||
view: TicTacToe = self.view |
|
||||
state = view.board[self.y][self.x] |
|
||||
if state in (view.X, view.O): |
|
||||
return |
|
||||
|
|
||||
if view.current_player == view.X: |
|
||||
self.style = discord.ButtonStyle.danger |
|
||||
self.label = 'X' |
|
||||
self.disabled = True |
|
||||
view.board[self.y][self.x] = view.X |
|
||||
view.current_player = view.O |
|
||||
content = "It is now O's turn" |
|
||||
else: |
|
||||
self.style = discord.ButtonStyle.success |
|
||||
self.label = 'O' |
|
||||
self.disabled = True |
|
||||
view.board[self.y][self.x] = view.O |
|
||||
view.current_player = view.X |
|
||||
content = "It is now X's turn" |
|
||||
|
|
||||
winner = view.check_board_winner() |
|
||||
if winner is not None: |
|
||||
if winner == view.X: |
|
||||
content = 'X won!' |
|
||||
elif winner == view.O: |
|
||||
content = 'O won!' |
|
||||
else: |
|
||||
content = "It's a tie!" |
|
||||
|
|
||||
for child in view.children: |
|
||||
child.disabled = True |
|
||||
|
|
||||
view.stop() |
|
||||
|
|
||||
await interaction.response.edit_message(content=content, view=view) |
|
||||
|
|
||||
|
|
||||
# This is our actual board View |
|
||||
class TicTacToe(discord.ui.View): |
|
||||
# This tells the IDE or linter that all our children will be TicTacToeButtons |
|
||||
# This is not required |
|
||||
children: List[TicTacToeButton] |
|
||||
X = -1 |
|
||||
O = 1 |
|
||||
Tie = 2 |
|
||||
|
|
||||
def __init__(self): |
|
||||
super().__init__() |
|
||||
self.current_player = self.X |
|
||||
self.board = [ |
|
||||
[0, 0, 0], |
|
||||
[0, 0, 0], |
|
||||
[0, 0, 0], |
|
||||
] |
|
||||
|
|
||||
# Our board is made up of 3 by 3 TicTacToeButtons |
|
||||
# The TicTacToeButton maintains the callbacks and helps steer |
|
||||
# the actual game. |
|
||||
for x in range(3): |
|
||||
for y in range(3): |
|
||||
self.add_item(TicTacToeButton(x, y)) |
|
||||
|
|
||||
# This method checks for the board winner -- it is used by the TicTacToeButton |
|
||||
def check_board_winner(self): |
|
||||
for across in self.board: |
|
||||
value = sum(across) |
|
||||
if value == 3: |
|
||||
return self.O |
|
||||
elif value == -3: |
|
||||
return self.X |
|
||||
|
|
||||
# Check vertical |
|
||||
for line in range(3): |
|
||||
value = self.board[0][line] + self.board[1][line] + self.board[2][line] |
|
||||
if value == 3: |
|
||||
return self.O |
|
||||
elif value == -3: |
|
||||
return self.X |
|
||||
|
|
||||
# Check diagonals |
|
||||
diag = self.board[0][2] + self.board[1][1] + self.board[2][0] |
|
||||
if diag == 3: |
|
||||
return self.O |
|
||||
elif diag == -3: |
|
||||
return self.X |
|
||||
|
|
||||
diag = self.board[0][0] + self.board[1][1] + self.board[2][2] |
|
||||
if diag == 3: |
|
||||
return self.O |
|
||||
elif diag == -3: |
|
||||
return self.X |
|
||||
|
|
||||
# If we're here, we need to check if a tie was made |
|
||||
if all(i != 0 for row in self.board for i in row): |
|
||||
return self.Tie |
|
||||
|
|
||||
return None |
|
||||
|
|
||||
|
|
||||
class TicTacToeBot(commands.Bot): |
|
||||
def __init__(self): |
|
||||
intents = discord.Intents.default() |
|
||||
intents.message_content = True |
|
||||
|
|
||||
super().__init__(command_prefix=commands.when_mentioned_or('$'), intents=intents) |
|
||||
|
|
||||
async def on_ready(self): |
|
||||
print(f'Logged in as {self.user} (ID: {self.user.id})') |
|
||||
print('------') |
|
||||
|
|
||||
|
|
||||
bot = TicTacToeBot() |
|
||||
|
|
||||
|
|
||||
@bot.command() |
|
||||
async def tic(ctx: commands.Context): |
|
||||
"""Starts a tic-tac-toe game with yourself.""" |
|
||||
await ctx.send('Tic Tac Toe: X goes first', view=TicTacToe()) |
|
||||
|
|
||||
|
|
||||
bot.run('token') |
|
Loading…
Reference in new issue