Как преобразовать традиционный код в слэш-команды?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как преобразовать традиционный код в слэш-команды?

Сообщение Anonymous »

Я 12-летний программист/создатель ботов Discord. Когда я программировал своего бота, мне хотелось, чтобы у него было автодополнение.

Код: Выделить всё

import os
import json
import random as random_
import string
import hashlib
import discord
from discord.ext import commands
from dotenv import load_dotenv
import asyncio
# Load environment variables from a .env file
load_dotenv("secrets.env")

# Constants
MODERATOR_ROLE = "mod"
DICTIONARY_ROLE = "dictionary"
KIN_ROLE = "kin"  # This role is for you only
DICTIONARY_FILE = 'dictionary.json'
MONEY_FILE = "money.json"
BOT_OWNER_ID = int(os.getenv("BOT_OWNER_ID"))
TOKEN = os.getenv("DISCORD_TOKEN")
KEY_FILE = "money_key.txt"
SHA256_FILE = "money_sha256.txt"
RESTRICTED_ROLE = "restricted"
MEMBER_ROLE = "member"
MAX_ATTEMPTS = 6
RECEIVED_FILE = "received.json"
BANNED_ROLE = "banned"
WORDLE_FILE = "wordle.txt"
# Initialize the bot with a command prefix
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='/', intents=intents)
@bot.event
async def on_command_error(ctx, error):
"""Global error handler for commands."""
if isinstance(error, commands.CommandInvokeError):
await ctx.send(f"An error occurred while processing your command: {error.original}")
elif isinstance(error, commands.CommandNotFound):
await ctx.send("The command you used was not found.")
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send("A required argument is missing. Please check the command usage.")
elif isinstance(error, commands.BadArgument):
await ctx.send("Invalid argument provided. Please check the command usage.")
else:
await ctx.send(f"An unexpected error occurred: {error}")
raise error  # Optionally, re-raise the error for debugging
@bot.event
async def on_ready():
print(f'Bot is ready. Logged in as {bot.user}')
@bot.command()
async def join(ctx, group: str):
"""Assigns a role based on the group name provided."""
group = group.lower()

if group not in ["python", "cplusplus", "csharp", "stackoverflow"]:
await ctx.send("Invalid group.  Please choose either 'python', 'cplusplus', 'csharp' or 'stackoverflow'.")
return

role = discord.utils.get(ctx.guild.roles, name=group)
if role:
try:
await ctx.author.add_roles(role)
await ctx.send(f"Role '{group}' has been assigned to you.")
except discord.errors.Forbidden:
await ctx.send("Error: Missing permissions to assign the role.")
except discord.errors.HTTPException as e:
await ctx.send(f"Error: Failed to assign the role ({e}).")
else:
await ctx.send(f"Error: Role '{group}' not found.")
@bot.event
async def on_member_join(member):
# Check if the new member has the "restricted" role
restricted_role = discord.utils.get(member.guild.roles, name=RESTRICTED_ROLE)
if restricted_role in member.roles:
print(f'{member.display_name} has the restricted role, not assigning member role.')
return
# Assign the "member" role to the new member
member_role = discord.utils.get(member.guild.roles, name=MEMBER_ROLE)
if member_role:
try:
await member.add_roles(member_role)
print(f'Assigned {MEMBER_ROLE} role to {member.display_name}')
except discord.errors.Forbidden:
print(f'Error: Missing permissions to assign role {MEMBER_ROLE} to {member.display_name}')
except discord.errors.HTTPException as e:
print(f'Error: Failed to assign role {MEMBER_ROLE} to {member.display_name} ({e})')
else:
print(f'Error: Role {MEMBER_ROLE} not found')
# Check if the user has the Kin role
def is_kin(ctx):
return ctx.author.id == BOT_OWNER_ID  # Only the bot owner has full control

# Check if the user has the moderator role
def is_moderator(ctx):
return "mod" in [i.name.lower() for i in ctx.author.roles]

# Check if the user has the dictionary user role
def is_dictionary_user(ctx):
return "dictionary" in [i.name.lower() for i in ctx.author.roles]

# Check if the user is the bot owner
def is_bot_owner(ctx):
return ctx.author.id == BOT_OWNER_ID

# Custom help command
class HelpCommand(commands.HelpCommand):
def __init__(self):
super().__init__(command_attrs=dict(hidden=True))

async def send_bot_help(self, mapping):
channel = self.get_destination()
description = "Here's a list of available commands:\n\n"
for cog, commands in mapping.items():
if cog is None:
cog_name = "General"
else:
cog_name = cog.qualified_name
for command in commands:
description += f"/{command.name}: {command.help}\n"
await channel.send(description)

async def send_command_help(self, command):
channel = self.get_destination()
description = f"**Command**: /{command.name}\n"
if command.help:
description += f"**Description**: {command.help}\n"
if command.aliases:
description += f"**Aliases**: {', '.join(command.aliases)}\n"
await channel.send(description)

# Set custom help command
bot.help_command = HelpCommand()

# Helper function to ensure file existence
def ensure_file_exists(filename, default_content={}):
if not os.path.exists(filename):
with open(filename, "w") as file:
json.dump(default_content, file)
@bot.command()
# Set a role for a member
async def role(ctx, member: discord.Member, role: discord.Role):
if is_kin(ctx):
"""Assigns a role to a member.  Kin role only."""
if role in ctx.guild.roles:
if role not in member.roles:
if role.name != "kin":
await member.add_roles(role)
await ctx.send(f"{role.name} role has been assigned to {member.mention}.")
else:
await ctx.send("You can't give someone your role, Kin.")
else:
await ctx.send(f"{member.mention} already has the {role.name} role.")
else:
await ctx.send(f"The role {role.name} does not exist.")
else:
ctx.send("You don't have the permission to do that.")
@bot.command()
async def demote(ctx, member: discord.Member, role: discord.Role):
if is_kin(ctx):
"""Deletes a role from a member. Kin role only."""
if role in ctx.guild.roles:
if role in member.roles:
await member.remove_roles(role)
await ctx.send(f"{member.mention} has been demoted from {role.name}.")
else:
await ctx.send(f"{member.mention} does not have the {role.name} role.")
else:
await ctx.send(f"The role {role.name} does not exist.")
else:
ctx.send("You don't have the permission to do that.")
async def setrolebypass(ctx, member: discord.Member, role: discord.Role):
"""Assigns a role to a member. Kin role only."""
if role in ctx.guild.roles:
if role not in member.roles:
if role.name != "kin":
await member.add_roles(role)
await ctx.send(f"{role.name} role has been assigned to {member.mention}.")
else:
await ctx.send("You can't give someone your role, Kin.")
else:
await ctx.send(f"{member.mention} already has the {role.name} role.")
else:
await ctx.send(f"The role {role.name} does not exist.")
@bot.command()
async def init(ctx):
guild = ctx.guild
overwrites = {
guild.default_role: discord.PermissionOverwrite(read_message_history=True),
guild.me: discord.PermissionOverwrite(read_message_history=True)
}

for channel_name in ['#rules', '#commands']:
channel = discord.utils.get(guild.text_channels, name=channel_name.strip('#'))
if channel:
await channel.set_permissions(guild.default_role, read_messages=True, send_messages=False)
@bot.command()
async def mute(ctx, member: discord.Member, time: str, reason: str = "No reason"):
if is_moderator(ctx):
"""Mute a member for a specified time.  Format: hh\hmm\mss\s where \s, \m, \h are literal."""
restricted_role = discord.utils.get(ctx.guild.roles, name=RESTRICTED_ROLE)
member_role = discord.utils.get(ctx.guild.roles, name=MEMBER_ROLE)
appeals_channel = discord.utils.get(ctx.guild.text_channels, name="appeals")

await member.add_roles(restricted_role)
await member.remove_roles(member_role)
await ctx.send(f'{member.mention} has been muted for {time}.')

# Allow the muted user to type in #appeals
await appeals_channel.set_permissions(member, send_messages=True, read_messages=True)

# Parse the time format
time_seconds = 0
if time == "forever":
time_seconds = -1
if 'h' in time:
hours, time = time.split('h')
time_seconds += int(hours) * 3600
if 'm' in time:
minutes, time = time.split('m')
time_seconds += int(minutes) * 60
if 's' in time:
seconds = time.split('s')[0]
time_seconds += int(seconds)

await member.send(f"You have been muted for {time} with reason \"{reason}\".")

if time_seconds > 0:
await asyncio.sleep(time_seconds)
await unmute(ctx, member)

# Revert permissions in #appeals
await appeals_channel.set_permissions(member, overwrite=None)
else:
await ctx.send("You don't have the permission to do that.")
# Unmute a member
@bot.command()
async def unmute(ctx, member: discord.Member):
if is_moderator(ctx):
restricted_role = discord.utils.get(ctx.guild.roles, name=RESTRICTED_ROLE)
if restricted_role in member.roles:
await member.remove_roles(restricted_role)
await ctx.send(f'{member.mention} has been unmuted.')
else:
await ctx.send(f'{member.mention} is not muted.')
if restricted_role in member.roles:
await member.remove_roles(restricted_role)
member_role = discord.utils.get(ctx.guild.roles, name=MEMBER_ROLE)
if member_role:
await member.add_roles(member_role)

else:
await ctx.send("You don't have the permission to do that.")
# Kick a member
@bot.command()
async def kick(ctx, member: discord.Member, *, reason=None):
if is_moderator(ctx):
await member.kick(reason=reason)
await ctx.send(f'{member.mention} has been kicked.')
else:
await ctx.send("You don't have the permission to do that.")
def split_message(data):
words = data.split()
messages = []
current_message = ""

for word in words:
# Check if adding the next word would exceed the 2000 character limit
if len(current_message) + len(word) + 1 > 2000:  # +1 for the space
messages.append(current_message)
current_message = word
else:
if current_message:
current_message += " " + word
else:
current_message = word

# Append the last message if it contains any words
if current_message:
messages.append(current_message)

return messages

# Handle commands related to the dictionary
@bot.command()
async def dictionary(ctx, word: str, command: str ="get", meaning: str=None):
"""Commands to manage the dictionary: get, add, delete."""
ensure_file_exists("dictionary.json")

with open("dictionary.json", "r") as file:
data = json.load(file)
if command == "get":
if word in data:
a = split_message(data[word])
await ctx.send(f"{word}: {a[0]}")
if len(a) >  1:
for i in a[1:]:
await ctx.send(f"{i}")
else:
await ctx.send(f"Word '{word}' not found in the dictionary.")
elif command == "add":
if is_dictionary_user(ctx):
if meaning:
data[word] = meaning
with open("dictionary.json", "w") as file:
json.dump(data, file)
await ctx.send(f"Added '{word}': '{meaning}' to the dictionary.")
else:
await ctx.send("Please provide a meaning for the word.")
else:
await ctx.send("You don't have the permission to do that.")
elif command == "delete":
if is_dictionary_user(ctx):
if word in data:
del data[word]
with open("dictionary.json", "w") as file:
json.dump(data, file)
await ctx.send(f"Deleted '{word}' from the dictionary.")
else:
await ctx.send(f"Word '{word}' not found in the dictionary.")
else:
await ctx.send("You don't have the permission to do that.")
else:
await ctx.send("Invalid command.  Use 'get', 'add', or 'delete'.")

@bot.command()
async def lock(ctx, channel: discord.TextChannel):
if is_moderator(ctx):
# Get the 'everyone' role
everyone_role = ctx.guild.default_role
# Get the 'Moderator' role
moderator_role = discord.utils.get(ctx.guild.roles, name="mod")

# Set permissions for the 'everyone' role to disallow sending messages
await channel.set_permissions(everyone_role, send_messages=False)
# Ensure 'Moderator' role can still send messages
await channel.set_permissions(moderator_role, send_messages=True)

await ctx.send(f"{channel.mention} has been locked.")
else:
await ctx.send("You don't have the permission to do that.")
@bot.command()
async def unlock(ctx, channel: discord.TextChannel):
if is_moderator(ctx):
# Get the 'everyone' role
everyone_role = ctx.guild.default_role

# Reset permissions for the 'everyone' role to allow sending messages
await channel.set_permissions(everyone_role, send_messages=True)

await ctx.send(f"{channel.mention} has been unlocked.")
else:
await ctx.send("You don't have the permission to do that.")
@bot.command()
async def report(ctx, user: discord.User, reason: str):
"""Report a user with a reason."""

# Assuming 'mod' is the name of the role to mention
mod_role = discord.utils.get(ctx.guild.roles, name="mod")

# Create the report message
report_message = f"User  reported  because of: {reason}"

# Send the report message to a specific channel (replace '1266041632122208328' with your channel ID)
report_channel = bot.get_channel(1266041632122208328)

if not report_channel:
await ctx.send("Report channel not found.")
return

await report_channel.send(f"{mod_role.mention} {report_message}")
await ctx.send(f"Report sent! {mod_role.mention} has been notified.")
# Handle money-related commands
@bot.command()
async def id(ctx, user: discord.User | None):
if not user:
user = ctx.author
await ctx.send("ID of " + user.name + ": " + str(user.id))

@bot.command()
async def money(ctx, command: str, *args):
"""Handles various money-related commands."""
ensure_file_exists(MONEY_FILE, default_content={})
ensure_file_exists(RECEIVED_FILE, default_content={})

user_id = str(ctx.author.id)

if command == "view":
"""Shows the user's current balance."""
with open(MONEY_FILE, "r") as file:
money_data = json.load(file)

balance = money_data.get(user_id, 0)
await ctx.send(f"Your balance is ${balance}")

elif command == "list":
"""Lists all users' balances."""
with open(MONEY_FILE, "r") as file:
money_data = json.load(file)

balances = "\n".join(f": ${balance}"  for user_id, balance in money_data.items())
if balances:
await ctx.send(f"Balances:\n{balances}")
else:
await ctx.send("No balances available.")

elif command == "puzzle":
"""Shows the SHA-256 hash of the money key."""
if os.path.exists(SHA256_FILE):
with open(SHA256_FILE, "r") as file:
sha256_hash = file.read().strip()
await ctx.send(f"SHA-256 Hash: {sha256_hash}")
else:
await ctx.send("SHA-256 hash file does not exist.")

elif command == "decode":
"""Decodes the given answer and updates balance if correct."""
answer = args[0] if args else ""
correct_answer = open(SHA256_FILE).read()
hashed_answer = hashlib.sha256(answer.encode()).hexdigest()

if hashed_answer == correct_answer:
# Load received users
with open(RECEIVED_FILE, "r") as file:
received_data = json.load(file)

# Check if this user has already received their reward
if user_id in received_data:
await ctx.send("You have already claimed your reward.")
return

# Process the answer and update the balance
with open(MONEY_FILE, "r") as file:
money_data = json.load(file)

if user_id in money_data:
money_data[user_id] += 1  # Add $1 to the user's account
else:
money_data[user_id] = 1  # Initialize with $1 for the user's account

# Save the updated balance
with open(MONEY_FILE, "w") as file:
json.dump(money_data, file)

# Mark this user as having received their reward
received_data[user_id] = True
with open(RECEIVED_FILE, "w") as file:
json.dump(received_data, file)

await ctx.send("Correct answer! $1 has been added to your balance.")
else:
await ctx.send("Incorrect answer. Please try again.")

elif command == "renew":
"""Renew the money key and update the SHA-256 hash."""
if is_moderator(ctx):
new_key = ''.join(random_.choices(string.ascii_letters + string.digits, k=32))
new_hash = hashlib.sha256(new_key.encode()).hexdigest()

# Save the new key and hash to the respective files
with open(KEY_FILE, "w") as key_file:
key_file.write(new_key)
with open(SHA256_FILE, "w") as hash_file:
hash_file.write(new_hash)
os.remove("received.json")
await ctx.send("The money key has been renewed.")
else:
await ctx.send("You don't have the permission to do that.")
elif command == "transfer":
"""Transfer money to another user."""
if len(args) < 2:
await ctx.send("Please specify the user and the amount to transfer.")
return
recipient_id = str(args[0]).strip('')
try:
amount = int(args[1])
except ValueError:
await ctx.send("Invalid amount.  Please enter a number.")
return

with open(MONEY_FILE, "r") as file:
money_data = json.load(file)

if money_data.get(user_id, 0) < amount:
await ctx.send("You do not have enough balance to transfer that amount.")
return

if recipient_id not in money_data:
money_data[recipient_id] = 0

money_data[user_id] -= amount
money_data[recipient_id] += amount

with open(MONEY_FILE, "w") as file:
json.dump(money_data, file)

await ctx.send(f"Transferred ${amount} to .")

else:
await ctx.send("Invalid money command.")

# Fun Commands

@bot.command()
async def random(ctx, start: int = 0, end: int = 100):
"""Outputs a random number between start and end (inclusive)."""
number = random_.randint(start, end)
await ctx.send(f"Random number between {start} and {end}: {number}")

@bot.command()
async def wait(ctx, seconds: int):
"""Waits for a specified number of seconds."""
await asyncio.sleep(seconds)
await ctx.send(f"Waited for {seconds} seconds.")

@bot.command()
async def abcd(ctx):
"""Outputs a random letter: A, B, C, or D."""
letter = random_.choice(['A', 'B', 'C', 'D'])
await ctx.send(f"Random letter: {letter}")

@bot.command()
async def dice(ctx):
"""Outputs a graphic text art of one of six sides of a dice."""
dice_faces = [
"⚀", "⚁", "⚂", "⚃", "⚄", "⚅"
]
face = random_.choice(dice_faces)
await ctx.send(f"Dice roll: {face}")

@bot.command()
async def wordle(ctx):
"""Starts an infinite wordle game with a shared guess limit."""
if not os.path.exists(WORDLE_FILE):
await ctx.send("Wordle file does not exist.")
return
with open(DICTIONARY_FILE, "r") as file:
dictionary: dict = json.load(file)
with open(WORDLE_FILE, "w") as file:
def check(a):
return len(a) == 5
file.write(random_.choice(list(filter(check, list(dictionary.keys())))))
with open(WORDLE_FILE) as file:
correct_word = file.read()
if not os.path.exists(DICTIONARY_FILE):
await ctx.send("Dictionary file does not exist.")
return

def check(m):
return m.author == ctx.author and m.channel == ctx.channel

attempts = 0
guessed_words = []

await ctx.send("Guess the word (You have 6 attempts):")

while attempts < MAX_ATTEMPTS:
guess = await bot.wait_for('message', check=check)
guess_word = guess.content.strip().lower()

if len(guess_word) != len(correct_word):
await ctx.send(f"Please enter a word of length {len(correct_word)}.")
continue

if guess_word not in dictionary:
await ctx.send("Word not found in the dictionary. Try again.")
continue

if guess_word == correct_word.lower():
await ctx.send("Congratulations! You guessed the correct word.")
break

attempts += 1
guessed_words.append(guess_word)
remaining_attempts = MAX_ATTEMPTS - attempts
if remaining_attempts == 0:
await ctx.send(f"Game over! The correct word was '{correct_word}'.")
break
hint = generate_hint(guess_word, correct_word)
await ctx.send(f"Incorrect guess. Hint: {hint}.  You have {remaining_attempts} attempts left.")
def generate_hint(guess, correct_word):
"""Generates a hint based on the guess and the correct word."""
hint = []
correct = ["*", "*", "*", "*", "*"]
correct_word = correct_word.lower()
guess = guess.lower()

for i, letter in enumerate(guess):
if letter in correct_word:
if correct_word[i] == letter:
correct[i] = letter
else:
hint.append(letter)
return str(tuple(hint)) + " " + str(correct)

# Run the bot
bot.run(TOKEN)

Я пробовал программировать, используя взаимодействия вместо контекста, но это было слишком сложно программировать, поэтому я спросил ChatGPT, и он выдал дерьмовые ответы.
Итак, если кого-то интересуют различия между контекстом и взаимодействиями, прокомментируйте.
P/S: также присоединяйтесь к моему серверу разногласий https://discord.gg/H8gku9J2

Подробнее здесь: https://stackoverflow.com/questions/788 ... h-commands
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как преобразовать традиционный код в слэш-команды?
    Anonymous » » в форуме Python
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • Discord Bot не регистрирует слэш-команды в дереве команд
    Anonymous » » в форуме Python
    0 Ответы
    26 Просмотры
    Последнее сообщение Anonymous
  • Как удалить старые слэш-команды из бота Discord?
    Anonymous » » в форуме Python
    0 Ответы
    27 Просмотры
    Последнее сообщение Anonymous
  • Слэш-команды говорят: «Приложение не ответило вовремя», используя discord.py
    Anonymous » » в форуме Python
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous
  • Слэш-команды говорят, что «приложение не ответило вовремя», используя discord.py
    Anonymous » » в форуме Python
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»