Created
October 7, 2018 14:30
-
-
Save IAmJSD/38b18443e294595031f0d7656818fad7 to your computer and use it in GitHub Desktop.
The source code for the Rethink version of The Key Bakery. The required environment variables are PASSWORD (If using a Rethink password), TOKEN (for the Discord token), SERVER_ID (the server ID you are using it in) and APPLICATION_CHANNEL_ID (the channel key applications go to). I will not give support for this, I am only open sourcing.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import discord | |
import os | |
import logging | |
import datetime as dt | |
import random | |
import asyncio | |
import re | |
import rethinkdb as r | |
# Imports go here. | |
try: | |
import uvloop | |
loop = uvloop.new_event_loop() | |
except ImportError: | |
loop = asyncio.get_event_loop() | |
# Gets the best event loop. | |
logging.basicConfig(level=logging.INFO) | |
# Configures logging. | |
r.set_loop_type("asyncio") | |
# Sets the loop type to asyncio. | |
connection = loop.run_until_complete( | |
r.connect( | |
host="localhost", | |
password=os.environ.get("PASSWORD") or "" | |
) | |
) | |
# Gets the Rethink connection. | |
connection.use("bread_moe") | |
# Uses the Bread.moe DB. | |
client = discord.Client( | |
loop=loop, activity=discord.Game( | |
name="Key Generator 2018 - Tag me to join!" | |
) | |
) | |
# Defines the Discord client. | |
main_menu_messages = {} | |
# A dict of messages/owners on the main menu. | |
allowed_server = int(os.environ.get("SERVER_ID", "0")) | |
# Defines the allowed server. | |
user_id_re = re.compile("[0-9]{16,18}") | |
# The regex for a user ID. | |
async def show_main_menu(message): | |
em = discord.Embed( | |
title="Main menu:", | |
description="This is the main menu for " | |
"The Key Bakery. Created by JakeMakesStuff#0001.", | |
colour=discord.Colour.blue(), | |
timestamp=dt.datetime.now() | |
) | |
em.add_field( | |
name="Username:", | |
value=f"{message.author}", | |
inline=True | |
) | |
user_index = await r.table("users").get_all( | |
f"{message.author.id}", index="user_id" | |
).coerce_to("array").run(connection) | |
try: | |
user = user_index[0] | |
except IndexError: | |
user = None | |
if not user: | |
status = "User not applied." | |
elif user.get("blocked"): | |
status = "User blocked." | |
elif user.get("approved") is None: | |
status = "User awaiting approval." | |
elif not user['approved']: | |
status = "User denied." | |
else: | |
status = "User accepted." | |
staff = message.author.guild_permissions.manage_messages | |
if staff: | |
status += " (Staff)" | |
em.add_field( | |
name="Account Status:", | |
value=status, | |
inline=True | |
) | |
reactions = [] | |
if not user or (user.get("approved") is False and not user.get("blocked")): | |
em.add_field( | |
name="⌨ Apply", | |
value="Allows you to apply to use our service.", | |
inline=False | |
) | |
reactions.append("⌨") | |
elif user.get("approved") and not user.get("blocked"): | |
em.add_field( | |
name="📮 Resend Current Key", | |
value="Resends your current key. This does not make a new one.", | |
inline=False | |
) | |
reactions.append("📮") | |
em.add_field( | |
name="🔑 Reset Key", | |
value="Creates a new key and DMs it to you.", | |
inline=False | |
) | |
reactions.append("🔑") | |
em.add_field( | |
name="🔨 Template Generation", | |
value="DMs a link to the ShareX/KShare template generator " | |
"with your key pre-prepared.", | |
inline=False | |
) | |
reactions.append("🔨") | |
if staff: | |
em.add_field( | |
name="⛔ Blacklist Users", | |
value="Allows you to blacklist users.", | |
inline=False | |
) | |
reactions.append("⛔") | |
em.add_field( | |
name="❌ Exit", | |
value="Exits this menu.", | |
inline=False | |
) | |
reactions.append("❌") | |
try: | |
m = await message.channel.send(embed=em) | |
main_menu_messages[m.id] = message.author.id | |
for reaction in reactions: | |
await m.add_reaction(reaction) | |
except discord.Forbidden: | |
pass | |
# Renders the main menu. | |
async def disallowed_server(message): | |
try: | |
await message.channel.send( | |
embed=discord.Embed( | |
title="Disallowed server:", | |
description="This bot can only be used in the " | |
"bread.moe server.", | |
colour=discord.Colour.red(), | |
timestamp=dt.datetime.now() | |
) | |
) | |
except discord.Forbidden: | |
pass | |
# Sent in disallowed servers when tagged. | |
async def key_application_handler(message, user): | |
user_index = await r.table("users").get_all( | |
f"{user.id}", index="user_id" | |
).coerce_to("array").run(connection) | |
try: | |
user_db = user_index[0] | |
except IndexError: | |
user_db = None | |
if not user_db or (user_db.get("approved") is False and not user_db.get("blocked")): | |
em = discord.Embed(colour=discord.Colour.green()) | |
em.set_footer(text="The Key Bakery") | |
em.add_field( | |
name="⭐ You applied!", | |
value="Congratulations! You applied to get a key for one" | |
" of the best image hosting services (we hope) on the internet." | |
" That was easy, wasn't it. You will be DM'd if we accept you.", | |
inline=False | |
) | |
em.add_field( | |
name="🕰 How long will my application take?", | |
value="I (the bot) automagically tagged the staff behind the scene" | |
"s so we can manually verify your account. The amount of time will" | |
" depend on how busy we are. We may deny your application if you a" | |
"re obnoxious about it, tag us in an attempt to speed it up or hav" | |
"e a suspicious account.", | |
inline=False | |
) | |
if user_db: | |
user_db['approved'] = None | |
else: | |
user_db = { | |
"user_id": f"{user.id}", | |
"blocked": False, | |
"approved": None | |
} | |
await r.table("users").insert(user_db, conflict="update").run(connection) | |
staff_em = discord.Embed( | |
title="Key Application:", | |
colour=discord.Colour.green(), | |
timestamp=dt.datetime.now() | |
) | |
staff_em.add_field( | |
name="Account Created:", | |
value=f"{user.created_at}" | |
) | |
staff_em.add_field( | |
name="Account Joined:", | |
value=f"{user.joined_at}" | |
) | |
staff_em.add_field( | |
name="User:", | |
value=f"{user.mention} ({user.id})" | |
) | |
staff_em.set_footer( | |
text=f"{user.id}" | |
) | |
try: | |
channel = client.get_channel(int( | |
os.environ['APPLICATION_CHANNEL_ID'] | |
)) | |
m = await channel.send("@here", embed=staff_em) | |
await m.add_reaction("🎟") | |
await m.add_reaction("❌") | |
await m.add_reaction("⛔") | |
except discord.Forbidden: | |
return | |
except KeyError: | |
return | |
try: | |
await message.edit(embed=em) | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
del main_menu_messages[message.id] | |
# Handles key applications. | |
async def blacklist_handler(message, user): | |
if not user.guild_permissions.manage_messages: | |
return | |
try: | |
await message.edit( | |
embed=discord.Embed( | |
title="Type mentions/IDs of users to blacklist:", | |
description="Seperate them with spaces. Quick! You have 2" | |
" minutes.", | |
datestamp=dt.datetime.now() | |
) | |
) | |
except discord.Forbidden: | |
return | |
except discord.NotFound: | |
return | |
def check(m): | |
return m.author.id == user.id and\ | |
message.channel.id == m.channel.id | |
try: | |
reply_msg = await client.wait_for( | |
"message", check=check, timeout=120 | |
) | |
except asyncio.TimeoutError: | |
try: | |
return await message.edit( | |
embed=discord.Embed( | |
title="You timed out:", | |
description="The operation was " | |
"killed because you timed out.", | |
datestamp=dt.datetime.now(), | |
colour=discord.Colour.red() | |
) | |
) | |
except discord.Forbidden: | |
return | |
except discord.NotFound: | |
return | |
result = "" | |
for msg_part in [ | |
x for x in reply_msg.content.split() | |
if x != "" | |
]: | |
match = user_id_re.search(msg_part) | |
if not match: | |
result += f"{msg_part} - Invalid tag/user ID\n" | |
continue | |
user_id = int(match.group(0)) | |
user_index = await r.table("users").get_all( | |
f"{user_id}", index="user_id" | |
).coerce_to("array").run(connection) | |
try: | |
user_db = user_index[0] | |
user_db['blocked'] = True | |
except IndexError: | |
user_db = { | |
"user_id": f"{user_id}", | |
"blocked": True | |
} | |
await r.table("users").insert(user_db, conflict="update").run(connection) | |
result += f"{msg_part} - User successfully blacklisted\n" | |
if result == "": | |
result = "No message content given." | |
try: | |
await reply_msg.delete() | |
except discord.Forbidden: | |
pass | |
em = discord.Embed( | |
title="Blacklist Results:", | |
description=f"```{result}```", | |
timestamp=dt.datetime.now() | |
) | |
try: | |
await message.edit( | |
embed=em | |
) | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
# The blacklist handler. | |
@client.event | |
async def on_reaction_add(reaction, user): | |
if user.id == client.user.id: | |
# This is the bot. | |
return | |
if reaction.message.id in main_menu_messages: | |
# Ok this is a main menu message. | |
try: | |
await reaction.message.remove_reaction( | |
reaction, user | |
) | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
# Removes the reaction. | |
if user.id != main_menu_messages[reaction.message.id]: | |
# This isn't the user that created the embed. | |
return | |
reaction_str = str(reaction.emoji) | |
# Ensures the reaction is a string. | |
if reaction_str == "❌": | |
# Deletes the message. | |
try: | |
return await reaction.message.delete() | |
except discord.Forbidden: | |
return | |
except discord.NotFound: | |
return | |
if reaction_str == "⌨": | |
# Handles applying for a key. | |
try: | |
await reaction.message.clear_reactions() | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
return await key_application_handler( | |
reaction.message, user | |
) | |
if reaction_str == "⛔": | |
# Handles blacklisting users. | |
try: | |
await reaction.message.clear_reactions() | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
return await blacklist_handler( | |
reaction.message, user | |
) | |
if reaction_str == "📮": | |
# Handles resending the key. | |
try: | |
await reaction.message.clear_reactions() | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
user_index = await r.table("users").get_all( | |
f"{user.id}", index="user_id" | |
).coerce_to("array").run(connection) | |
try: | |
user_db = user_index[0] | |
except IndexError: | |
return | |
if user_db.get("approved"): | |
# Ok, we shall try a key resend. | |
try: | |
await user.send(f"Your key is `{user_db['id']}`") | |
await reaction.message.edit( | |
embed=discord.Embed( | |
title="Successfully DM'd:", | |
description="Check your DMs.", | |
colour=discord.Colour.green(), | |
timestamp=dt.datetime.now() | |
) | |
) | |
except discord.Forbidden: | |
try: | |
await reaction.message.edit( | |
embed=discord.Embed( | |
title="Could not DM:", | |
description="Do you have DMs for me on?", | |
colour=discord.Colour.red(), | |
timestamp=dt.datetime.now() | |
) | |
) | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
del main_menu_messages[reaction.message.id] | |
return | |
if reaction_str == "🔨": | |
# Handles sending a link to the template generator with the | |
# key pre-added. | |
try: | |
await reaction.message.clear_reactions() | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
user_index = await r.table("users").get_all( | |
f"{user.id}", index="user_id" | |
).coerce_to("array").run(connection) | |
try: | |
user_db = user_index[0] | |
except IndexError: | |
return | |
if user_db.get("approved"): | |
# Ok, we shall try sending the URL. | |
try: | |
await user.send( | |
"The URL is https://bread.moe/" | |
f"templategenerator.html?key={user_db['id']}." | |
" **DO NOT SHARE THIS URL.**" | |
) | |
await reaction.message.edit( | |
embed=discord.Embed( | |
title="Successfully DM'd:", | |
description="Check your DMs.", | |
colour=discord.Colour.green(), | |
timestamp=dt.datetime.now() | |
) | |
) | |
except discord.Forbidden: | |
try: | |
await reaction.message.edit( | |
embed=discord.Embed( | |
title="Could not DM:", | |
description="Do you have DMs for me on?", | |
colour=discord.Colour.red(), | |
timestamp=dt.datetime.now() | |
) | |
) | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
del main_menu_messages[reaction.message.id] | |
return | |
if reaction_str == "🔑": | |
# Handles reseting the key. | |
try: | |
await reaction.message.clear_reactions() | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
user_index = await r.table("users").get_all( | |
f"{user.id}", index="user_id" | |
).coerce_to("array").run(connection) | |
try: | |
user_db = user_index[0] | |
except IndexError: | |
return | |
if user_db.get("approved"): | |
# Time to generate a new key and send it. | |
await r.table("users").get(user_db['id']).delete().run(connection) | |
user_db['id'] = await r.uuid().run(connection) | |
await r.table("users").insert(user_db).run(connection) | |
try: | |
await user.send(f"Your key is `{user_db['id']}`") | |
await reaction.message.edit( | |
embed=discord.Embed( | |
title="Successfully DM'd:", | |
description="Check your DMs.", | |
colour=discord.Colour.green(), | |
timestamp=dt.datetime.now() | |
) | |
) | |
except discord.Forbidden: | |
try: | |
await reaction.message.edit( | |
embed=discord.Embed( | |
title="Could not DM:", | |
description="Do you have DMs for me on?", | |
colour=discord.Colour.red(), | |
timestamp=dt.datetime.now() | |
) | |
) | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
del main_menu_messages[reaction.message.id] | |
return | |
return | |
if len(reaction.message.embeds) == 1 and ( | |
reaction.message.author.id == client.user.id | |
): | |
# This *could* be a key application embed. | |
embed = reaction.message.embeds[0] | |
if embed.title == "Key Application:": | |
# Oh sweet! | |
try: | |
await reaction.message.remove_reaction( | |
reaction, user | |
) | |
except discord.Forbidden: | |
pass | |
except discord.NotFound: | |
pass | |
# Removes the reaction. | |
reaction_str = str(reaction.emoji) | |
# Ensures the reaction is a string. | |
if reaction_str == "⛔": | |
# We chose to block the user. | |
await r.table("users").get(f"{embed.footer.text}").update({ | |
"blocked": True | |
}).run(connection) | |
embed.title = "User Blocked:" | |
embed.colour = discord.Colour.red() | |
try: | |
await reaction.message.clear_reactions() | |
except discord.Forbidden: | |
pass | |
user = client.get_user(int(embed.footer.text)) | |
if user: | |
try: | |
await user.send( | |
"You were blocked from using bread.moe" | |
) | |
except discord.Forbidden: | |
pass | |
try: | |
return await reaction.message.edit(embed=embed) | |
except discord.Forbidden: | |
return | |
if reaction_str == "❌": | |
# We chose to deny the application, not block the user. | |
await r.table("users").get(f"{embed.footer.text}").update({ | |
"approved": False | |
}).run(connection) | |
embed.title = "Application Denied:" | |
embed.colour = discord.Colour.red() | |
try: | |
await reaction.message.clear_reactions() | |
except discord.Forbidden: | |
pass | |
user = client.get_user(int(embed.footer.text)) | |
if user: | |
try: | |
await user.send( | |
"Your key application was denied" | |
) | |
except discord.Forbidden: | |
pass | |
try: | |
return await reaction.message.edit(embed=embed) | |
except discord.Forbidden: | |
return | |
if reaction_str == "🎟": | |
# We chose to accept this user. | |
user_index = await r.table("users").get_all( | |
f"{embed.footer.text}", index="user_id" | |
).coerce_to("array").run(connection) | |
try: | |
user_db = user_index[0] | |
except IndexError: | |
return | |
embed.title = "Application Approved:" | |
try: | |
await reaction.message.clear_reactions() | |
except discord.Forbidden: | |
pass | |
user = client.get_user(int(embed.footer.text)) | |
if user: | |
try: | |
em = discord.Embed( | |
title="Key Approved:", | |
description="Congratulations! Your " | |
"key application has been accepted.", | |
colour=discord.Colour.green(), | |
timestamp=dt.datetime.now() | |
) | |
em.add_field( | |
name="Key:", | |
value=user_db['id'] | |
) | |
em.add_field( | |
name="ShareX/KShare Template Generation:", | |
value="https://bread.moe/templategene" | |
f"rator.html?key={user_db['id']} - Do NOT share " | |
"this link, it has your key embedded in it" | |
) | |
await user.send( | |
embed=em | |
) | |
except discord.Forbidden: | |
pass | |
await r.table("users").get(user_db['id']).update({ | |
"approved": True | |
}).run(connection) | |
try: | |
return await reaction.message.edit(embed=embed) | |
except discord.Forbidden: | |
return | |
# Handles reactions. | |
@client.event | |
async def on_message(message): | |
if len(message.mentions) == 0: | |
# Don't bother. | |
return | |
if client.user.id in [x.id for x in message.mentions]: | |
# Ok we are intrested. | |
if not message.guild or message.guild.id != allowed_server: | |
return await disallowed_server(message) | |
await show_main_menu(message) | |
# Defines on_message. | |
@client.event | |
async def on_message_delete(message): | |
if message.id in main_menu_messages: | |
del main_menu_messages[message.id] | |
# Stops a memory leak. | |
client.run(os.environ['TOKEN']) | |
# Starts the client. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment