From 7391d0418e5942fb17771daa361283743a3aaf5b Mon Sep 17 00:00:00 2001 From: Sky Date: Wed, 12 Feb 2025 10:03:49 -0600 Subject: [PATCH 1/9] - added docker support (Dockerfile, docker-compose.yaml) - added MongoDB to config to switch between local development and Docker usage - added logs_channel to config --- Dockerfile | 23 +++++++++++++++++++++++ config.py | 2 +- config/main.yml.example | 5 +++++ docker-compose.yaml | 24 ++++++++++++++++++++++++ handlers.py | 2 +- main.py | 14 +++++++++----- 6 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yaml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9ce0b90 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# Use the official Python image from the Docker Hub +FROM python:3.9-slim + +# Set the working directory in the container +WORKDIR /app + +# Copy the requirements file into the container +COPY requirements.txt . + +# Install the dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# Copy the rest of the application code into the container +COPY . . + +# Set environment variables +ENV PYTHONUNBUFFERED=1 + +# Expose the port the app runs on +EXPOSE 8000 + +# Run the application +CMD ["python", "main.py"] \ No newline at end of file diff --git a/config.py b/config.py index 6642e9b..b74faf1 100644 --- a/config.py +++ b/config.py @@ -4,7 +4,7 @@ # Third-party libraries import yaml -MAIN_CONFIG = "code/config/main.yml" +MAIN_CONFIG = "config/main.yml" # Load config files with open(MAIN_CONFIG) as file: diff --git a/config/main.yml.example b/config/main.yml.example index 06f03d2..3944d31 100644 --- a/config/main.yml.example +++ b/config/main.yml.example @@ -1,6 +1,7 @@ discord: token: "discord-bot-token" role_channel: "role-channel" + logs_channel: 123456789012345678 sauce_channels: # Channels ids where source providing should work - 123456789012345678 - 234567890123456789 @@ -8,6 +9,10 @@ discord: - 345678901234567890 - 456789012345678901 +mongodb: + uri: "mongodb://mongodb:27017/" # use mongodb://127.0.0.1/sourcebot for local development, leave alone for docker + db: "sourcebot" + telegram: token: "-" diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..727efc6 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,24 @@ + +services: + sourcebot: + build: . + container_name: sourcebot + environment: + - PYTHONUNBUFFERED=1 + volumes: + - .:/app + ports: + - "8000:8000" + depends_on: + - mongodb + + mongodb: + image: mongo:4.4 + container_name: mongodb + ports: + - "27017:27017" + volumes: + - mongo_data:/data/db + +volumes: + mongo_data: \ No newline at end of file diff --git a/handlers.py b/handlers.py index 3641e38..822d638 100644 --- a/handlers.py +++ b/handlers.py @@ -424,7 +424,7 @@ async def tiktok(**kwargs): tiktok_id = url.split('/')[-1] # Prepare mongodb connection - client = MongoClient("mongodb://127.0.0.1/sourcebot") + client = MongoClient(config['mongodb']['uri']) cached_data = client['sourcebot']['tiktok_db'].find_one({ 'tiktok_id': int(tiktok_id) }) diff --git a/main.py b/main.py index c6b4be1..4e09e11 100755 --- a/main.py +++ b/main.py @@ -60,7 +60,7 @@ async def handle_reaction(payload): return # Search for role in mongodb - client = MongoClient('mongodb://127.0.0.1/sourcebot') + client = MongoClient(config['mongodb']['uri']) result = client['sourcebot']['roles'].find_one({ 'guild': payload.guild_id, 'emoji': emoji @@ -110,6 +110,10 @@ async def on_message(message: discord.Message): ''' Events for each message (main functionality of the bot) ''' + + # Optional logging - DEBUG USE ONLY + #print(f"(Diagnostic) Message from {message.author}: {message.content}") + if message.author == bot.user: return @@ -211,7 +215,7 @@ async def _tiktok(ctx): ''' Posts a random tiktok from sourcebot's collection. ''' - client = MongoClient('mongodb://127.0.0.1/sourcebot') + client = MongoClient(config['mongodb']['uri']) tiktok = client['sourcebot']['tiktok_db'].aggregate([{ "$sample": { "size": 1 } }]).next() await ctx.respond(f"{config['media']['url']}/tiktok-{tiktok['tiktok_id']}.mp4") @@ -268,7 +272,7 @@ async def _list(ctx): Returns current list of roles configured for sourcebot. ''' embed = discord.Embed(title="Current settings", colour=discord.Colour(0x8ba089)) - client = MongoClient('mongodb://127.0.0.1/sourcebot') + client = MongoClient(config['mongodb']['uri']) for role in client['sourcebot']['roles'].find({'guild': ctx.guild.id}): embed.add_field(name=role['emoji'], value=f"<@&{role['role']}>") await ctx.respond(embed=embed) @@ -279,7 +283,7 @@ async def _add(ctx, emoji: str, *, role: discord.Role): ''' Adds a new role reaction to the sourcebot. ''' - client = MongoClient('mongodb://127.0.0.1/sourcebot') + client = MongoClient(config['mongodb']['uri']) client['sourcebot']['roles'].insert_one({ 'guild': ctx.guild.id, 'emoji': emoji, @@ -293,7 +297,7 @@ async def _remove(ctx, emoji: str): ''' Removes a role reaction from sourcebot list. ''' - client = MongoClient('mongodb://127.0.0.1/sourcebot') + client = MongoClient(config['mongodb']['uri']) client['sourcebot']['roles'].delete_one({ 'guild': ctx.guild.id, 'emoji': emoji From 305c80b87a06543166ba478b6519d5450c6fde9d Mon Sep 17 00:00:00 2001 From: Sky Date: Wed, 12 Feb 2025 12:19:30 -0600 Subject: [PATCH 2/9] add nginx, lets encrypt, cloudflare dns challenge support --- .gitignore | 14 ++++++- Dockerfile | 6 ++- docker-compose.yaml | 24 ++++++++++- main.py | 3 +- nginx-certbot.env.example | 17 ++++++++ nginx.conf.example | 62 ++++++++++++++++++++++++++++ nginx_secrets/cloudflare.ini.example | 2 + 7 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 nginx-certbot.env.example create mode 100644 nginx.conf.example create mode 100644 nginx_secrets/cloudflare.ini.example diff --git a/.gitignore b/.gitignore index cf286ec..6e266e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,20 @@ # Ignore configuration files /config/*.yml /config/*.secret +/user_conf.d/*.conf +/nginx_secrets/*.ini +/nginx_secrets/accounts/ +/nginx_secrets/archive/ +/nginx_secrets/live/ +/nginx_secrets/renewal/ +/nginx_secrets/renewal-hooks/ +*.env +/.venv/ # Ignore logs *.log # Python specific -__pycache__ \ No newline at end of file +__pycache__ + +# Ignore media files +/media/* \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 9ce0b90..29069e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,9 @@ # Use the official Python image from the Docker Hub FROM python:3.9-slim +# Install ffmpeg +RUN apt-get update && apt-get install -y ffmpeg && rm -rf /var/lib/apt/lists/* + # Set the working directory in the container WORKDIR /app @@ -20,4 +23,5 @@ ENV PYTHONUNBUFFERED=1 EXPOSE 8000 # Run the application -CMD ["python", "main.py"] \ No newline at end of file +CMD ["python", "main.py"] + diff --git a/docker-compose.yaml b/docker-compose.yaml index 727efc6..7686bdb 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,4 +1,3 @@ - services: sourcebot: build: . @@ -7,6 +6,7 @@ services: - PYTHONUNBUFFERED=1 volumes: - .:/app + - media:/media ports: - "8000:8000" depends_on: @@ -20,5 +20,25 @@ services: volumes: - mongo_data:/data/db + nginx: + image: jonasal/nginx-certbot:latest + container_name: nginx + environment: + - CERTBOT_EMAIL + env_file: + - ./nginx-certbot.env + volumes: + - ./media:/media + - ./nginx_secrets:/etc/letsencrypt # Docker managed volume (see list at the bottom) + - ./user_conf.d:/etc/nginx/user_conf.d # or a host mount with a relative or full path. + ports: + - 80:80 + - 443:443 + depends_on: + - sourcebot + + volumes: - mongo_data: \ No newline at end of file + mongo_data: + media: + nginx_secrets: \ No newline at end of file diff --git a/main.py b/main.py index 1a4c08b..a0fab46 100755 --- a/main.py +++ b/main.py @@ -109,8 +109,7 @@ async def on_message(message: discord.Message): ''' Events for each message (main functionality of the bot) ''' - - # Optional logging - DEBUG USE ONLY + # Optional logging - DEBUG USE ONLY, not recommended for production #print(f"(Diagnostic) Message from {message.author}: {message.content}") if message.author == bot.user: diff --git a/nginx-certbot.env.example b/nginx-certbot.env.example new file mode 100644 index 0000000..51aecf4 --- /dev/null +++ b/nginx-certbot.env.example @@ -0,0 +1,17 @@ +# Required +CERTBOT_EMAIL=your@email.org + +# Optional (Defaults) +DHPARAM_SIZE=2048 +ELLIPTIC_CURVE=secp256r1 +RENEWAL_INTERVAL=8d +RSA_KEY_SIZE=2048 +STAGING=0 +USE_ECDSA=1 + +# Advanced (Defaults) +# Ideally use dns-cloudflare (or other DNS provider) instead of webroot +CERTBOT_AUTHENTICATOR=webroot +CERTBOT_DNS_PROPAGATION_SECONDS="" +DEBUG=0 +USE_LOCAL_CA=0 \ No newline at end of file diff --git a/nginx.conf.example b/nginx.conf.example new file mode 100644 index 0000000..ba128ea --- /dev/null +++ b/nginx.conf.example @@ -0,0 +1,62 @@ + +server { + server_name STATIC.EXAMPLE.COM; + listen 443 ssl; + listen [::]:443 ssl ipv6only=on; + + if ($scheme != "https") { + return 301 https://$host$request_uri; + } + + # Cloudflare IPv4 https://www.cloudflare.com/ips-v4/ + + set_real_ip_from 173.245.48.0/20; + set_real_ip_from 103.21.244.0/22; + set_real_ip_from 103.22.200.0/22; + set_real_ip_from 103.31.4.0/22; + set_real_ip_from 141.101.64.0/18; + set_real_ip_from 108.162.192.0/18; + set_real_ip_from 190.93.240.0/20; + set_real_ip_from 188.114.96.0/20; + set_real_ip_from 197.234.240.0/22; + set_real_ip_from 198.41.128.0/17; + set_real_ip_from 162.158.0.0/15; + set_real_ip_from 104.16.0.0/13; + set_real_ip_from 104.24.0.0/14; + set_real_ip_from 172.64.0.0/13; + set_real_ip_from 131.0.72.0/22; + + # Cloudflare IPv6 https://www.cloudflare.com/ips-v6/ + set_real_ip_from 2400:cb00::/32; + set_real_ip_from 2606:4700::/32; + set_real_ip_from 2803:f800::/32; + set_real_ip_from 2405:b500::/32; + set_real_ip_from 2405:8100::/32; + set_real_ip_from 2a06:98c0::/29; + set_real_ip_from 2c0f:f248::/32; + + real_ip_header CF-Connecting-IP; + + index index.html; + root /media; + + location /vr { + auth_basic "restricted"; + auth_basic_user_file "/etc/nginx/.htpasswd"; + autoindex on; + autoindex_exact_size off; + } + + + ssl_certificate /etc/letsencrypt/live/STATIC.EXAMPLE.COM/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/STATIC.EXAMPLE.COM/privkey.pem; + + access_log /var/log/nginx/STATIC.EXAMPLE.COM.log cf_custom; + +} + +server { + # Drop any request that does not match any of the other server names. + listen 443 ssl default_server; + ssl_reject_handshake on; +} \ No newline at end of file diff --git a/nginx_secrets/cloudflare.ini.example b/nginx_secrets/cloudflare.ini.example new file mode 100644 index 0000000..5d1bef2 --- /dev/null +++ b/nginx_secrets/cloudflare.ini.example @@ -0,0 +1,2 @@ +# Cloudflare API token used by Certbot +dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567 \ No newline at end of file From 7c30b4d0a7042e3c9779472c989df2196f945a4a Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 13 Feb 2025 19:43:06 -0600 Subject: [PATCH 3/9] restructured docker compose, corrections in handling of let's encrypt data --- .gitignore | 9 +---- Dockerfile | 3 +- README.md | 39 ++++++++++++++++++- docker-compose.yaml | 14 +++---- nginx.conf.example | 22 +++++------ .../nginx_secrets}/cloudflare.ini.example | 0 6 files changed, 59 insertions(+), 28 deletions(-) rename {nginx_secrets => nginx/nginx_secrets}/cloudflare.ini.example (100%) diff --git a/.gitignore b/.gitignore index 6e266e2..2d80b2c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,8 @@ # Ignore configuration files /config/*.yml /config/*.secret -/user_conf.d/*.conf -/nginx_secrets/*.ini -/nginx_secrets/accounts/ -/nginx_secrets/archive/ -/nginx_secrets/live/ -/nginx_secrets/renewal/ -/nginx_secrets/renewal-hooks/ +/nginx/user_conf.d/*.conf +/nginx/nginx_secrets/*.ini *.env /.venv/ diff --git a/Dockerfile b/Dockerfile index 29069e3..635aaeb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,5 +23,4 @@ ENV PYTHONUNBUFFERED=1 EXPOSE 8000 # Run the application -CMD ["python", "main.py"] - +CMD ["python", "main.py"] \ No newline at end of file diff --git a/README.md b/README.md index a395172..25aa0c4 100644 --- a/README.md +++ b/README.md @@ -15,4 +15,41 @@ Mongodb: ``` use sourcebot db.tiktok_db.createIndex( { "tiktok_id": 1 }, { unique: true } ) -``` \ No newline at end of file +``` + +# Local Configuration + +Set variables in `config/main.yml` + +Required env variables: +``` +discord: + token: + role_channel: + logs_channel: + sauce_channels; + money_guilds: + +mongodb: + uri: + db: +``` + +# Docker Instructions + +You must configure the following files for Docker: + +- `config/main.yml` + - Bot configuration + - See `config/main.yaml.example` +- `user_conf.d/nginx.conf` + - NGINX configuration for GIF/Media conversion hosting + - See, rename & copy `nginx.conf.example` into the `user_conf.d` folder + - Change all instances of `STATIC.EXAMPLE.COM` to your desired hostname +- `nginx-certbot.env` + - Let's Encrypt configuration + - See `nginx-certbot.env.example` +- `nginx/nginx_secrets/cloudflare.ini` + - Optional for Cloudflare DNS Let's Encrypt challenge + - This can be subbed for other DNS API challenges + - Can also be removed if you want to use default web challenge (godspeed) \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 7686bdb..39ae2a9 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -21,18 +21,16 @@ services: - mongo_data:/data/db nginx: - image: jonasal/nginx-certbot:latest + build: ./nginx container_name: nginx - environment: - - CERTBOT_EMAIL env_file: - ./nginx-certbot.env volumes: - ./media:/media - - ./nginx_secrets:/etc/letsencrypt # Docker managed volume (see list at the bottom) - - ./user_conf.d:/etc/nginx/user_conf.d # or a host mount with a relative or full path. + - nginx_secrets:/etc/letsencrypt # Docker managed volume (see list at the bottom) + - ./nginx/nginx_secrets/cloudflare.ini:/etc/letsencrypt/cloudflare.ini # Optional DNS INI file, remove if not needed + - ./user_conf.d:/etc/nginx/user_conf.d # or a host mount with a relative or full path. ports: - - 80:80 - 443:443 depends_on: - sourcebot @@ -41,4 +39,6 @@ services: volumes: mongo_data: media: - nginx_secrets: \ No newline at end of file + nginx_secrets: + user_conf.d: + \ No newline at end of file diff --git a/nginx.conf.example b/nginx.conf.example index ba128ea..d377a46 100644 --- a/nginx.conf.example +++ b/nginx.conf.example @@ -40,23 +40,23 @@ server { index index.html; root /media; - location /vr { - auth_basic "restricted"; - auth_basic_user_file "/etc/nginx/.htpasswd"; - autoindex on; - autoindex_exact_size off; - } + #location /vr { + # auth_basic "restricted"; + # auth_basic_user_file "/etc/nginx/.htpasswd"; + # autoindex on; + # autoindex_exact_size off; + #} ssl_certificate /etc/letsencrypt/live/STATIC.EXAMPLE.COM/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/STATIC.EXAMPLE.COM/privkey.pem; - access_log /var/log/nginx/STATIC.EXAMPLE.COM.log cf_custom; + # access_log /var/log/nginx/STATIC.EXAMPLE.COM cf_custom; } -server { +#server { # Drop any request that does not match any of the other server names. - listen 443 ssl default_server; - ssl_reject_handshake on; -} \ No newline at end of file +# listen 443 ssl default_server; +# ssl_reject_handshake on; +#} \ No newline at end of file diff --git a/nginx_secrets/cloudflare.ini.example b/nginx/nginx_secrets/cloudflare.ini.example similarity index 100% rename from nginx_secrets/cloudflare.ini.example rename to nginx/nginx_secrets/cloudflare.ini.example From ea4b8a39481bfa99567f832765c7f8d6aea0d0c9 Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 13 Feb 2025 19:49:06 -0600 Subject: [PATCH 4/9] added Dockerfile for nginx-certbot-docker --- nginx/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 nginx/Dockerfile diff --git a/nginx/Dockerfile b/nginx/Dockerfile new file mode 100644 index 0000000..f737e3d --- /dev/null +++ b/nginx/Dockerfile @@ -0,0 +1,2 @@ +FROM jonasal/nginx-certbot:latest +COPY nginx/user_conf.d/* /etc/nginx/conf.d/ \ No newline at end of file From 24650a57c0bfc54af823d8c8d517dc6d2004c9b9 Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 13 Feb 2025 19:55:40 -0600 Subject: [PATCH 5/9] fixed docker-compose, eliminated need for second Dockerfile (whoops, we did not actually need that....) --- docker-compose.yaml | 4 ++-- nginx/Dockerfile | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 nginx/Dockerfile diff --git a/docker-compose.yaml b/docker-compose.yaml index 39ae2a9..7b852ff 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -21,7 +21,7 @@ services: - mongo_data:/data/db nginx: - build: ./nginx + image: jonasal/nginx-certbot:latest container_name: nginx env_file: - ./nginx-certbot.env @@ -29,7 +29,7 @@ services: - ./media:/media - nginx_secrets:/etc/letsencrypt # Docker managed volume (see list at the bottom) - ./nginx/nginx_secrets/cloudflare.ini:/etc/letsencrypt/cloudflare.ini # Optional DNS INI file, remove if not needed - - ./user_conf.d:/etc/nginx/user_conf.d # or a host mount with a relative or full path. + - ./nginx/user_conf.d:/etc/nginx/user_conf.d # or a host mount with a relative or full path. ports: - 443:443 depends_on: diff --git a/nginx/Dockerfile b/nginx/Dockerfile deleted file mode 100644 index f737e3d..0000000 --- a/nginx/Dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -FROM jonasal/nginx-certbot:latest -COPY nginx/user_conf.d/* /etc/nginx/conf.d/ \ No newline at end of file From 972b0ac618b1be0624134e4e48be823ff5198aec Mon Sep 17 00:00:00 2001 From: Sky Date: Sun, 9 Mar 2025 10:40:41 -0500 Subject: [PATCH 6/9] upgraded python to 3.11-slim --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 635aaeb..5e97ba7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Use the official Python image from the Docker Hub -FROM python:3.9-slim +FROM python:3.11-slim # Install ffmpeg RUN apt-get update && apt-get install -y ffmpeg && rm -rf /var/lib/apt/lists/* From 07af0aa6f105d95785b4ca29dfb23fc2d07884ee Mon Sep 17 00:00:00 2001 From: Sky Date: Sun, 9 Mar 2025 10:40:52 -0500 Subject: [PATCH 7/9] added docker compose watch functionality --- docker-compose.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docker-compose.yaml b/docker-compose.yaml index 7b852ff..482413a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -11,6 +11,16 @@ services: - "8000:8000" depends_on: - mongodb + develop: + watch: + - action: rebuild + path: . + ignore: + - "*.pyc" + - "__pycache__/" + - ".git/" + - "media/" + - "*.md" mongodb: image: mongo:4.4 From 0804be3f259c51b01b2ea3402c96f45d0778bc11 Mon Sep 17 00:00:00 2001 From: Sky Date: Sun, 9 Mar 2025 10:41:10 -0500 Subject: [PATCH 8/9] upgraded pysaucenao to 1.6.3 or higher --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b80830e..42157fb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -47,7 +47,7 @@ pydantic==2.9.2 pydantic_core==2.23.4 pymongo==4.8.0 pyparsing==3.1.4 -pysaucenao==1.6.2 +pysaucenao>=1.6.2 PySocks==1.7.1 python-dateutil==2.8.2 python-magic==0.4.27 From 0f82f79400236fe61c15fab4f151fe4c8ddaf869 Mon Sep 17 00:00:00 2001 From: Sky Date: Sun, 9 Mar 2025 10:42:26 -0500 Subject: [PATCH 9/9] added functionality for console debug messaging on link detection and parser detection with config toggle. added ability to enable/disable link embed deletion on source message --- config/main.yml.example | 4 +++ main.py | 54 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/config/main.yml.example b/config/main.yml.example index aa1c7e8..b7d4474 100644 --- a/config/main.yml.example +++ b/config/main.yml.example @@ -8,6 +8,10 @@ discord: money_guilds: - 345678901234567890 - 456789012345678901 + debug: + link_detection: true + handler_detection: true + delete_original_embeds: true mongodb: uri: "mongodb://mongodb:27017/" # use mongodb://127.0.0.1/sourcebot for local development, leave alone for docker diff --git a/main.py b/main.py index a0fab46..92a529b 100755 --- a/main.py +++ b/main.py @@ -28,6 +28,9 @@ # Spoiler regular expression spoiler_regex = re.compile(r"(\|\|.*?\|\||\<.*?\>|\`.*?\`)", re.DOTALL) +# URL detection regular expression +url_regex = re.compile(r'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+[^\s]*') + # Role reactions async def handle_reaction(payload): ''' @@ -118,6 +121,13 @@ async def on_message(message: discord.Message): # Process prefix commands await bot.process_commands(message) + # Debug message for links in messages + if url_regex.search(message.content) and config['discord'].get('debug', {}).get('link_detection', False): + print(f"[DEBUG] Link detected in message from {message.author} (ID: {message.author.id}) in channel {message.channel.name if hasattr(message.channel, 'name') else 'DM'}") + print(f"[DEBUG] Message content: {message.content}") + print(f"[DEBUG] Links found: {[match.group(0) for match in url_regex.finditer(message.content)]}") + print("-" * 50) + # Ignore text in valid spoiler tag content = re.sub(spoiler_regex, '', message.content) @@ -167,10 +177,30 @@ async def on_message(message: discord.Message): ) if isinstance(files, list): - # Debug logs + # Debug logs to console + if config['discord'].get('debug', {}).get('handler_detection', False): + print(f"[DEBUG] Handler successfully processed: {parser['function'].__name__}") + print(f"[DEBUG] Match groups: {match.groups()}") + print(f"[DEBUG] From user: {message.author} in channel: {message.channel.name if hasattr(message.channel, 'name') else 'DM'}") + print("-" * 50) + + # Debug logs to Discord channel logs_channel = bot.get_channel(config['discord']['logs_channel']) await logs_channel.send(f"```\n{message.author=}\n{message.channel=}\n{match.groups()=}\n```") + # Delete original message embeds if configured + if config['discord'].get('delete_original_embeds', False) and not isinstance(message.channel, discord.DMChannel): + try: + await message.edit(suppress=True) + if config['discord'].get('debug', {}).get('handler_detection', False): + print(f"[DEBUG] Deleted embeds from message: {message.id}") + except discord.Forbidden: + if config['discord'].get('debug', {}).get('handler_detection', False): + print(f"[DEBUG] No permission to delete embeds from message: {message.id}") + except Exception as e: + if config['discord'].get('debug', {}).get('handler_detection', False): + print(f"[DEBUG] Error deleting embeds from message: {message.id}, Error: {str(e)}") + for i in range(0, len(files), 10): await message.channel.send(files=[ discord.File(file) for file in files[i:i+10] ]) await logs_channel.send(files=[ discord.File(file) for file in files[i:i+10] ]) @@ -183,11 +213,31 @@ async def on_message(message: discord.Message): ) if isinstance(output, list): - # Debug logs + # Debug logs to console + if config['discord'].get('debug', {}).get('handler_detection', False): + print(f"[DEBUG] Handler successfully processed: {parser['function'].__name__}") + print(f"[DEBUG] Match groups: {match.groups()}") + print(f"[DEBUG] From user: {message.author} in channel: {message.channel.name if hasattr(message.channel, 'name') else 'DM'}") + print("-" * 50) + + # Debug logs to Discord channel logs_channel = bot.get_channel(config['discord']['logs_channel']) if parser['function'] is not handlers.youtube: await logs_channel.send(f"```\n{message.author=}\n{message.channel=}\n{match.groups()=}\n```") + # Delete original message embeds if configured + if config['discord'].get('delete_original_embeds', False) and not isinstance(message.channel, discord.DMChannel): + try: + await message.edit(suppress=True) + if config['discord'].get('debug', {}).get('handler_detection', False): + print(f"[DEBUG] Deleted embeds from message: {message.id}") + except discord.Forbidden: + if config['discord'].get('debug', {}).get('handler_detection', False): + print(f"[DEBUG] No permission to delete embeds from message: {message.id}") + except Exception as e: + if config['discord'].get('debug', {}).get('handler_detection', False): + print(f"[DEBUG] Error deleting embeds from message: {message.id}, Error: {str(e)}") + for kwargs in output: await message.channel.send(**kwargs) if parser['function'] is not handlers.youtube: