Fix SQL lockups, get commands working, remove DB and availcommands and .env
This commit is contained in:
parent
f50221c672
commit
05074d33be
6
.env
6
.env
|
@ -1,6 +0,0 @@
|
||||||
##EXAMPLE .ENV FILE
|
|
||||||
|
|
||||||
BOT_TOKEN = "INPUT DISCORD API KEY HERE"
|
|
||||||
BOT_CHANNEL_ID = INPUT CHANNEL ID FOR COMMANDS
|
|
||||||
WELCOME_CHANNEL_ID = INPUT CHANNEL ID FOR YOUR WELCOME MESSAGE MAINTENANCE
|
|
||||||
GUILD_ID = INPUT GUILD ID FOR YOUR DISCORD SERVER
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
||||||
/.venv
|
/.venv
|
||||||
member_data.db
|
member_data.db
|
||||||
discord.log
|
discord.log
|
||||||
|
SparkBot.log
|
36
README.md
Normal file
36
README.md
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# SparkBot
|
||||||
|
|
||||||
|
A Discord bot for Spark Studio Salem
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Go to https://discord.com/developers/applications and make an application
|
||||||
|
- Go to the Bot page.
|
||||||
|
- Copy `env.dist` to `.env` and add the Bot Token to this file.
|
||||||
|
- Choose what channels you want the bot to operate in on your server and add their IDs to the file as well.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Requires Python 3.
|
||||||
|
|
||||||
|
- Run `pip install -r requirements.txt`
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
Run `python3 main.py`
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Available Commands
|
||||||
|
|
||||||
|
```
|
||||||
|
/help : to view all commands
|
||||||
|
/nick : to view current nickname
|
||||||
|
/setnick : to change nickname
|
||||||
|
/reinit : to re-initialize a user in the database (i.e. if they joined when the bot wasn't listening)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database
|
||||||
|
|
||||||
|
Initialization of the structure is automatically handled inside `main.py` and
|
||||||
|
creates the SQLITE3 file `member_data.db`.
|
6
env.dist
Normal file
6
env.dist
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
##EXAMPLE .ENV FILE
|
||||||
|
|
||||||
|
BOT_TOKEN = ""INPUT DISCORD API KEY HERE"
|
||||||
|
BOT_CHANNEL_ID = INPUT CHANNEL ID FOR COMMANDS
|
||||||
|
WELCOME_CHANNEL_ID = INPUT WELCOME CHANNEL ID HERE
|
||||||
|
GUILD_ID = INPUT GUILD ID HERE
|
165
main.py
165
main.py
|
@ -7,7 +7,7 @@ import sqlite3
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from discord import ui, Interaction
|
from discord import ui, Interaction
|
||||||
|
import random
|
||||||
|
|
||||||
async def welcome_message():
|
async def welcome_message():
|
||||||
# Find the #welcome channel
|
# Find the #welcome channel
|
||||||
|
@ -37,26 +37,44 @@ async def welcome_message():
|
||||||
|
|
||||||
async def update_nickname(member, firstname, lastname): #update server nickname from DB
|
async def update_nickname(member, firstname, lastname): #update server nickname from DB
|
||||||
nickname = f"{firstname} {lastname}"
|
nickname = f"{firstname} {lastname}"
|
||||||
c.execute("UPDATE members SET nickname = ?, firstname = ?, lastname = ? WHERE user_id = ?", (nickname, firstname, lastname, member.id))
|
with sqlite3.connect('member_data.db') as conn:
|
||||||
conn.commit()
|
c = conn.cursor()
|
||||||
print(f'Updated DB nickname for: {member}, {firstname}, {lastname}, {nickname}')
|
c.execute("UPDATE members SET nickname = ?, firstname = ?, lastname = ? WHERE user_id = ?", (nickname, firstname, lastname, member.id))
|
||||||
|
conn.commit()
|
||||||
|
print(f'Updated DB nickname for: {member}, {firstname}, {lastname}, {nickname}')
|
||||||
await member.edit(nick=nickname)
|
await member.edit(nick=nickname)
|
||||||
|
|
||||||
async def remove_user(user): #Remove user from DB and delete server nickname
|
async def remove_user(user): #Remove user from DB and delete server nickname
|
||||||
c.execute("DELETE FROM members WHERE user_id = ?", (user.id,))
|
with sqlite3.connect('member_data.db') as conn:
|
||||||
conn.commit()
|
c = conn.cursor()
|
||||||
|
c.execute("DELETE FROM members WHERE user_id = ?", (user.id,))
|
||||||
|
conn.commit()
|
||||||
if user:
|
if user:
|
||||||
await user.edit(nick=None)
|
await user.edit(nick=None)
|
||||||
#TODO demote user role
|
#TODO demote user role
|
||||||
|
|
||||||
async def update_onboard(member): #increase onboarding status by 1
|
async def update_onboard(member): #increase onboarding status by 1
|
||||||
print(f'Updating onboarding for: {member.display_name}')
|
logging.info(f'Updating onboarding for: {member.display_name} {member.id}')
|
||||||
c.execute("SELECT onboarding_status FROM members WHERE user_id = ?", (member.id,))
|
|
||||||
status = c.fetchone()
|
# Connect to the database using a context manager
|
||||||
status += 1
|
with sqlite3.connect('member_data.db') as conn:
|
||||||
c.execute("UPDATE members SET onboarding_status = ? WHERE user_id = ?",
|
c = conn.cursor()
|
||||||
(status, member.id))
|
|
||||||
conn.commit()
|
c.execute("SELECT onboarding_status FROM members WHERE user_id = ?", (member.id,))
|
||||||
|
row = c.fetchone()
|
||||||
|
|
||||||
|
if row is None:
|
||||||
|
logging.error("No matching user found in the database.")
|
||||||
|
return
|
||||||
|
|
||||||
|
status = row[0]
|
||||||
|
status += 1
|
||||||
|
|
||||||
|
c.execute("UPDATE members SET onboarding_status = ? WHERE user_id = ?",
|
||||||
|
(status, member.id))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
logging.warning(f'Updated onboarding for {member.display_name}: {status}')
|
||||||
|
|
||||||
async def add_member_to_role(member, role_name):
|
async def add_member_to_role(member, role_name):
|
||||||
print(f"Adding {role_name} role to {member.display_name}")
|
print(f"Adding {role_name} role to {member.display_name}")
|
||||||
|
@ -77,25 +95,26 @@ logging.basicConfig(filename='SparkBot.log', level=logging.INFO)
|
||||||
intents = discord.Intents.all()
|
intents = discord.Intents.all()
|
||||||
|
|
||||||
# Connect to SQLite database
|
# Connect to SQLite database
|
||||||
conn = sqlite3.connect('member_data.db')
|
with sqlite3.connect('member_data.db') as conn:
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
|
|
||||||
# Create table with fields if it doesn't exist already
|
# Create table with fields if it doesn't exist already
|
||||||
c.execute('''CREATE TABLE IF NOT EXISTS members (
|
c.execute('''CREATE TABLE IF NOT EXISTS members (
|
||||||
user_id INTEGER PRIMARY KEY,
|
user_id INTEGER PRIMARY KEY,
|
||||||
username TEXT, nickname TEXT,
|
username TEXT, nickname TEXT,
|
||||||
firstname TEXT, lastname TEXT,
|
firstname TEXT, lastname TEXT,
|
||||||
join_datetime TEXT,
|
join_datetime TEXT,
|
||||||
onboarding_status INTEGER,
|
onboarding_status INTEGER,
|
||||||
last_change_datetime TEXT
|
last_change_datetime TEXT
|
||||||
)''')
|
)''')
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
class PersistentViewBot(commands.Bot):
|
class PersistentViewBot(commands.Bot):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
intents = discord.Intents().all()
|
intents = discord.Intents().all()
|
||||||
super().__init__(command_prefix=commands.when_mentioned_or("."), intents=intents)
|
super().__init__(command_prefix=commands.when_mentioned_or("/"), intents=intents)
|
||||||
async def setup_hook(self) -> None:
|
async def setup_hook(self) -> None:
|
||||||
self.add_view(OnboardButtons())
|
self.add_view(OnboardButtons())
|
||||||
#self.add_view(OnboardButtons()) #Add More views with more add_view commands.
|
#self.add_view(OnboardButtons()) #Add More views with more add_view commands.
|
||||||
|
@ -151,26 +170,92 @@ async def on_ready():
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
|
print("Members in the DB:")
|
||||||
|
|
||||||
|
with sqlite3.connect('member_data.db') as conn:
|
||||||
|
c = conn.cursor()
|
||||||
|
|
||||||
|
c.execute("SELECT user_id, username, nickname FROM members")
|
||||||
|
for row in c.fetchall():
|
||||||
|
print(f' ID: {row[0]} User: {row[1]} Nick: {row[2]}')
|
||||||
|
|
||||||
|
print("Ready.")
|
||||||
|
|
||||||
|
@client.command(name='reinit')
|
||||||
|
async def cmd_reinit(ctx):
|
||||||
|
"""Re-initialize a user in the database (i.e. if the bot wasn't listening when they joined)"""
|
||||||
|
await on_member_join(ctx.author)
|
||||||
|
await ctx.send("Reinitialized!")
|
||||||
|
|
||||||
|
@client.command(name='nick')
|
||||||
|
async def cmd_nick(ctx):
|
||||||
|
"""View current nickname"""
|
||||||
|
await ctx.send(f'You are {ctx.author.nick}')
|
||||||
|
|
||||||
|
@client.command(name='setnick')
|
||||||
|
async def cmd_setnick(ctx, arg1, arg2):
|
||||||
|
"""Change nickname (use two words separated by a space)"""
|
||||||
|
await update_nickname(ctx.author, arg1, arg2)
|
||||||
|
await ctx.send(f'You are now {ctx.author.nick}')
|
||||||
|
|
||||||
|
@client.command(name='99')
|
||||||
|
async def cmd_nine_nine(ctx):
|
||||||
|
brooklyn_99_quotes = [
|
||||||
|
'I\'m the human form of the 💯 emoji.',
|
||||||
|
'Bingpot!',
|
||||||
|
(
|
||||||
|
'Cool. Cool cool cool cool cool cool cool, '
|
||||||
|
'no doubt no doubt no doubt no doubt.'
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
response = random.choice(brooklyn_99_quotes)
|
||||||
|
await ctx.send(response)
|
||||||
|
|
||||||
|
# @client.event
|
||||||
|
# async def on_message(message):
|
||||||
|
# if message.author == client.user:
|
||||||
|
# return
|
||||||
|
|
||||||
|
# brooklyn_99_quotes = [
|
||||||
|
# 'I\'m the human form of the 💯 emoji.',
|
||||||
|
# 'Bingpot!',
|
||||||
|
# (
|
||||||
|
# 'Cool. Cool cool cool cool cool cool cool, '
|
||||||
|
# 'no doubt no doubt no doubt no doubt.'
|
||||||
|
# ),
|
||||||
|
# ]
|
||||||
|
|
||||||
|
# if message.content == '/99':
|
||||||
|
# response = random.choice(brooklyn_99_quotes)
|
||||||
|
# await message.channel.send(response)
|
||||||
|
|
||||||
@client.event
|
@client.event
|
||||||
async def on_member_join(member):
|
async def on_member_join(member):
|
||||||
await welcome_message()
|
await welcome_message()
|
||||||
# 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
|
with sqlite3.connect('member_data.db') as conn:
|
||||||
# Add new member to the database
|
c = conn.cursor()
|
||||||
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()))
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
# Update member nickname
|
# Check if member already exists in the database
|
||||||
await member.edit(nick=c.execute("SELECT nickname FROM members WHERE user_id = ?", (member.id,)).fetchone()[0])
|
c.execute("SELECT * FROM members WHERE user_id = ?", (member.id,))
|
||||||
|
|
||||||
# Log member join
|
existing_member = c.fetchone()
|
||||||
logging.info(f'Member {member.name} joined the server.')
|
|
||||||
|
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()))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
# Update member nickname
|
||||||
|
await member.edit(nick=c.execute("SELECT nickname FROM members WHERE user_id = ?", (member.id,)).fetchone()[0])
|
||||||
|
|
||||||
|
# Log member join
|
||||||
|
logging.warning(f'Member {member.name} joined the server.')
|
||||||
|
else:
|
||||||
|
logging.info(f'Member {member.name} rejoined the server.')
|
||||||
|
|
||||||
@client.tree.command(name="remove", description="Remove user from database, and remove user's nickname")
|
@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")
|
@app_commands.describe(member="The member you want to remove")
|
||||||
|
@ -181,7 +266,7 @@ async def remove(interaction: discord.Integration, member: discord.Member):
|
||||||
@client.event
|
@client.event
|
||||||
async def on_member_remove(member):
|
async def on_member_remove(member):
|
||||||
# Log member leave
|
# Log member leave
|
||||||
logging.info(f'Member {member.name} left the server.')
|
logging.warning(f'Member {member.name} left the server.')
|
||||||
|
|
||||||
|
|
||||||
# Load bot token and welcome channel id from .env file
|
# Load bot token and welcome channel id from .env file
|
||||||
|
|
|
@ -10,6 +10,5 @@ discord==2.3.2
|
||||||
discord.py==2.3.2
|
discord.py==2.3.2
|
||||||
frozenlist==1.4.1
|
frozenlist==1.4.1
|
||||||
idna==3.6
|
idna==3.6
|
||||||
logging==0.4.9.6
|
|
||||||
multidict==6.0.5
|
multidict==6.0.5
|
||||||
yarl==1.9.4
|
yarl==1.9.4
|
||||||
|
|
Loading…
Reference in New Issue
Block a user