From 063b68fdc12a13bbc1445c919d569dd7fdde9c86 Mon Sep 17 00:00:00 2001 From: Shiven Ajwaliya Date: Sat, 30 May 2026 16:00:48 +1000 Subject: [PATCH 01/32] 279-Bug fix quest progress counting in restricted channels --- features/quests.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/features/quests.py b/features/quests.py index dc467a0..dd27883 100644 --- a/features/quests.py +++ b/features/quests.py @@ -2,6 +2,9 @@ from discord import app_commands from discord.ext import commands +# Import Config +from features.config import BOTS_CATEGORY_ID, PASSIVE_REWARD_EXCLUDED_CHANNEL_IDS + # Import Database Helpers from database.mongo import ( init_default_quests, @@ -115,6 +118,13 @@ async def process_quest_update(self, user_id, channel, action_type="message"): async def on_message(self, message: discord.Message): if message.author.bot: return + + # Skip quest progress in restricted channels (same rules as token earning) + if message.channel.category and message.channel.category.id == BOTS_CATEGORY_ID: + return + if message.channel.id in PASSIVE_REWARD_EXCLUDED_CHANNEL_IDS: + return + # Trigger message quest updates await self.process_quest_update( str(message.author.id), message.channel, "message" From 0e1a15af9096afbcb3b7d4b1fee6ee2188d6fec5 Mon Sep 17 00:00:00 2001 From: Shiven Ajwaliya Date: Sat, 30 May 2026 16:13:19 +1000 Subject: [PATCH 02/32] 285-Enhancement add budget reset date to check-budget command embed --- features/economy.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/features/economy.py b/features/economy.py index d83e1d7..89e39b7 100644 --- a/features/economy.py +++ b/features/economy.py @@ -2,7 +2,7 @@ import discord from discord import app_commands from discord.ext import commands, tasks -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone import random from typing import Optional import asyncio @@ -1175,11 +1175,19 @@ async def check_budget(self, interaction: discord.Interaction): int(await get_setting("nitro_redeemed_count", "0")) int(await get_setting("pin_redeemed_count", "0")) + now = datetime.now(timezone.utc) + if now.month == 12: + reset_date = datetime(now.year + 1, 1, 1, tzinfo=timezone.utc) + else: + reset_date = datetime(now.year, now.month + 1, 1, tzinfo=timezone.utc) + reset_timestamp = int(reset_date.timestamp()) + embed = discord.Embed(title="šŸ’° **Budget Status**", color=discord.Color.blue()) embed.description = ( f"**Total Monthly Budget:** ${total_budget:.2f}\n" f"**Total Spent on Redemptions:** ${total_spent:.2f}\n" - f"**Remaining Budget:** ${remaining:.2f}" + f"**Remaining Budget:** ${remaining:.2f}\n" + f"**Budget Resets:** ()" ) await interaction.response.send_message(embed=embed, ephemeral=True) From 1d687a873b21472173468c25f368be677e2d2c4b Mon Sep 17 00:00:00 2001 From: Shiven Ajwaliya Date: Sat, 30 May 2026 19:48:28 +1000 Subject: [PATCH 03/32] 277-Feature add /version slash command with embed display --- features/general.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/general.py b/features/general.py index 1b52347..57050a0 100644 --- a/features/general.py +++ b/features/general.py @@ -194,6 +194,14 @@ async def admin_help(self, interaction: discord.Interaction): "BRT": "America/Sao_Paulo", } + @app_commands.command(name="version", description="View the bot's current version.") + async def version(self, interaction: discord.Interaction): + embed = discord.Embed( + description=f"šŸ¤– R7 Bot is running\n# {BOT_VERSION}", + color=discord.Color.blurple(), + ) + await interaction.response.send_message(embed=embed) + @app_commands.command( name="convert-time", description="Convert a date and time to all Discord timestamp formats.", From 62b8acea2fbcc01225fde2d63409d00993d77a90 Mon Sep 17 00:00:00 2001 From: Shiven Ajwaliya Date: Sat, 30 May 2026 19:54:31 +1000 Subject: [PATCH 04/32] 278-Enhancement restrict !starttourney and !endtourney to tourney admin channel --- features/tourney/tourney_commands.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/tourney/tourney_commands.py b/features/tourney/tourney_commands.py index ebfd4f6..2c2fcc1 100644 --- a/features/tourney/tourney_commands.py +++ b/features/tourney/tourney_commands.py @@ -1316,6 +1316,12 @@ async def start_tourney_command(ctx: commands.Context, region: str = None): await ctx.reply("You don't have permission to start the tourney.") return + if ctx.channel.id != TOURNEY_ADMIN_CHANNEL_ID: + await ctx.reply( + f"This command can only be used in <#{TOURNEY_ADMIN_CHANNEL_ID}>." + ) + return + guild = ctx.guild if not guild: return @@ -1549,6 +1555,12 @@ async def end_tourney_command(ctx: commands.Context): await ctx.reply("You don't have permission to end the tourney.") return + if ctx.channel.id != TOURNEY_ADMIN_CHANNEL_ID: + await ctx.reply( + f"This command can only be used in <#{TOURNEY_ADMIN_CHANNEL_ID}>." + ) + return + guild = ctx.guild if guild is None: return From a4d1036c2bd2cef4584941ee384d20e303641ad8 Mon Sep 17 00:00:00 2001 From: Shiven Ajwaliya Date: Sat, 30 May 2026 20:22:41 +1000 Subject: [PATCH 05/32] 265-Enhancement add response time duration to hacked user flag embed --- features/security.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/features/security.py b/features/security.py index f74c215..e9dc065 100644 --- a/features/security.py +++ b/features/security.py @@ -1,7 +1,7 @@ import discord from discord import app_commands from discord.ext import commands -from datetime import timedelta, datetime +from datetime import timedelta, datetime, timezone from math import ceil import asyncio @@ -70,6 +70,7 @@ async def _execute_hacked_action(self, guild, target_user, moderator): cutoff_date = datetime.utcnow() - timedelta(hours=12) total_deleted = 0 channels_checked = 0 + earliest_message_time = None # COMBINE LISTS: Convert all to list() first to avoid SequenceProxy errors all_channels = ( @@ -91,13 +92,29 @@ async def _execute_hacked_action(self, guild, target_user, moderator): ) if len(deleted) > 0: total_deleted += len(deleted) + channel_earliest = min(msg.created_at for msg in deleted) + if ( + earliest_message_time is None + or channel_earliest < earliest_message_time + ): + earliest_message_time = channel_earliest except Exception: pass channels_checked += 1 await asyncio.sleep(0.1) - # 6. Build Result Embed + # 6. Calculate response time + if earliest_message_time is not None: + response_delta = datetime.now(timezone.utc) - earliest_message_time + total_seconds = int(response_delta.total_seconds()) + hours, remainder = divmod(total_seconds, 3600) + minutes = remainder // 60 + response_time_str = f"{hours:02d}:{minutes:02d}" + else: + response_time_str = "N/A (no messages found)" + + # 7. Build Result Embed embed = discord.Embed( title="🚨 User Flagged as Hacked", description=f"**Target:** {target_user.mention} (`{target_user.id}`)\n**Action:** 7-Day Timeout & Message Purge", @@ -109,6 +126,11 @@ async def _execute_hacked_action(self, guild, target_user, moderator): value=f"šŸ—‘ļø Deleted **{total_deleted} messages** across **{channels_checked} channels** (Past 12 hours).", inline=False, ) + embed.add_field( + name="Response Time", + value=f"ā±ļø {response_time_str}", + inline=False, + ) embed.add_field( name="Next Step", value="User added to Hacked Database. Use `/unhacked` when recovered.", From 38292ff165e2344081789d7df9d46639345b2fe4 Mon Sep 17 00:00:00 2001 From: Shiven Ajwaliya Date: Sat, 30 May 2026 20:46:24 +1000 Subject: [PATCH 06/32] 251-Enhancement add moderator identity to hacked command embed --- features/security.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/security.py b/features/security.py index e9dc065..6c4df32 100644 --- a/features/security.py +++ b/features/security.py @@ -117,7 +117,11 @@ async def _execute_hacked_action(self, guild, target_user, moderator): # 7. Build Result Embed embed = discord.Embed( title="🚨 User Flagged as Hacked", - description=f"**Target:** {target_user.mention} (`{target_user.id}`)\n**Action:** 7-Day Timeout & Message Purge", + description=( + f"**Target:** {target_user.mention} (`{target_user.id}`)\n" + f"**Moderator:** {moderator.mention}\n" + f"**Action:** 7-Day Timeout & Message Purge" + ), color=discord.Color.dark_red(), ) embed.add_field(name="Status", value=timeout_status, inline=False) From 9106e1589bca851d455890621c2c2c524f45fc8c Mon Sep 17 00:00:00 2001 From: Shiven Ajwaliya Date: Sun, 31 May 2026 21:55:34 +1000 Subject: [PATCH 07/32] 292-Enhancement update README and help commands with accurate documentation --- README.md | 21 +++++++++++++++++---- features/general.py | 3 ++- features/tourney/tourney_commands.py | 2 ++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4b36a9a..5921e7b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Overview **Name:** Remaining7 Discord Bot -**Version:** v1.7.5 +**Version:** v1.9.2 **Contributors:** remainingdelta, nightwarrior5 **Objective:** A feature-rich Discord bot for the Remaining7 community server (16k+ members). Handles an R7 Token economy, leveling, quests, a Brawl Stars collection minigame, tournament management with Matcherino integration, support tickets, event operations, a security protocol, and multi-language translation. **Server Link:** https://discord.gg/6MzrjS2X8k @@ -15,6 +15,7 @@ - **Database:** MongoDB Atlas via `motor` (async) - **Translation:** `deep-translator` + `langdetect` - **External API:** Matcherino (tournament brackets, payouts) +- **AI Integration:** Gemini API (GitHub issue generation) - **Linting:** Ruff (`ruff check .` / `ruff format .`) --- @@ -23,7 +24,10 @@ ``` Remaining7-Discord-Bot/ ā”œā”€ā”€ main.py # Entry point — loads cogs, syncs commands +ā”œā”€ā”€ pyproject.toml # Project metadata and version ā”œā”€ā”€ requirements.txt +ā”œā”€ā”€ Makefile +ā”œā”€ā”€ LICENSE ā”œā”€ā”€ .env.example ā”œā”€ā”€ .gitignore ā”œā”€ā”€ CLAUDE.md @@ -36,9 +40,10 @@ Remaining7-Discord-Bot/ │ ā”œā”€ā”€ quests.py # Daily & weekly quest system │ ā”œā”€ā”€ security.py # Hacked protocol (timeout, purge, flag) │ ā”œā”€ā”€ event.py # Event channel cleanup & reward payouts -│ ā”œā”€ā”€ general.py # /help, /mod-help, /admin-help, /convert-time +│ ā”œā”€ā”€ general.py # /help, /mod-help, /admin-help, /version, /convert-time │ ā”œā”€ā”€ translation.py # !t prefix & /translate slash command (55 languages) │ ā”œā”€ā”€ support_tickets.py # General support tickets (issues, support, apps, partnership) +│ ā”œā”€ā”€ github_tickets.py # AI-powered GitHub issue creation from tickets (Gemini) │ ā”œā”€ā”€ ticket_command_router.py # Shared routing for tourney & support ticket commands │ ā”œā”€ā”€ brawl/ │ │ ā”œā”€ā”€ brawlers.json # Brawler data (name, rarity, gadgets, star powers, hypercharges) @@ -64,7 +69,7 @@ Remaining7-Discord-Bot/ ## Core Features ### R7 Token Economy -- **Passive Income:** Users earn 2–5 R7 Tokens per message (20-second cooldown). Server Boosters get a 2% average bonus. +- **Passive Income:** Users earn 2–5 R7 Tokens per message (20-second cooldown). Server Boosters get a 5% increase in tokens on average. - **Daily Rewards:** `/daily` grants 80–160 tokens (scaled by level). Requires 5 messages sent since last claim and a 24-hour cooldown. - **Supply Drop:** `/drop ` (Admin) to force a token drop in general chat. - **Balance & Ranking:** `/balance [user]`, `/leaderboard [page]`. @@ -150,6 +155,11 @@ Remaining7-Discord-Bot/ - Staff can close, reopen, and delete tickets with transcript generation. - Transcripts DM'd to the opener and archived in a log channel. +### GitHub Ticket Integration +- AI-powered GitHub issue creation from support tickets using Gemini. +- Automatically generates structured bug reports, feature requests, and enhancement issues from ticket conversations. +- Requires `GEMINI_TOKEN` and `GITHUB_TOKEN` environment variables. + ### Event Management - **Automated Monitoring:** Daily background task at 12:00 AM ET scans event channels. - **Smart Alerts:** Alert sent when messages are 7+ days old (prevents exceeding Discord's 14-day bulk-delete limit). @@ -170,6 +180,7 @@ Remaining7-Discord-Bot/ ### Utility - `/convert-time