shbot/bot.py

449 lines
18 KiB
Python

import discord
import asyncio
import time
import datetime
import random
import os
from os import system
from os import environ
from discord.ext import commands
from discord.commands import Option
from discord.commands import permissions
from discord.ui import InputText, Modal
def left(s, amount):
return s[:amount]
def right(s, amount):
return s[-amount:]
def mid(s, offset, amount):
return s[offset:offset+amount]
intents = discord.Intents.default()
intents.members = True
intents.message_content = True
intents.presences = True
token = os.environ['TOKEN']
prefix = os.environ['PREFIX']
bot = commands.Bot(intents=intents, command_prefix=prefix)
admin_role=261603488331595776
member_role=261603747711418371
gm_role=511893805956595722
def admin(ctx):
if ctx.guild.get_role(admin_role) in ctx.author.roles:
return True
def member(ctx):
if ctx.guild.get_role(member_role) in ctx.author.roles:
return True
def is_admin():
async def predicate(ctx):
if ctx.guild.get_role(admin_role) in ctx.author.roles:
return True
return commands.check(predicate)
def is_member():
async def predicate(ctx):
if ctx.guild.get_role(member_role) in ctx.author.roles:
return True
return commands.check(predicate)
def is_gm():
async def predicate(ctx):
if ctx.guild.get_role(gm_role) in ctx.author.roles:
return True
return commands.check(predicate)
emojinumbers = ["0\u20E3", "1\u20E3" , "2\u20E3" , "3\u20E3" , "4\u20E3" , "5\u20E3" , "6\u20E3" , "7\u20E3" , "8\u20E3" , "9\u20E3"]
alphabet = {"a" : "🇦","b" : "🇧","c" : "🇨","d" : "🇩","e" : "🇪","f" : "🇫","g" : "🇬","h" : "🇭","i" : "🇮","j" : "🇯","k" : "🇰","l" : "🇱","m" : "🇲","n" : "🇳","o" : "🇴","p" : "🇵","q" : "🇶","r" : "🇷","s" : "🇸","t" : "🇹","u" : "🇺","v" : "🇻","w" : "🇼","x" : "🇽","y" : "🇾","z" : "🇿","0" : "0\u20E3","1" : "1\u20E3","2" : "2\u20E3","3" : "3\u20E3","4" : "4\u20E3","5" : "5\u20E3","6" : "6\u20E3","7" : "7\u20E3","8" : "8\u20E3","9" : "9\u20E3"}
bot.help_command = commands.DefaultHelpCommand(dm_help=False, no_category="Befehle die du nutzen kannst")
@bot.event
async def on_command_error(ctx, error):
try:
await ctx.message.delete()
except:
print("message not found")
print(error)
em = discord.Embed(title="Error", description=error, colour=0xFF0000)
await ctx.send(content="ups, da ist wohl was schief gegangen :( traurige Bot Geräusche...", embed=em, delete_after=20)
@bot.event
async def on_ready():
print("Bot ready on Version %s..." % discord.__version__)
activity = discord.Activity(name='%shelp' % prefix, type=discord.ActivityType.listening)
#activity = discord.Game('%shelp for Help' % prefix)
await bot.change_presence(status=discord.Status.online, activity=activity)
#@bot.listen()
#async def on_presence_update(before, after):
# if not before.is_on_mobile() and after.id == 274197471515639808 and after.is_on_mobile():
# await bot.get_channel(512004326382632961).send("https://cdn.discordapp.com/attachments/512004326382632961/979468921985982514/unknown.png")
class Confirm(discord.ui.View):
def __init__(self):
super().__init__()
self.value = None
@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("Bestätigt", ephemeral=True, delete_after=5.0)
self.value = True
self.stop()
@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("Abgebrochen", ephemeral=True, delete_after=5.0)
self.value = False
self.stop()
@bot.slash_command(guild_ids=[261575556708040705])
@commands.has_role(member_role)
async def roll(ctx,
dice: Option(str, "Würfel den/die du werfen willst. z.B. W20, 3d6", default="W20"),
):
"""Rolle einen oder mehrere Würfel"""
rollt = 0
rolle = " "
roll = dice.lower()
if "d" in roll:
rolls = "d"
if "w" in roll:
rolls = "w"
rollc = roll.split(rolls)[0]
if rollc == "":
rollc = 1
else:
rollc = int(rollc)
rolld = int(roll.split(rolls)[1])
for x in range(rollc):
rollo = random.randint(1, rolld)
rollt = rollt + rollo
rolle = rolle + " :game_die: " + str(rollo) + " "
if rollc > 1:
rolltotal = "Total: " + str(rollt)
else:
rolltotal = ""
if rollc > 12:
rolltotal = rolle + "\n" + rolltotal
rolle = ""
em = discord.Embed(title=rolle, description=rolltotal, colour=0x009933)
await ctx.response.send_message(embed=em)
@bot.slash_command(guild_ids=[261575556708040705])
@commands.has_role(gm_role)
async def gmroll(ctx,
dice: Option(str, "Würfel den/die du werfen willst. z.B. W20, 3d6", default="W20"),
):
"""Rolle einen oder mehrere Würfel verdeckt"""
rollt = 0
rolle = " "
roll = dice.lower()
if "d" in roll:
rolls = "d"
if "w" in roll:
rolls = "w"
rollc = roll.split(rolls)[0]
if rollc == "":
rollc = 1
else:
rollc = int(rollc)
rolld = int(roll.split(rolls)[1])
for x in range(rollc):
rollo = random.randint(1, rolld)
rollt = rollt + rollo
rolle = rolle + " :game_die: " + str(rollo) + " "
if rollc > 1:
rolltotal = "Total: " + str(rollt)
else:
rolltotal = ""
if rollc > 12:
rolltotal = rolle + "\n" + rolltotal
rolle = ""
em = discord.Embed(title=rolle, description=rolltotal, colour=0x009933)
await ctx.response.send_message(embed=em, ephemeral=True)
class MyModal(Modal):
def __init__(self) -> None:
self.message_id = 0
super().__init__(title="Emojitext")
self.add_item(InputText(label="Dein Text:", placeholder="Jeder Buchstabe nur einmal!"))
def set_message_id(self, message_id):
self.message_id = message_id
async def callback(self, interaction: discord.Interaction):
await interaction.response.send_message(content="Füge Reaktionen hinzu...", ephemeral=True)
emojitext = self.children[0].value.lower()
original_message = await interaction.channel.fetch_message(self.message_id)
for x in list(emojitext):
await original_message.add_reaction(alphabet[x])
@bot.message_command(name="Emoji Text", guild_ids=[261575556708040705])
@commands.has_role(member_role)
async def emoji_text(ctx, message: discord.Message):
modal = MyModal()
modal.title = "Emoji Bot"
modal.set_message_id(message.id)
await ctx.interaction.response.send_modal(modal)
@bot.command(help="Umfrage mit mehreren Antwortmöglichkeiten", usage="<Frage> | <Antwort1> | <Antwort2> ...")
@is_member()
async def survey(ctx, *, arg):
await ctx.message.delete()
answers = arg.split("|")
question = answers[0]
answers.remove(question)
desc = ""
z = 1
for y in answers:
desc = desc + emojinumbers[z] + " - " + y + "\n"
z = z + 1
em = discord.Embed(title=question, description=desc, colour=0x00E0FF)
em.set_author(name=ctx.author.display_name, url=None, icon_url=ctx.author.avatar.url)
ask_msg = await ctx.send(content="||@everyone||",embed=em)
a = 0
for x in emojinumbers:
if a < z and a != 0:
await ask_msg.add_reaction(x)
a = a + 1
await ask_msg.create_thread(name="Diskussion")
@bot.command(help="Umfrage bearbeiten", usage="ID | <Frage> | <Antwort1> | <Antwort2> ...", hidden=True)
@is_member()
async def surveyedit(ctx, *, arg):
#Nutzung: !surveyedit ID | <Frage> | <Antwort1> | <Antwort2> ...
await ctx.message.delete()
answers = arg.split("|")
survey_id = answers[0]
question = answers[1]
answers.remove(survey_id)
answers.remove(question)
desc = ""
z = 1
for y in answers:
desc = desc + emojinumbers[z] + " - " + y + "\n"
z = z + 1
em = discord.Embed(title=question, description=desc, colour=0x00E0FF)
em.set_author(name=ctx.author.display_name, url=None, icon_url=ctx.author.avatar.url)
survey_msg = await ctx.channel.fetch_message((int(survey_id)))
await survey_msg.edit(embed=em)
@bot.command(help="Ja/Nein Umfrage", usage="<Frage>")
@is_member()
async def vote(ctx, *, arg):
await ctx.message.delete()
em = discord.Embed(description=arg, colour=0x00E0FF)
em.set_author(name=ctx.author.display_name, url=None, icon_url=ctx.author.avatar.url)
ask_msg = await ctx.send(content="||@everyone||",embed=em)
for x in ["", "", ""]:
await ask_msg.add_reaction(x)
await ask_msg.create_thread(name="Diskussion")
@bot.command(help="den Bot etwas sagen lassen", usage="<text>")
@is_admin()
async def say(ctx, *, arg):
await ctx.message.delete()
em = discord.Embed(description=arg, colour=0x00E0FF)
await ctx.message.channel.send(embed=em)
@bot.command(help="Starte ne Runde PnP", usage="@Rolle")
@is_gm()
async def start(ctx, role_mention):
await ctx.message.delete()
pnp_info = await ctx.guild.fetch_channel(435501602485305345)
pnp_voice = await ctx.guild.fetch_channel(435869507123281920)
role = ctx.message.role_mentions[0]
em = discord.Embed(description='gespieltes PnP: %s\nTeilnehmer (zum Start):' % role.mention, colour=0x00770d)
move_members = []
for c in ctx.guild.voice_channels:
for m in c.members:
if role in m.roles:
move_members.append(m)
em.add_field(name=":white_check_mark: " + m.display_name, value = m.mention + " ist am Start! Juhu!", inline=False)
for m in move_members:
await m.move_to(pnp_voice)
start_msg = await pnp_info.send(content=":game_die: **INFO: PnP Sitzung gestartet!**",embed=em)
text_file = open("start_id.txt", "w")
text_file.write(str(start_msg.id))
text_file.close()
@bot.command(help="Beende die gestartete Runde PnP", usage="")
@is_gm()
async def stop(ctx):
await ctx.message.delete()
pnp_info = await ctx.guild.fetch_channel(435501602485305345)
pnp_voice = await ctx.guild.fetch_channel(435869507123281920)
move_to_talk = await ctx.guild.fetch_channel(801869864745697280)
text_file = open("start_id.txt", "r")
start_id = text_file.read()
text_file.close()
start_msg = await pnp_info.fetch_message(start_id)
now_time = datetime.datetime.utcnow().replace(microsecond=0, tzinfo=datetime.timezone.utc)
then_time = start_msg.created_at.replace(microsecond=0, tzinfo=datetime.timezone.utc)
dauer = str(now_time - then_time)
for m in pnp_voice.members:
await m.move_to(move_to_talk)
await start_msg.edit(content=":game_die: **INFO: PnP Sitzung beendet!** Dauer: %s" % dauer)
@bot.command(help="bringt dich ins Labor :)", usage="")
@is_admin()
async def labor(ctx):
await ctx.message.delete()
await ctx.author.move_to(bot.get_channel(765601577334865972))
@bot.command(help="Hinzufügen einer Rolle mit Textchannel und hinzufügen von Usern zur Rolle", usage="\"Name der Rolle\" @User1 @User2 ...")
@is_admin()
async def add(ctx, *, arg):
await ctx.message.delete()
try:
role_name = ctx.message.content.split("\"")[1]
text_name = role_name.lower().replace(" ", "-")
role = await ctx.guild.create_role(name=role_name, mentionable=True)
overwrites = {
ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False),
role: discord.PermissionOverwrite(read_messages=True)
}
channel = await ctx.guild.create_text_channel(text_name, overwrites=overwrites, topic="Dieser Channel wurde von SecondBot erstellt.")
for user in ctx.message.mentions:
await user.add_roles(role)
em = discord.Embed(title=':loudspeaker: Ein neuer Channel für %s!' % role_name, description='Herzlich Willkommen! Es gibt nun eine neue Gruppe %s und diesen wunderbaren Channel hier! Der Channel ist nur für euch und die Admins sichtbar.' % role.mention, colour=0xffa500)
await channel.send(embed=em)
except Exception as e:
em = discord.Embed(title="Error Code", description=e, color=0xff0000)
await ctx.channel.send(content="Das hat nicht funktioniert. Syntax: !add \"<Rolle>\" <User Mentions>", embed=em, delete_after=20.0)
@bot.command(help="Löschen von Nachrichten", usage="all|<Anzahl>|x minutes/hours/days/weeks")
@is_admin()
async def purge(ctx, *, arg):
#Nutzung: !purge all|<Anzahl>|x minutes/hours/days/weeks
await ctx.message.delete()
by_limit = False
by_time = False
try:
if ctx.message.content.split(" ")[2] == "minutes":
by_time = True
delta = datetime.timedelta(minutes=int(ctx.message.content.split(" ")[1]))
if ctx.message.content.split(" ")[2] == "hours":
by_time = True
delta = datetime.timedelta(hours=int(ctx.message.content.split(" ")[1]))
if ctx.message.content.split(" ")[2] == "days":
by_time = True
delta = datetime.timedelta(days=int(ctx.message.content.split(" ")[1]))
if ctx.message.content.split(" ")[2] == "weeks":
by_time = True
delta = datetime.timedelta(weeks=int(ctx.message.content.split(" ")[1]))
except IndexError:
try:
if ctx.message.content.split(" ")[1] == "all":
by_limit = True
limit = None
else:
by_limit = True
limit = int(ctx.message.content.split(" ")[1])
except:
print("List error, ploz ignore")
except:
print("List error, ploz ignore")
if by_time:
after_time = datetime.datetime.utcnow() - delta
question = await ctx.send("Would you really like to delete all messages of the last {} {}?".format(ctx.message.content.split(" ")[1], ctx.message.content.split(" ")[2]))
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) == ""
await question.add_reaction("")
try:
reaction, user = await bot.wait_for("reaction_add", timeout=60.0, check=check)
except asyncio.TimeoutError:
await question.delete()
else:
await question.delete()
deleted = await ctx.channel.purge(limit=200, after=after_time)
await ctx.send(content='Ich habe {} Nachrichten gelöscht.'.format(len(deleted)), delete_after=5.0)
if by_limit:
if limit == None:
count = "alle"
else:
count = str(limit)
question = await ctx.send("Sollen wirklich {} Nachrichten gelöscht werden?".format(count))
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) == ""
await question.add_reaction("")
try:
reaction, user = await bot.wait_for("reaction_add", timeout=60.0, check=check)
except asyncio.TimeoutError:
await question.delete()
else:
await question.delete()
deleted = await ctx.channel.purge(limit=limit)
await ctx.send(content='Ich habe {} Nachrichten gelöscht.'.format(len(deleted)), delete_after=5.0)
@bot.command(help="zeige einem User Liebe", usage="<@User1> <@User2> ...")
@is_member()
async def liebe(ctx, *, arg):
await ctx.message.delete()
for user in ctx.message.mentions:
if user.dm_channel == None:
await user.create_dm()
await user.dm_channel.send("❤️ von {}".format(ctx.author.display_name))
@bot.command(help="zeige einem User Hiebe", usage="<@User1> <@User2> ...")
@is_member()
async def hiebe(ctx, *, arg):
await ctx.message.delete()
for user in ctx.message.mentions:
if user.dm_channel == None:
await user.create_dm()
await user.dm_channel.send("HIEBE :punch: von {}".format(ctx.author.display_name))
@bot.command(help="kickt Member ohne Rolle, die 7 Tage nicht online waren", usage="")
@is_admin()
async def prune(ctx):
await ctx.message.delete()
count = await ctx.guild.estimate_pruned_members(days=30)
view = Confirm()
question = await ctx.send("Sollen wirklich {} Leichen gekickt werden?".format(count), view=view)
await view.wait()
if view.value is None:
await question.delete()
await ctx.send(content="Zeit ausgelaufen", delete_after=5.0)
elif view.value:
await question.delete()
deleted = await ctx.guild.prune_members(days=7)
await ctx.send(content='Ich habe {} Leiche(n) beseitigt.'.format(deleted), delete_after=5.0)
else:
await question.delete()
@bot.command(help="Rolle einen oder mehrere Würfel", usage="<anzahl_optional>W<seitenzahl> (z.B. %sroll W20 oder %sroll 10W6)" % (prefix, prefix))
@is_member()
async def roll(ctx, arg):
await ctx.message.delete()
rollt = 0
rolle = " "
roll = arg.lower()
if "d" in roll:
rolls = "d"
if "w" in roll:
rolls = "w"
rollc = roll.split(rolls)[0]
if rollc == "":
rollc = 1
else:
rollc = int(rollc)
rolld = int(roll.split(rolls)[1])
for x in range(rollc):
rollo = random.randint(1, rolld)
rollt = rollt + rollo
rolle = rolle + " :game_die: " + str(rollo) + " "
if rollc > 1:
rolltotal = "Total: " + str(rollt)
else:
rolltotal = ""
if rollc > 12:
rolltotal = rolle + "\n" + rolltotal
rolle = ""
em = discord.Embed(title=rolle, description=rolltotal, colour=0x009933)
await ctx.send(embed=em)
bot.run(token)