166 lines
5.0 KiB
Python
166 lines
5.0 KiB
Python
import discord
|
||
from discord.ext import commands
|
||
import logging
|
||
from dotenv import load_dotenv
|
||
from pathlib import Path
|
||
import os
|
||
import sqlite_utils
|
||
import re
|
||
|
||
# Show the path we expect to load
|
||
# Explicitly find the .env file in the same directory as the script
|
||
|
||
env_path = Path(__file__).resolve().parent / ".env"
|
||
print(f"Looking for .env at: {env_path}")
|
||
|
||
|
||
# Load the env file
|
||
load_dotenv(dotenv_path=env_path)
|
||
|
||
# Print token (or None)
|
||
token = os.getenv("DISCORD_TOKEN")
|
||
print(f"Loaded token Succesfully")
|
||
|
||
if token is None:
|
||
raise RuntimeError(".env file not loaded or DISCORD_TOKEN not set.")
|
||
|
||
# --- Load bad words from file into a set ---
|
||
with open("bad_words.txt", "r", encoding="utf-8") as f:
|
||
BAD_WORDS = {line.strip().lower() for line in f if line.strip()}
|
||
|
||
# Compile regex pattern for performance
|
||
# \b = word boundary, (?i) = case-insensitive
|
||
bad_words_pattern = re.compile(r"\b(" + "|".join(map(re.escape, BAD_WORDS)) + r")\b", re.IGNORECASE)
|
||
|
||
|
||
token = os.getenv("DISCORD_TOKEN")
|
||
|
||
handler = logging.FileHandler(filename='discord.log', encoding='utf-8', mode='w')
|
||
intents = discord.Intents.default()
|
||
intents.message_content = True
|
||
intents.members = True
|
||
|
||
bot = commands.Bot(command_prefix='!', intents=intents)
|
||
|
||
@bot.event
|
||
async def on_ready():
|
||
print(f"{bot.user.name} is ready")
|
||
|
||
#Imports users from Discord to users table in dbot.db
|
||
for guild in bot.guilds:
|
||
print(f"Importing members from guild: {guild.name} ({guild.id})")
|
||
async for member in guild.fetch_members(limit=None):
|
||
add_user_to_db(member)
|
||
print(f"All members have been added/updated in the database.")
|
||
|
||
@bot.event
|
||
async def on_member_join(member):
|
||
await member.send(f"Welcome to the server {member.name}")
|
||
|
||
#Responding to cuss words
|
||
@bot.event
|
||
async def on_message(message):
|
||
if message.author == bot.user:
|
||
return
|
||
|
||
# Check if message contains a bad word
|
||
if bad_words_pattern.search(message.content):
|
||
await message.channel.send(
|
||
f"{message.author.mention} - bro that’s a bad worddddd!"
|
||
)
|
||
|
||
await bot.process_commands(message)
|
||
|
||
@bot.command()
|
||
async def hello(ctx):
|
||
await ctx.send(f"Hello{ctx.author.mention}!")
|
||
|
||
##############################Points System Setup##################################################
|
||
|
||
#Initialize SQLite database
|
||
db = sqlite_utils.Database("dbot.db")
|
||
|
||
# Creates the table if it does not exist (should only do this part once)
|
||
if "users" not in db.table_names():
|
||
db["users"].create(
|
||
{"id": str, #Discord ID
|
||
"name": str, # ACTUAL Discord name
|
||
"discriminator": str, #4-digits after the username
|
||
"displayName": str, # Name that appears in the server
|
||
"points": int, #Points lol
|
||
"title": str, #Field that will bestow a title upon the user depending on amount of points/level
|
||
},
|
||
pk="id"
|
||
)
|
||
|
||
#Sets Variable users_table as the newly created (or already existing) database
|
||
usersTable = db["users"]
|
||
|
||
|
||
#Checks to see if the User has an ID in the table, if not it gets added, ALSO updates the displayName/discrimnator if they change
|
||
def add_user_to_db(member: discord.Member):
|
||
userID = str(member.id)
|
||
try:
|
||
existing = usersTable.get(userID)
|
||
except KeyError:
|
||
existing = None
|
||
|
||
if not existing:
|
||
# Insert new user
|
||
usersTable.insert(
|
||
{
|
||
"id": userID,
|
||
"name": member.name,
|
||
"discriminator": member.discriminator,
|
||
"displayName": member.display_name,
|
||
"points": 0,
|
||
"title": ""
|
||
},
|
||
pk="id",
|
||
ignore=True
|
||
)
|
||
else:
|
||
# Update if name or discriminator changed
|
||
updated = False
|
||
if existing.get("displayName") != member.display_name:
|
||
existing["displayName"] = member.display_name
|
||
updated = True
|
||
if existing.get("discriminator") != member.discriminator:
|
||
existing["discriminator"] = member.discriminator
|
||
updated = True
|
||
if updated:
|
||
usersTable.update(userID, existing)
|
||
|
||
|
||
|
||
#Import all members from ALL servers
|
||
#@bot.event
|
||
#async def on_ready():
|
||
# print(f"{bot.user.name} is ready")
|
||
|
||
# for guild in bot.guilds:
|
||
# print(f"Importing members from guild: {guild.name} ({guild.id})")
|
||
# async for member in guild.members(limit=None):
|
||
# add_user_to_db(member)
|
||
# print(f"All members have been added/updated in the database.")
|
||
|
||
|
||
#Creates function for bot to use
|
||
def getPoints(userID: int) -> int:
|
||
userID = str(userID)
|
||
try:
|
||
row = usersTable.get(userID)
|
||
return row["points"]
|
||
except KeyError:
|
||
return 0
|
||
|
||
#Bot Command to view points
|
||
@bot.command()
|
||
async def points(ctx, member: discord.Member = None):
|
||
member = member or ctx.author
|
||
total = getPoints(member.id)
|
||
await ctx.send(f"{member.mention} has {total} points.")
|
||
|
||
|
||
|
||
bot.run(token, log_handler=handler, log_level=logging.DEBUG) |