feat(app): first deployment

Author:    Dingo <7553117+DingosGotMyBaby@users.noreply.github.com>
This commit is contained in:
Dingo
2024-07-13 15:29:37 +10:00
commit 431e21ba23
8 changed files with 361 additions and 0 deletions

9
.env.example Normal file
View File

@@ -0,0 +1,9 @@
# Better ways to do all this but I'm lazy
# If you wanna fix it, send a PR in
TOKEN=ashjkfhakjfbajkbfjabfjbanfbahbfbhbb69420
GUILD=1234567890
BANCHANNEL=1234567890
COUNTINGMESSAGE=None # Set after bootstrap
MODLOGS=1234569890
OWNER=1234567890
DEBUG=True # Only checks if the debug has a value, not if it's True

162
.gitignore vendored Normal file
View File

@@ -0,0 +1,162 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

13
Dockerfile Normal file
View File

@@ -0,0 +1,13 @@
FROM python:3.12-slim
RUN apt-get update
RUN apt-get install -y build-essential
RUN pip install --upgrade pip
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
CMD [ "python3", "app.py" ]

13
LICENSE.MD Normal file
View File

@@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

31
README.MD Normal file
View File

@@ -0,0 +1,31 @@
# Discord Ban Bot
This is a Python Discord bot that automatically bans users when they post in a specific channel.
## Prerequisites
Before running the bot, make sure you have the following:
- Python 3.x installed
- Discord.py library installed (`pip install discord.py`)
## Setup
1. Clone this repository to your local machine.
2. Create a new Discord bot on the Discord Developer Portal.
3. Make a copy of `.env.example` and call it `.env`
3. Copy the bot token and paste it in the `.env` file.
4. Customize the `.env` file to specify the target channel ID, message id of the message to edit
5. Run the `app.py` script to start the bot.
## Usage
Once the bot is running, it will monitor the specified channel for new messages. If a user posts in that channel, they will be automatically banned and receive the specified ban message.
## Contributing
Contributions are welcome! If you have any suggestions or improvements, feel free to open an issue or submit a pull request.
## License
This project is licensed under the [MIT License](LICENSE).

114
app.py Normal file
View File

@@ -0,0 +1,114 @@
import discord
from discord import app_commands
import logging
import dotenv
import os
logging.basicConfig(level=logging.DEBUG)
dotenv.load_dotenv()
logging.info("All imported packages and versions: ")
logging.info(f"discord: {discord.__version__}")
MY_GUILD = discord.Object(id=os.environ["GUILD"]) # replace with your guild id
TOKEN = os.environ["TOKEN"]
BAN_CHANNEL = int(os.environ["BANCHANNEL"])
MOD_LOGS = int(os.environ["MODLOGS"])
OWNER = int(os.environ["OWNER"])
COUNTING_MESSAGE = int(os.environ["COUNTINGMESSAGE"]) if os.environ["COUNTINGMESSAGE"] != "None" else None
DEBUG = True if os.environ["DEBUG"] else False
bots = [1078508426923085864, 1176688824508756030]
class MyClient(discord.Client):
def __init__(self, *, intents: discord.Intents):
super().__init__(intents=intents)
self.tree = app_commands.CommandTree(self)
async def setup_hook(self):
# This copies the global commands over to your guild.
await self.tree.sync()
# intents = discord.Intents(messages=True, guilds=True, reactions=True, members=True),
# intents = discord.Intents.default()
# intents.message_content = True
# intents.guilds = True
# intents.members = True
intents = discord.Intents.all()
client = MyClient(intents=intents)
@client.event
async def on_ready():
logging.info(f"Logged in as {client.user} (ID: {client.user.id})")
logging.info(f"Guilds: {len(client.guilds)}")
logging.info(
f"Invite URL: {discord.utils.oauth_url(client.user.id, permissions=discord.Permissions(permissions=139653810176))}"
)
@client.event
async def on_message(message: discord.Message):
if message.author.bot:
return
if message.guild.id == MY_GUILD.id:
if message.channel.id == BAN_CHANNEL:
# get name of channel
channel = client.get_channel(BAN_CHANNEL)
if message.content:
# Here we ban the user cause they posted in the channel :)
if not DEBUG:
# message.author.ban(reason=f"Posted in the {channel.name} channel.")
logging.info(f"{message.author} was banned for posting in {channel.name}.")
else:
await message.channel.send(content=f"{message.author} is a bozo.")
logging.info(f"{message.author} was banned for posting in {channel.name}.")
# Send a message to the mod logs channel
mod_logs = client.get_channel(MOD_LOGS)
await mod_logs.send(
f"{message.author} was banned for posting in {channel.name}."
)
# edit logging message to update the counter
count_message = await message.channel.fetch_message(COUNTING_MESSAGE)
await count_message.edit(
content=f"Total bans from idiots: {int(count_message.content.split()[-1])+1}"
)
else:
return
else:
logging.debug(f"Message from {message.author} in {message.guild.name}({message.guild.id}):{message.channel.name}: {message.content}")
return
# Bootstrap command
@client.tree.command()
# @app_commands.checks.cooldown(1, 600, key=lambda i: (i.guild_id, i.user.id))
@app_commands.describe(channel="The channel you want to have the bans be in")
async def bootstrap(interaction: discord.Interaction, channel: discord.channel.TextChannel):
"""
Bootstraps the bot to the guild
Args:
interaction (discord.Interaction): Discord Interaction
channel (discord.channel.TextChannel): The channel you want the bot to post to
"""
if interaction.guild_id != MY_GUILD.id:
await interaction.response.send_message("You are not in the correct guild.", ephemeral=True)
return
if interaction.user.id != OWNER:
await interaction.response.send_message("You are not authorised to use this command, this has been logged so the bot guy can call you an idiot.", ephemeral=True)
return
if interaction.guild_id == MY_GUILD.id:
message = await channel.send("Total bans from idiots: 0")
await message.pin()
await interaction.response.send_message(f"Bootstrapped the bot. Message ID to set in env is {message.id}", ephemeral=True)
logging.info(f"Bootstrapped the bot. Message ID to set in env is {message.id}")
else:
await interaction.response.send_message("You are not in the correct guild.", ephemeral=True)
client.run(TOKEN)

17
docker-compose.yaml Normal file
View File

@@ -0,0 +1,17 @@
version: "3.9"
services:
bot:
# user: "1000:1000" # Didn't work
build: .
env_file:
- .env
restart: always
# environment:
# - TRANSFORMERS_CACHE=/cache
# - HF_HOME=/cache
# - XDG_CACHE_HOME=/cache
# volumes:
# - cache:/cache
# - ./data:/app/data
# volumes:
# cache:

2
requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
discord.py
python-dotenv