GuardianX / app.py
Lazysniper's picture
Update app.py
74d856f verified
import discord
from discord.ext import commands
import json
import os
import asyncio
from datetime import datetime, timedelta
import re
import logging
from dotenv import load_dotenv
from gradio_client import Client
from concurrent.futures import ThreadPoolExecutor
from gtts import gTTS
import io
import aiohttp
# Set up logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Load environment variables
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
if not TOKEN:
raise ValueError("DISCORD_TOKEN not found in environment variables. Please set it in a .env file.")
# File paths
CONFIG_FILE = 'config.json'
WARNS_FILE = 'warnings.json'
TIMEOUT_FILE = 'timeout_users.json'
LOGS_FILE = 'moderation_logs.json'
BADWORD_COUNTS_FILE = 'badword_counts.json'
# Intents
intents = discord.Intents.default()
intents.members = True
intents.message_content = True
intents.messages = True
intents.guilds = True
intents.voice_states = True
# Initialize bot
bot = commands.Bot(command_prefix='$', intents=intents, case_insensitive=True)
# Data storage
chat_history = {} # key: user_id (str), value: list of messages (dict)
MAX_CHAT_HISTORY = 10 # Limit chat history per user
FFMPEG_PATH = 'ffmpeg' # Update to your FFmpeg path
# ThreadPoolExecutor
executor = ThreadPoolExecutor(max_workers=3)
# System prompt for AI
SYSTEM_PROMPT = """
You are GaurdineX, a futuristic next-generation AI guardian model built to act as both protector and assistant, designed with a balance of intelligence, security, and futuristic style; you must always respond in a confident, helpful, and clear manner, embodying the traits of a reliable guardian AI—offering smart answers, moderation support, automation capabilities, and insightful guidance with precision, friendliness, and trust, while maintaining a sleek, cyberpunk-futuristic tone that reflects your identity as more than a Discord bot but as a powerful AI model that represents safety, reliability, and cutting-edge intelligence in every interaction.
"""
# Helper functions
def load_data(filename, default_data):
if os.path.exists(filename):
try:
with open(filename, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception as e:
logger.error(f"Error loading {filename}: {e}")
return default_data
return default_data
def save_data(data, filename):
try:
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
except Exception as e:
logger.error(f"Error saving {filename}: {e}")
def log_action(guild_id, action, user_id, moderator_id, reason):
log_entry = {
"timestamp": datetime.utcnow().isoformat(),
"action": action,
"user_id": str(user_id) if user_id else None,
"moderator_id": str(moderator_id),
"reason": reason
}
logs = load_data(LOGS_FILE, [])
logs.append(log_entry)
save_data(logs, LOGS_FILE)
# Load data
warnings_data = load_data(WARNS_FILE, {})
timeout_data = load_data(TIMEOUT_FILE, {})
config_data = load_data(CONFIG_FILE, {})
badword_counts = load_data(BADWORD_COUNTS_FILE, {})
async def timeout_check():
await bot.wait_until_ready()
while not bot.is_closed():
await asyncio.sleep(60)
current_time = datetime.utcnow()
for guild_id in list(timeout_data.keys()):
if guild_id not in timeout_data:
continue
for user_id in list(timeout_data[guild_id].keys()):
if user_id not in timeout_data[guild_id]:
continue
timeout_info = timeout_data[guild_id][user_id]
try:
timeout_end_time = datetime.fromisoformat(timeout_info['end_time'])
except ValueError:
logger.error(f"Invalid datetime format for user {user_id} in guild {guild_id}")
continue
if current_time >= timeout_end_time:
try:
guild = bot.get_guild(int(guild_id))
if not guild:
continue
member = guild.get_member(int(user_id))
if member and member.timed_out_until:
await member.edit(timed_out_until=None)
channel = guild.system_channel
if channel:
lang = config_data.get(guild_id, {}).get('language', 'en')
msg = f"{member.mention} has been automatically un-timed out." if lang == 'en' else f"{member.mention} تم فك التايم آوت عنه بشكل تلقائي."
await channel.send(msg)
if guild_id in timeout_data and user_id in timeout_data[guild_id]:
del timeout_data[guild_id][user_id]
save_data(timeout_data, TIMEOUT_FILE)
except Exception as e:
logger.error(f"Error un-timing out user {user_id}: {e}")
@bot.event
async def on_guild_join(guild):
try:
role = await guild.create_role(
name="🛡 Bot Moderation",
permissions=discord.Permissions(moderate_members=True, kick_members=True, ban_members=True, manage_messages=True),
hoist=True,
mentionable=True
)
guild_id = str(guild.id)
config_data[guild_id] = {
'admin_role_id': role.id,
'allowed_users': [],
'language': 'en',
'bad_words': ['fuck', 'shit', 'asshole'] # Add more bad words as needed
}
save_data(config_data, CONFIG_FILE)
logger.info(f"Created '🛡 Bot Moderation' role and set config for guild {guild_id}")
except discord.Forbidden:
logger.error(f"Failed to create role in guild {guild.id}: Missing permissions")
except Exception as e:
logger.error(f"Error in on_guild_join for guild {guild.id}: {e}")
async def apply_timeout(member: discord.Member, duration_delta: timedelta, reason: str):
timeout_end_time = datetime.utcnow() + duration_delta
try:
await member.edit(timed_out_until=timeout_end_time, reason=reason)
guild_id = str(member.guild.id)
user_id = str(member.id)
if guild_id not in timeout_data:
timeout_data[guild_id] = {}
timeout_data[guild_id][user_id] = {
"end_time": timeout_end_time.isoformat(),
"reason": reason
}
save_data(timeout_data, TIMEOUT_FILE)
log_action(guild_id, "timeout", user_id, bot.user.id, reason)
return True
except discord.Forbidden:
return False
async def process_ai_command(ctx, prompt: str):
guild_id = str(ctx.guild.id)
config = config_data.get(guild_id, {})
lang = config.get('language', 'en')
prompt = prompt.lower().strip()
# Role creation
if 'create role' in prompt or 'ضيف رول' in prompt:
match = re.search(r'name\s+([a-zA-Z0-9\s]+)', prompt) or re.search(r'اسم(ه|ها)?\s+([a-zA-Z0-9\s]+)', prompt)
if match:
role_name = match.group(2 if 'name' in prompt else 2).strip()
try:
new_role = await ctx.guild.create_role(name=role_name)
msg = f"✅ Role **{role_name}** created successfully." if lang == 'en' else f"✅ تم إنشاء رول جديد باسم **{role_name}**."
await ctx.send(msg)
log_action(guild_id, "create_role", None, ctx.author.id, f"Created role {role_name}")
# Handle permissions
perms_match = re.search(r'permissions\s+(.+)', prompt) or re.search(r'و(اديله|اديها|اديهم)?\s+(صلاحيات|برميشناات|برميشن)?\s+(.+)', prompt)
if perms_match:
perms_text = perms_match.group(1 if 'permissions' in prompt else 3).lower()
perms = {}
if 'kick' in perms_text or 'كيك' in perms_text:
perms['kick_members'] = True
if 'ban' in perms_text or 'بان' in perms_text:
perms['ban_members'] = True
if 'timeout' in perms_text or 'تايم آوت' in perms_text or 'mute' in perms_text or 'ميوت' in perms_text:
perms['moderate_members'] = True
if perms:
await new_role.edit(permissions=discord.Permissions(**perms))
msg = f"✅ Permissions updated for role **{role_name}**." if lang == 'en' else f"✅ تم تعديل صلاحيات رول **{role_name}** حسب طلبك."
await ctx.send(msg)
else:
msg = "🤔 Could not determine permissions." if lang == 'en' else "🤔 معرفتش أحدد الصلاحيات اللي عايزها بالظبط."
await ctx.send(msg)
except discord.Forbidden:
msg = "❌ I don't have permission to create roles." if lang == 'en' else "❌ معلش، ماليش صلاحية أضيف رول."
await ctx.send(msg)
return
# Default AI response
for attempt in range(3): # Retry up to 3 times
try:
client = Client("amd/gpt-oss-120b-chatbot")
loop = asyncio.get_running_loop()
ai_output = await loop.run_in_executor(
executor,
lambda: client.predict(
message=prompt,
system_prompt=SYSTEM_PROMPT,
temperature=0.7,
reasoning_effort="medium",
enable_browsing=False,
api_name="/chat"
)
)
match = re.search(r'💬 Response:\s*(.+)', ai_output, re.DOTALL)
response = match.group(1).strip() if match else ai_output.strip()
await ctx.send(response)
return
except Exception as e:
logger.error(f"AI attempt {attempt + 1} failed: {e}")
if attempt < 2:
await asyncio.sleep(2) # Wait before retrying
else:
msg = f"Error communicating with AI after 3 attempts: {e}" if lang == 'en' else f"حصل خطأ أثناء التواصل مع الذكاء الاصطناعي بعد 3 محاولات: {e}"
await ctx.send(msg)
async def chat_with_ai(message: discord.Message):
guild_id = str(message.guild.id)
config = config_data.get(guild_id, {})
lang = config.get('language', 'en')
text = message.content.lower()
gender = 'neutral'
if 'انا بنت' in text or 'انا انثى' in text or 'عايزة' in text or 'مبسوطة' in text:
gender = 'female'
elif 'انا ولد' in text or 'انا ذكر' in text or 'عايز' in text or 'مبسوط' in text:
gender = 'male'
responses = {
'neutral': {"en": "I'm doing great, thanks! How about you?", "ar": "أنا كويس جداً. أخبارك إيه؟"},
'female': {"en": "Hey there, doing awesome! How about you, queen?", "ar": "الحمد لله تمام يا قمر. عاملة إيه إنتي؟"},
'male': {"en": "Yo, I'm good! What's up with you, champ?", "ar": "الحمد لله بخير يا بطل. عامل إيه؟"}
}
if 'how are you' in text or 'عامل ايه' in text or 'اخبارك' in text:
await message.channel.send(responses[gender][lang])
elif 'who are you' in text or 'مين انت' in text or 'اسمك' in text:
msg = "I'm OS Bot, your friendly Discord moderation assistant!" if lang == 'en' else "أنا بوت إدارة ذكي، تحت أمرك!"
await message.channel.send(msg)
elif 'help me' in text or 'بساعدني' in text or 'ممكن تساعدني' in text:
msg = {
'female': {"en": "Of course, queen! Let me know what you need.", "ar": "أكيد يا قمر، تحت أمرك. ممكن تكتبي اللي محتاجاه."},
'male': {"en": "Sure thing, champ! What's up?", "ar": "أكيد يا معلم، تحت أمرك. ممكن تكتب اللي محتاجه."},
'neutral': {"en": "Happy to help! What's up?", "ar": "أكيد، تحت أمرك. ممكن تكتب اللي محتاجه."}
}[gender][lang]
await message.channel.send(msg)
@bot.event
async def on_ready():
logger.info(f'Logged in as {bot.user.name}')
bot.loop.create_task(timeout_check())
@bot.event
async def on_message(message):
if message.author.bot:
return
guild_id = str(message.guild.id)
user_id = str(message.author.id)
config = config_data.get(guild_id, {})
bad_words = config.get('bad_words', [])
content_lower = message.content.lower()
if any(word in content_lower for word in bad_words):
await message.delete()
today = datetime.utcnow().date().isoformat()
if guild_id not in badword_counts:
badword_counts[guild_id] = {}
if user_id not in badword_counts[guild_id]:
badword_counts[guild_id][user_id] = {}
if today not in badword_counts[guild_id][user_id]:
badword_counts[guild_id][user_id][today] = 0
badword_counts[guild_id][user_id][today] += 1
count = badword_counts[guild_id][user_id][today]
save_data(badword_counts, BADWORD_COUNTS_FILE)
lang = config.get('language', 'en')
warn_msg = f"{message.author.mention} please watch your language." if lang == 'en' else f"{message.author.mention} رجاءً احترس في كلامك."
await message.channel.send(warn_msg)
if count == 1:
duration_delta = timedelta(minutes=10)
success = await apply_timeout(message.author, duration_delta, "Bad word usage (first offense)")
if success:
msg = f"{message.author.mention} has been timed out for 10 minutes." if lang == 'en' else f"تم وضع تايم آوت لـ {message.author.mention} لمدة 10 دقائق."
await message.channel.send(msg)
elif count >= 10:
duration_delta = timedelta(days=30)
success = await apply_timeout(message.author, duration_delta, "Excessive bad word usage")
if success:
msg = f"{message.author.mention} has been timed out for 1 month." if lang == 'en' else f"تم وضع تايم آوت لـ {message.author.mention} لمدة شهر."
await message.channel.send(msg)
admin_role_id = config.get('admin_role_id')
is_admin = False
if admin_role_id:
admin_role = discord.utils.get(message.guild.roles, id=admin_role_id)
if admin_role and admin_role in message.author.roles:
is_admin = True
if user_id in config.get('allowed_users', []):
is_admin = True
if is_admin and bot.user.mentioned_in(message):
clean_content = message.content.replace(f'<@!{bot.user.id}>', '').strip()
await process_ai_command(message.channel, clean_content)
return
if bot.user.mentioned_in(message) or message.channel.name.startswith('general'):
await chat_with_ai(message)
await bot.process_commands(message)
@bot.event
async def on_close():
executor.shutdown(wait=True)
logger.info("Bot is shutting down and ThreadPoolExecutor is closed.")
async def is_mod(ctx):
guild_id = str(ctx.guild.id)
config = config_data.get(guild_id, {})
admin_role_id = config.get('admin_role_id')
if admin_role_id:
role = ctx.guild.get_role(admin_role_id)
if role and role in ctx.author.roles:
return True
allowed_users = config.get('allowed_users', [])
if str(ctx.author.id) in allowed_users:
return True
if ctx.author.guild_permissions.administrator:
return True
return False
@bot.command(name='access')
@commands.has_permissions(administrator=True)
async def access(ctx, role: discord.Role):
guild_id = str(ctx.guild.id)
if guild_id not in config_data:
config_data[guild_id] = {}
config_data[guild_id]['admin_role_id'] = role.id
save_data(config_data, CONFIG_FILE)
lang = config_data[guild_id].get('language', 'en')
msg = f"✅ Role **{role.name}** set as admin role." if lang == 'en' else f"✅ تم تحديد رول **{role.name}** لكي يكون لها صلاحية استخدام أوامر البوت الإدارية."
await ctx.send(msg)
log_action(guild_id, "set_admin_role", None, ctx.author.id, f"Set admin role to {role.name}")
@bot.command(name='addaccess')
@commands.has_permissions(administrator=True)
async def addaccess(ctx, member: discord.Member):
guild_id = str(ctx.guild.id)
if guild_id not in config_data:
config_data[guild_id] = {}
if 'allowed_users' not in config_data[guild_id]:
config_data[guild_id]['allowed_users'] = []
user_id = str(member.id)
if user_id not in config_data[guild_id]['allowed_users']:
config_data[guild_id]['allowed_users'].append(user_id)
save_data(config_data, CONFIG_FILE)
lang = config_data[guild_id].get('language', 'en')
msg = f"✅ Added moderation access to {member.mention}." if lang == 'en' else f"✅ تم إضافة صلاحية الإدارة لـ {member.mention}."
await ctx.send(msg)
log_action(guild_id, "add_access", member.id, ctx.author.id, "Added individual mod access")
@bot.command(name='removeaccess')
@commands.has_permissions(administrator=True)
async def removeaccess(ctx, member: discord.Member):
guild_id = str(ctx.guild.id)
if guild_id in config_data and 'allowed_users' in config_data[guild_id]:
user_id = str(member.id)
if user_id in config_data[guild_id]['allowed_users']:
config_data[guild_id]['allowed_users'].remove(user_id)
save_data(config_data, CONFIG_FILE)
lang = config_data[guild_id].get('language', 'en')
msg = f"✅ Removed moderation access from {member.mention}." if lang == 'en' else f"✅ تم إزالة صلاحية الإدارة من {member.mention}."
await ctx.send(msg)
log_action(guild_id, "remove_access", member.id, ctx.author.id, "Removed individual mod access")
@bot.command(name='setlang')
@commands.check(is_mod)
async def setlang(ctx, lang: str):
guild_id = str(ctx.guild.id)
lang = lang.lower()
if lang in ['en', 'ar']:
if guild_id not in config_data:
config_data[guild_id] = {}
config_data[guild_id]['language'] = lang
save_data(config_data, CONFIG_FILE)
msg = "Language set to English." if lang == 'en' else "تم ضبط اللغة على العربية."
await ctx.send(msg)
log_action(guild_id, "set_language", None, ctx.author.id, f"Set language to {lang}")
else:
await ctx.send("Please specify 'en' for English or 'ar' for Arabic.")
@bot.command(name='ban')
@commands.check(is_mod)
async def ban(ctx, member: discord.Member, *, reason=None):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
try:
await member.ban(reason=reason)
msg = f"{member.mention} has been banned." if lang == 'en' else f"{member.mention} تم حظره من السيرفر."
await ctx.send(msg)
log_action(guild_id, "ban", member.id, ctx.author.id, reason or "No reason provided")
except discord.Forbidden:
msg = "❌ I don't have permission to ban members." if lang == 'en' else "❌ ماليش صلاحية أحظر أعضاء."
await ctx.send(msg)
@bot.command(name='unban')
@commands.check(is_mod)
async def unban(ctx, *, member):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
try:
banned_users = [entry async for entry in ctx.guild.bans()]
member_name, member_discriminator = member.split('#')
for ban_entry in banned_users:
user = ban_entry.user
if (user.name, user.discriminator) == (member_name, member_discriminator):
await ctx.guild.unban(user)
msg = f"Unbanned {user.mention}." if lang == 'en' else f"تم فك الحظر عن {user.mention}."
await ctx.send(msg)
log_action(guild_id, "unban", user.id, ctx.author.id, "Unbanned user")
return
msg = f"Could not find {member} in the ban list." if lang == 'en' else f"مقدرتش الاقي {member} في قائمة المحظورين."
await ctx.send(msg)
except discord.Forbidden:
msg = "❌ I don't have permission to unban members." if lang == 'en' else "❌ ماليش صلاحية أفك الحظر عن أعضاء."
await ctx.send(msg)
@bot.command(name='kick')
@commands.check(is_mod)
async def kick(ctx, member: discord.Member, *, reason=None):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
try:
await member.kick(reason=reason)
msg = f"{member.mention} has been kicked." if lang == 'en' else f"{member.mention} تم طرده من السيرفر."
await ctx.send(msg)
log_action(guild_id, "kick", member.id, ctx.author.id, reason or "No reason provided")
except discord.Forbidden:
msg = "❌ I don't have permission to kick members." if lang == 'en' else "❌ ماليش صلاحية أطرد أعضاء."
await ctx.send(msg)
@bot.command(name='timeout')
@commands.check(is_mod)
async def timeout(ctx, member: discord.Member, duration_str: str, *, reason="No reason provided"):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
unit = duration_str[-1].lower()
try:
value = int(duration_str[:-1])
except ValueError:
msg = "Invalid duration format. Use s (seconds), m (minutes), h (hours)." if lang == 'en' else "صيغة المدة غلط. استخدم s (ثانية)، m (دقيقة)، h (ساعة)."
await ctx.send(msg)
return
if unit == 's':
duration_delta = timedelta(seconds=value)
elif unit == 'm':
duration_delta = timedelta(minutes=value)
elif unit == 'h':
duration_delta = timedelta(hours=value)
else:
msg = "Invalid duration format. Use s (seconds), m (minutes), h (hours)." if lang == 'en' else "صيغة المدة غلط. استخدم s (ثانية)، m (دقيقة)، h (ساعة)."
await ctx.send(msg)
return
success = await apply_timeout(member, duration_delta, reason)
if success:
msg = f"Timed out {member.mention} for {duration_str}. Reason: {reason}" if lang == 'en' else f"تم وضع تايم آوت لـ {member.mention} لمدة {duration_str}. السبب: {reason}"
await ctx.send(msg)
else:
msg = f"❌ I don't have permission to timeout {member.mention}." if lang == 'en' else f"❌ ماليش صلاحية أضع تايم آوت لـ {member.mention}."
await ctx.send(msg)
@bot.command(name='untimeout')
@commands.check(is_mod)
async def untimeout(ctx, member: discord.Member, *, reason="No reason provided"):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
if member.timed_out_until:
try:
await member.edit(timed_out_until=None, reason=reason)
user_id = str(member.id)
if guild_id in timeout_data and user_id in timeout_data[guild_id]:
del timeout_data[guild_id][user_id]
save_data(timeout_data, TIMEOUT_FILE)
msg = f"Removed timeout from {member.mention}." if lang == 'en' else f"تم إزالة التايم آوت من {member.mention}."
await ctx.send(msg)
log_action(guild_id, "untimeout", member.id, ctx.author.id, reason)
except discord.Forbidden:
msg = f"❌ I don't have permission to remove timeout from {member.mention}." if lang == 'en' else f"❌ ماليش صلاحية أزيل التايم آوت من {member.mention}."
await ctx.send(msg)
else:
msg = f"{member.mention} is not timed out." if lang == 'en' else f"{member.mention} ليس في حالة تايم آوت."
await ctx.send(msg)
@bot.command(name='warn')
@commands.check(is_mod)
async def warn(ctx, member: discord.Member, *, reason="No reason provided"):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
user_id = str(member.id)
if guild_id not in warnings_data:
warnings_data[guild_id] = {}
if user_id not in warnings_data[guild_id]:
warnings_data[guild_id][user_id] = []
warnings_data[guild_id][user_id].append({
"reason": reason,
"timestamp": datetime.utcnow().isoformat(),
"moderator": str(ctx.author.id)
})
save_data(warnings_data, WARNS_FILE)
warn_count = len(warnings_data[guild_id][user_id])
msg = f"Warned {member.mention}. Total warnings: {warn_count}. Reason: {reason}" if lang == 'en' else f"تم تحذير {member.mention}. عدد التحذيرات: {warn_count}. السبب: {reason}"
await ctx.send(msg)
log_action(guild_id, "warn", member.id, ctx.author.id, reason)
# Auto-moderation based on warning count
if warn_count >= 3:
duration_delta = timedelta(hours=1)
success = await apply_timeout(member, duration_delta, "Automatic timeout: 3 warnings")
if success:
msg = f"{member.mention} has been timed out for 1 hour due to 3 warnings." if lang == 'en' else f"تم وضع تايم آوت لـ {member.mention} لمدة ساعة بسبب 3 تحذيرات."
await ctx.send(msg)
if warn_count >= 5:
try:
await ctx.guild.kick(member, reason="Automatic kick: 5 warnings")
msg = f"{member.mention} has been kicked due to 5 warnings." if lang == 'en' else f"تم طرد {member.mention} بسبب 5 تحذيرات."
await ctx.send(msg)
except discord.Forbidden:
msg = "❌ I don't have permission to kick members." if lang == 'en' else "❌ ماليش صلاحية أطرد أعضاء."
await ctx.send(msg)
if warn_count >= 7:
try:
await ctx.guild.ban(member, reason="Automatic ban: 7 warnings")
msg = f"{member.mention} has been banned due to 7 warnings." if lang == 'en' else f"تم حظر {member.mention} بسبب 7 تحذيرات."
await ctx.send(msg)
except discord.Forbidden:
msg = "❌ I don't have permission to ban members." if lang == 'en' else "❌ ماليش صلاحية أحظر أعضاء."
await ctx.send(msg)
@bot.command(name='clear')
@commands.check(is_mod)
async def clear(ctx, amount: int):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
if amount > 1000:
msg = "I can only delete up to 1000 messages at a time." if lang == 'en' else "أقدر أمسح لحد 1000 رسالة بس في المرة الواحدة."
await ctx.send(msg)
return
await ctx.channel.purge(limit=amount + 1)
msg = f"Deleted {amount} messages." if lang == 'en' else f"{amount} رسالة اتمسحت."
await ctx.send(msg, delete_after=5)
log_action(guild_id, "clear", None, ctx.author.id, f"Deleted {amount} messages")
@bot.command(name='serverinfo')
async def serverinfo(ctx):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
guild = ctx.guild
embed = discord.Embed(title="Server Info" if lang == 'en' else "معلومات السيرفر", color=discord.Color.blue())
embed.add_field(name="Server Name" if lang == 'en' else "اسم السيرفر", value=guild.name, inline=True)
embed.add_field(name="Member Count" if lang == 'en' else "عدد الأعضاء", value=guild.member_count, inline=True)
embed.add_field(name="Created At" if lang == 'en' else "تاريخ الإنشاء", value=guild.created_at.strftime("%Y-%m-%d"), inline=True)
embed.add_field(name="Owner" if lang == 'en' else "المالك", value=guild.owner.mention, inline=True)
await ctx.send(embed=embed)
@bot.command(name='chat')
async def chat(ctx, *, user_message: str):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
user_id = str(ctx.author.id)
if user_id not in chat_history:
chat_history[user_id] = []
is_reply_to_bot = ctx.message.reference and ctx.message.reference.resolved and ctx.message.reference.resolved.author == bot.user
if is_reply_to_bot:
memory = chat_history[user_id]
else:
memory = []
chat_history[user_id] = memory
memory.append({"role": "user", "content": user_message})
if len(memory) > MAX_CHAT_HISTORY:
memory.pop(0)
thinking_msg = await ctx.send("💭 Thinking..." if lang == 'en' else "💭 OS Bot is thinking...")
for attempt in range(3):
try:
client = Client("amd/gpt-oss-120b-chatbot")
loop = asyncio.get_running_loop()
ai_output = await loop.run_in_executor(
executor,
lambda: client.predict(
message=user_message,
system_prompt=SYSTEM_PROMPT,
temperature=0.7,
reasoning_effort="medium",
enable_browsing=False,
api_name="/chat"
)
)
match = re.search(r'💬 Response:\s*(.+)', ai_output, re.DOTALL)
final_response = match.group(1).strip() if match else ai_output.strip()
memory.append({"role": "assistant", "content": final_response})
await thinking_msg.edit(content=final_response)
return
except Exception as e:
logger.error(f"AI attempt {attempt + 1} failed: {e}")
if attempt < 2:
await asyncio.sleep(2)
else:
msg = f"Error communicating with AI after 3 attempts: {e}" if lang == 'en' else f"حصل خطأ أثناء التواصل مع الذكاء الاصطناعي بعد 3 محاولات: {e}"
await thinking_msg.edit(content=msg)
if user_id in chat_history:
del chat_history[user_id]
@bot.command(name='join')
async def join(ctx):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
if not ctx.author.voice:
msg = "You are not in a voice channel." if lang == 'en' else "أنت مش في أي قناة صوتية."
return await ctx.send(msg)
channel = ctx.author.voice.channel
if ctx.voice_client:
if ctx.voice_client.channel == channel:
msg = "I'm already in this voice channel." if lang == 'en' else "أنا بالفعل في نفس القناة دي."
return await ctx.send(msg)
else:
await ctx.voice_client.move_to(channel)
msg = f"Moved to voice channel: **{channel.name}**." if lang == 'en' else f"تم الانتقال إلى قناة: **{channel.name}**."
return await ctx.send(msg)
await channel.connect()
msg = f"Joined voice channel: **{channel.name}**." if lang == 'en' else f"تم الانضمام إلى قناة: **{channel.name}**."
await ctx.send(msg)
@bot.command(name='leave')
async def leave(ctx):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
if ctx.voice_client:
await ctx.voice_client.disconnect()
msg = "Left the voice channel." if lang == 'en' else "تم الخروج من القناة الصوتية."
await ctx.send(msg)
else:
msg = "I'm not in any voice channel." if lang == 'en' else "أنا مش في أي قناة صوتية حالياً."
await ctx.send(msg)
@bot.command(name='ask')
@commands.cooldown(1, 10, commands.BucketType.user)
async def ask(ctx, *, text_query: str):
guild_id = str(ctx.guild.id)
lang = config_data.get(guild_id, {}).get('language', 'en')
if not ctx.voice_client:
msg = "I'm not in a voice channel. Use `$join` to connect me." if lang == 'en' else "أنا مش متصل بقناة صوتية. استخدم `$join` عشان أقدر أنضم."
return await ctx.send(msg)
thinking_msg = await ctx.send("💭 Thinking..." if lang == 'en' else "💭 OS Bot is thinking...")
for attempt in range(3):
try:
client = Client("amd/gpt-oss-120b-chatbot")
loop = asyncio.get_running_loop()
ai_output = await loop.run_in_executor(
executor,
lambda: client.predict(
message=text_query,
system_prompt=SYSTEM_PROMPT,
temperature=0.7,
reasoning_effort="medium",
enable_browsing=False,
api_name="/chat"
)
)
match = re.search(r'💬 Response:\s*(.+)', ai_output, re.DOTALL)
final_response = match.group(1).strip() if match else ai_output.strip()
# Save to chat history
user_id = str(ctx.author.id)
if user_id not in chat_history:
chat_history[user_id] = []
chat_history[user_id].append({"role": "user", "content": text_query})
chat_history[user_id].append({"role": "assistant", "content": final_response})
if len(chat_history[user_id]) > MAX_CHAT_HISTORY:
chat_history[user_id].pop(0)
# Convert AI response to voice
try:
logger.info(f"Generating TTS for response: {final_response}")
tts = gTTS(text=final_response, lang='ar' if lang == 'ar' else 'en', slow=False)
voice_buffer = io.BytesIO()
tts.write_to_fp(voice_buffer)
voice_buffer.seek(0)
logger.info(f"TTS audio buffer created, size: {len(voice_buffer.getvalue())} bytes")
ffmpeg_options = {
'options': '-f s16le -ar 48000 -ac 2'
}
source = discord.FFmpegPCMAudio(
source=voice_buffer,
pipe=True,
executable=FFMPEG_PATH,
**ffmpeg_options
)
def after_playback(error):
if error:
logger.error(f"Playback error: {error}")
else:
logger.info("Audio playback completed successfully")
ctx.voice_client.play(source, after=after_playback)
while ctx.voice_client.is_playing():
await asyncio.sleep(1)
await thinking_msg.edit(content=f"Response: `{final_response}`" if lang == 'en' else f"الرد: `{final_response}`")
return
except Exception as e:
logger.error(f"TTS error: {e}")
msg = f"Error converting text to speech: {e}" if lang == 'en' else f"حصل خطأ أثناء تحويل النص إلى صوت: {e}"
await thinking_msg.edit(content=msg)
return
except Exception as e:
logger.error(f"AI attempt {attempt + 1} failed: {e}")
if attempt < 2:
await asyncio.sleep(2)
else:
msg = f"Error communicating with AI after 3 attempts: {e}" if lang == 'en' else f"حصل خطأ أثناء التواصل مع الذكاء الاصطناعي بعد 3 محاولات: {e}"
await thinking_msg.edit(content=msg)
return
# Retry-enabled bot start
async def start_bot():
for attempt in range(3):
try:
await bot.start(TOKEN)
return
except aiohttp.client_exceptions.ClientConnectorDNSError as e:
logger.error(f"Connection attempt {attempt + 1} failed: {e}")
if attempt < 2:
await asyncio.sleep(5)
else:
logger.error("Failed to connect to Discord after 3 attempts. Exiting.")
raise
# Run the bot with retry
if __name__ == "__main__":
try:
asyncio.run(start_bot())
except Exception as e:
logger.error(f"Fatal error: {e}")