MineBot/main.py

194 lines
7.8 KiB
Python
Raw Normal View History

2024-03-26 00:30:05 +00:00
import discord
2024-04-06 03:45:38 +00:00
from discord.ext import commands, tasks
from discord import app_commands
2024-03-26 00:30:05 +00:00
import os
2024-04-02 22:45:34 +00:00
from dotenv import load_dotenv
import sqlite3
2024-03-26 00:30:05 +00:00
import logging
2024-04-02 22:45:34 +00:00
from datetime import datetime, timezone
2024-04-06 03:45:38 +00:00
from discord import ui, Interaction
async def welcome_message():
# Find the #welcome channel
welcome_channel_id = int(os.getenv('WELCOME_CHANNEL_ID'))
welcome_channel = discord.utils.get(client.get_all_channels(), id=welcome_channel_id)
# Check if welcome message has already been sent in the channel
async for message in welcome_channel.history(limit=100):
if message.author == client.user and message.embeds:
print(f'Welcome message found. Message ID: {message.id}')
return # If the welcome message is found, exit the function
# Send welcome message in the #welcome channel
print(f'No welcome message found, creating one now')
view = discord.ui.View()
button = discord.ui.Button(label="Complete Onboarding")
view.add_item(button)
embed = discord.Embed(title="Welcome to the Server!", description="Here's how to get started:")
# embed.set_thumbnail(url=ctx.guild.icon)
embed.add_field(name="Step 1:",
value="Read the server rules in [#rules](https://discord.com/channels/1207801896656568480/1207802982574596137) channel.")
embed.add_field(name="Step 2:",
value="Check out some cool posts over in [#projects](https://discord.com/channels/1207801896656568480/1207807674075320390).")
embed.add_field(name="Step 3:", value="Complete Onboarding procedure to unlock the rest of the server.")
embed.set_footer(text="Enjoy your stay!")
await welcome_channel.send(embed=embed, view=OnboardButtons())
2024-04-09 02:17:16 +00:00
async def update_nickname(member, firstname, lastname): #update server nickname from DB
2024-04-06 03:45:38 +00:00
nickname = f"{firstname} {lastname}"
c.execute("UPDATE members SET nickname = ?, firstname = ?, lastname = ? WHERE user_id = ?", (nickname, firstname, lastname, member.id))
conn.commit()
2024-04-09 02:17:16 +00:00
print(f'Updated DB nickname for: {member}, {firstname}, {lastname}, {nickname}')
2024-04-06 03:45:38 +00:00
await member.edit(nick=nickname)
2024-04-09 02:17:16 +00:00
async def remove_user(user): #Remove user from DB and delete server nickname
c.execute("DELETE FROM members WHERE user_id = ?", (user.id,))
conn.commit()
if user:
await user.edit(nick=None)
#TODO demote user role
async def update_onboard(member): #increase onboarding status by 1
print(f'Updating onboarding for: {member.display_name}')
c.execute("SELECT onboarding_status FROM members WHERE user_id = ?", (member.id,))
status = c.fetchone()
status += 1
c.execute("UPDATE members SET onboarding_status = ? WHERE user_id = ?",
(status, member.id))
conn.commit()
async def add_member_to_role(member, role_name):
print(f"Adding {role_name} role to {member.display_name}")
role = discord.utils.get(member.guild.roles, name=role_name) # Get role from guild
if role:
await member.add_roles(role)
print(f"Added role '{role_name}' to member '{member.display_name}'")
else:
print(f"Role '{role_name}' not found in server '{member.guild.name}'")
2024-03-26 00:30:05 +00:00
2024-04-02 22:45:34 +00:00
# Load environment variables
2024-03-26 00:30:05 +00:00
load_dotenv()
2024-04-02 22:45:34 +00:00
# Setup logging
2024-04-09 02:17:16 +00:00
logging.basicConfig(filename='SparkBot.log', level=logging.INFO)
2024-03-26 00:30:05 +00:00
2024-04-02 22:45:34 +00:00
# Define intents
2024-03-26 00:30:05 +00:00
intents = discord.Intents.all()
2024-04-02 22:45:34 +00:00
# Connect to SQLite database
2024-03-26 00:30:05 +00:00
conn = sqlite3.connect('member_data.db')
2024-04-02 22:45:34 +00:00
c = conn.cursor()
2024-03-26 00:30:05 +00:00
2024-04-06 03:45:38 +00:00
# Create table with fields if it doesn't exist already
c.execute('''CREATE TABLE IF NOT EXISTS members (
user_id INTEGER PRIMARY KEY,
username TEXT, nickname TEXT,
firstname TEXT, lastname TEXT,
join_datetime TEXT,
onboarding_status INTEGER,
last_change_datetime TEXT
)''')
2024-03-26 00:30:05 +00:00
2024-04-02 22:45:34 +00:00
conn.commit()
2024-03-26 00:30:05 +00:00
2024-04-06 03:45:38 +00:00
class PersistentViewBot(commands.Bot):
def __init__(self):
intents = discord.Intents().all()
super().__init__(command_prefix=commands.when_mentioned_or("."), intents=intents)
async def setup_hook(self) -> None:
self.add_view(OnboardButtons())
#self.add_view(OnboardButtons()) #Add More views with more add_view commands.
client = PersistentViewBot()
class OnboardModal(discord.ui.Modal, title="Onboarding: "):
first_name = discord.ui.TextInput(
style=discord.TextStyle.short,
label="First name",
required=True,
placeholder="John "
)
last_name = discord.ui.TextInput(
style=discord.TextStyle.short,
label="Last Name",
required=True,
placeholder="Doe"
)
async def on_submit(self, interaction: discord.InteractionResponse):
await interaction.response.defer()
await update_nickname(member=self.user, firstname=self.first_name.value, lastname=self.last_name.value)
2024-04-09 02:17:16 +00:00
await update_onboard(member=self.user)
role_to_add = "Maker"
await add_member_to_role(member=self.user, role_name=role_to_add)
# print(f'First name: {self.first_name.value}')
# print(f'Last Name: {self.last_name.value}')
# print(f'User: {self.user.id}')
2024-04-06 03:45:38 +00:00
#channel = interaction.guild.get_channel(WELCOME_CHANNEL_ID)
#embed = discord.Embed(title="New Onboarding data", description=self.message.value)
#embed.set_author(name=self.user.nick)
#await channel.send(embed=embed)
2024-04-09 02:17:16 +00:00
await interaction.send_message("Thanks for completing onboarding!", ephemeral=True)
2024-04-06 03:45:38 +00:00
async def on_error(self, interaction: discord.Interaction, error):
...
class OnboardButtons(discord.ui.View):
def __init__(self):
super().__init__(timeout=None)
@discord.ui.button(label="Complete Onboarding", style=discord.ButtonStyle.green, custom_id="1")
async def onboard(self, interaction: discord.InteractionResponse, button: discord.ui.Button):
onboard_modal = OnboardModal()
onboard_modal.user = interaction.user
await interaction.response.send_modal(onboard_modal)
@client.event
2024-04-02 22:45:34 +00:00
async def on_ready():
2024-04-06 03:45:38 +00:00
print(f'Logged in as {client.user}')
await welcome_message()
2024-04-09 02:17:16 +00:00
try: #sync slash commands
2024-04-06 03:45:38 +00:00
synced = await client.tree.sync()
print(f'Slash Commands Synced. {str(len(synced))} Total Commands {synced}')
except Exception as e:
print(e)
2024-03-26 00:30:05 +00:00
2024-04-06 03:45:38 +00:00
@client.event
2024-04-02 22:45:34 +00:00
async def on_member_join(member):
2024-04-06 03:45:38 +00:00
await welcome_message()
2024-04-02 22:45:34 +00:00
# Check if member already exists in the database
c.execute("SELECT * FROM members WHERE user_id = ?", (member.id,))
existing_member = c.fetchone()
if not existing_member: # If it's the member's first time joining
# Add new member to the database
c.execute(
"INSERT OR REPLACE INTO members (user_id, username, join_datetime, onboarding_status, last_change_datetime) VALUES (?, ?, ?, ?, ?)",
(member.id, member.name, member.joined_at.isoformat(), 0, datetime.now(timezone.utc).isoformat()))
2024-03-26 00:30:05 +00:00
conn.commit()
2024-04-02 22:45:34 +00:00
# Update member nickname
await member.edit(nick=c.execute("SELECT nickname FROM members WHERE user_id = ?", (member.id,)).fetchone()[0])
2024-03-26 00:30:05 +00:00
2024-04-02 22:45:34 +00:00
# Log member join
logging.info(f'Member {member.name} joined the server.')
2024-03-26 00:30:05 +00:00
2024-04-09 02:17:16 +00:00
@client.tree.command(name="remove", description="Remove user from database, and remove user's nickname")
@app_commands.describe(member="The member you want to remove")
async def remove(interaction: discord.Integration, member: discord.Member):
await remove_user(member)
await interaction.response.send_message(f"User {member.display_name} Removed", ephemeral=True)
2024-03-26 00:30:05 +00:00
2024-04-06 03:45:38 +00:00
@client.event
2024-04-02 22:45:34 +00:00
async def on_member_remove(member):
# Log member leave
logging.info(f'Member {member.name} left the server.')
# Load bot token and welcome channel id from .env file
TOKEN = os.getenv('BOT_TOKEN')
WELCOME_CHANNEL_ID = os.getenv('WELCOME_CHANNEL_ID')
2024-04-09 02:17:16 +00:00
GUILD_ID = str(os.getenv('GUILD_ID'))
2024-03-26 00:30:05 +00:00
2024-04-02 22:45:34 +00:00
# Start bot
2024-04-06 03:45:38 +00:00
client.run(TOKEN)