Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.exemple
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ CHANNEL_2=Your_Channel_ID_Here
CHANNEL_3=Your_Channel_ID_Here
NOTIFICATION_CHANNEL=Your_NOTIFICATION_Channel_ID_Here # This is the channel where the bot will send the notifications
RICH_PRESENCE=Katchau! # This is the rich presence of the bot (example: "Katchau!") as a string
ACTIVITY=listening # This is the activity of the bot, you can use "game", "listening", "watching" or "streaming")
ACTIVITY=listening # This is the activity of the bot, you can use "game", "listening", "watching" or "streaming")
BOT_LOCALE=en_US #(Optional) used to translate the bot messages.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ WORKDIR /app
# Copy the necessary files to the bot container
COPY bot.py /app
COPY requirements.txt /app
COPY locales /app/locales

# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt
Expand Down
78 changes: 55 additions & 23 deletions bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from datetime import datetime, timedelta
import operator
import os
import json
from dotenv import load_dotenv
import sqlite3

Expand All @@ -14,9 +15,25 @@
intents.voice_states = True
intents.members = True

client = commands.Bot(command_prefix='!', intents=intents)
client = commands.Bot(command_prefix=None, intents=intents)
slash = SlashCommand(client)

# Load locales
def load_locale(lang=None):
if not lang:
lang = os.getenv('BOT_LOCALE', 'en_US')

try:
with open(f'locales/{lang}.json', 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
# Fallback to English if locale file not found
with open('locales/en_US.json', 'r', encoding='utf-8') as f:
return json.load(f)

# Load locale from environment variable
locale = load_locale()

# Connect to SQLite database
conn = sqlite3.connect('bot_database.db')
cursor = conn.cursor()
Expand All @@ -30,6 +47,7 @@
last_call_time TIMESTAMP
)
''')

conn.commit()

# Dictionary of messages per channel
Expand All @@ -38,7 +56,7 @@
channel_env = f'CHANNEL_{i}'
channel_id = os.getenv(channel_env)
if channel_id:
channel_messages[channel_id] = "{member.name} is in {channel_name}"
channel_messages[channel_id] = locale["user_in_channel"].format(member="{member.name}", channel="{channel_name}")
else:
break # Stop the loop if there are no more defined channels

Expand Down Expand Up @@ -74,10 +92,19 @@ async def on_voice_state_update(member, before, after):
if before.channel == after.channel:
return # Ignore updates that don't involve channel changes

notification_channel_id = os.getenv('NOTIFICATION_CHANNEL')
if not notification_channel_id:
return

channel = client.get_channel(int(notification_channel_id))
if not channel:
return

# User joined a voice channel
if after.channel:
if len(after.channel.members) == 1:
channel = client.get_channel(int(os.getenv('NOTIFICATION_CHANNEL')))
await channel.send(f"{member.name} is in {after.channel.name}")
# First person in the channel - mark with @everyone
await channel.send(locale["user_joined_call"].format(member=member.mention))

# Update entry count and last call time in the database
cursor.execute('''
Expand All @@ -89,26 +116,31 @@ async def on_voice_state_update(member, before, after):
if show_log:
print(f"{member.name} entered a channel.")
else:
cursor.execute('SELECT last_call_time FROM users WHERE id = ?', (member.id,))
result = cursor.fetchone()
last_call_time = datetime.fromisoformat(result[0]) if result else datetime.min
if datetime.now() - last_call_time >= timedelta(minutes=60):
cursor.execute('UPDATE users SET last_call_time = ? WHERE id = ?', (datetime.now(), member.id))
conn.commit()
channel = client.get_channel(1206713130353295450)
if not before.channel:
await channel.send(f"{member.mention} is in the call! @here")
# Other people joining - just show channel info
await channel.send(locale["user_in_channel"].format(member=member.name, channel=after.channel.name))

# User left a voice channel
if before.channel and not after.channel:
await channel.send(locale["user_left_channel"].format(member=member.name, channel=before.channel.name))

if before.channel and after.channel and before.channel != after.channel and show_log:
print(f"{member.name} was moved from {before.channel.name} to {after.channel.name}")
# User moved between channels
if before.channel and after.channel and before.channel != after.channel:
await channel.send(locale["user_moved_to_channel"].format(
member=member.name,
old_channel=before.channel.name,
new_channel=after.channel.name
))

if show_log:
print(f"{member.name} was moved from {before.channel.name} to {after.channel.name}")

@slash.slash(name="leaders", description="Shows how many times each user entered calls.")
async def leaders(ctx):
cursor.execute('SELECT id, name, entry_count FROM users ORDER BY entry_count DESC LIMIT 10')
leaderboard = cursor.fetchall()
leaderboard_text = "Entry Leaderboard:\n"
leaderboard_text = locale["leaderboard_title"] + "\n"
for idx, (user_id, name, count) in enumerate(leaderboard, start=1):
leaderboard_text += f"{idx}. {name}: {count} times\n"
leaderboard_text += locale["leaderboard_entry"].format(position=idx, name=name, count=count) + "\n"
await ctx.send(content=leaderboard_text)
if show_log:
print('Leaderboard command executed.')
Expand All @@ -117,18 +149,18 @@ async def leaders(ctx):
async def toggle_message(ctx):
global send_message_enabled
send_message_enabled = not send_message_enabled
status = "enabled" if send_message_enabled else "disabled"
await ctx.send(content=f"Functionality to send a message when someone enters a call is now {status}.")
status = locale["toggle_enabled"] if send_message_enabled else locale["toggle_disabled"]
await ctx.send(content=status)

@slash.slash(name="help", description="Get a list of commands.")
async def help(ctx):
commands = [
"/leaders - Shows how many times each user entered calls.",
"/toggle - Turns on/off the functionality of sending a message when someone enters a call.",
"/help - Get a list of commands."
locale["help_leaders"],
locale["help_toggle"],
locale["help_help"]
]
command_list = "\n".join(commands)
await ctx.send(content=f"Hello, {ctx.author.name}! Here's the list of available commands:\n\n{command_list}")
await ctx.send(content=locale["help_title"].format(author=ctx.author.name) + "\n\n" + command_list)

# Load the bot token from environment variables
TOKEN = os.getenv('DISCORD_BOT_TOKEN')
Expand Down
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
bot:
container_name: esk
build:
context: .
restart: unless-stopped
env_file:
- .env
27 changes: 27 additions & 0 deletions locales/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Locales

By default, the bot will use the English locale, and have the portuguese locale available as an alternative.

If you want to use a different locale, you can create a new file in the `locales` folder with the name of the locale you want to use, and then set the `BOT_LOCALE` environment variable to the name of the locale you want to use.

The locale file must be a JSON file with the following structure as an example:

```json
{
"user_joined_call": "{member} joined the call! @everyone",
"user_in_channel": "{member} joined {channel}",
"user_left_channel": "{member} left {channel}",
"user_moved_to_channel": "{member} left {old_channel} and went to {new_channel}",
"leaderboard_title": "Entry Leaderboard:",
"leaderboard_entry": "{position}. {name}: {count} times",
"toggle_enabled": "Functionality to send a message when someone enters a call is now enabled.",
"toggle_disabled": "Functionality to send a message when someone enters a call is now disabled.",
"help_title": "Hello, {author}! Here's the list of available commands:",
"help_leaders": "/leaders - Shows how many times each user entered calls.",
"help_toggle": "/toggle - Turns on/off the functionality of sending a message when someone enters a call.",
"help_help": "/help - Get a list of commands."
}

```

[NOTE] Keep an eye on the `en_US.json` file, as it could be updated in the future and you might need to update your locale file.
14 changes: 14 additions & 0 deletions locales/en_US.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"user_joined_call": "{member} joined the call! @everyone",
"user_in_channel": "{member} joined {channel}",
"user_left_channel": "{member} left {channel}",
"user_moved_to_channel": "{member} left {old_channel} and went to {new_channel}",
"leaderboard_title": "Entry Leaderboard:",
"leaderboard_entry": "{position}. {name}: {count} times",
"toggle_enabled": "Functionality to send a message when someone enters a call is now enabled.",
"toggle_disabled": "Functionality to send a message when someone enters a call is now disabled.",
"help_title": "Hello, {author}! Here's the list of available commands:",
"help_leaders": "/leaders - Shows how many times each user entered calls.",
"help_toggle": "/toggle - Turns on/off the functionality of sending a message when someone enters a call.",
"help_help": "/help - Get a list of commands."
}
14 changes: 14 additions & 0 deletions locales/pt_BR.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"user_joined_call": "{member} entrou na call! @everyone",
"user_in_channel": "{member} entrou em {channel}",
"user_left_channel": "{member} saiu de {channel}",
"user_moved_to_channel": "{member} saiu de {old_channel} e foi para {new_channel}",
"leaderboard_title": "Ranking de Entradas:",
"leaderboard_entry": "{position}. {name}: {count} vezes",
"toggle_enabled": "Funcionalidade de enviar mensagem quando alguém entra na call foi ativada.",
"toggle_disabled": "Funcionalidade de enviar mensagem quando alguém entra na call foi desativada.",
"help_title": "Olá, {author}! Aqui está a lista de comandos disponíveis:",
"help_leaders": "/leaders - Mostra quantas vezes cada usuário entrou em calls.",
"help_toggle": "/toggle - Ativa/desativa a funcionalidade de enviar mensagem quando alguém entra na call.",
"help_help": "/help - Obtém a lista de comandos."
}
Loading