Skip to content

Commit 7c54bc8

Browse files
authored
Merge pull request #5 from codebyant/2025_revamp
Adds support for multiple languages ​​and environment settings
2 parents de48b71 + 3398f3f commit 7c54bc8

File tree

7 files changed

+121
-24
lines changed

7 files changed

+121
-24
lines changed

.env.exemple

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ CHANNEL_2=Your_Channel_ID_Here
44
CHANNEL_3=Your_Channel_ID_Here
55
NOTIFICATION_CHANNEL=Your_NOTIFICATION_Channel_ID_Here # This is the channel where the bot will send the notifications
66
RICH_PRESENCE=Katchau! # This is the rich presence of the bot (example: "Katchau!") as a string
7-
ACTIVITY=listening # This is the activity of the bot, you can use "game", "listening", "watching" or "streaming")
7+
ACTIVITY=listening # This is the activity of the bot, you can use "game", "listening", "watching" or "streaming")
8+
BOT_LOCALE=en_US #(Optional) used to translate the bot messages.

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ WORKDIR /app
77
# Copy the necessary files to the bot container
88
COPY bot.py /app
99
COPY requirements.txt /app
10+
COPY locales /app/locales
1011

1112
# Install dependencies
1213
RUN pip install --no-cache-dir -r requirements.txt

bot.py

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from datetime import datetime, timedelta
55
import operator
66
import os
7+
import json
78
from dotenv import load_dotenv
89
import sqlite3
910

@@ -14,9 +15,25 @@
1415
intents.voice_states = True
1516
intents.members = True
1617

17-
client = commands.Bot(command_prefix='!', intents=intents)
18+
client = commands.Bot(command_prefix=None, intents=intents)
1819
slash = SlashCommand(client)
1920

21+
# Load locales
22+
def load_locale(lang=None):
23+
if not lang:
24+
lang = os.getenv('BOT_LOCALE', 'en_US')
25+
26+
try:
27+
with open(f'locales/{lang}.json', 'r', encoding='utf-8') as f:
28+
return json.load(f)
29+
except FileNotFoundError:
30+
# Fallback to English if locale file not found
31+
with open('locales/en_US.json', 'r', encoding='utf-8') as f:
32+
return json.load(f)
33+
34+
# Load locale from environment variable
35+
locale = load_locale()
36+
2037
# Connect to SQLite database
2138
conn = sqlite3.connect('bot_database.db')
2239
cursor = conn.cursor()
@@ -30,6 +47,7 @@
3047
last_call_time TIMESTAMP
3148
)
3249
''')
50+
3351
conn.commit()
3452

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

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

95+
notification_channel_id = os.getenv('NOTIFICATION_CHANNEL')
96+
if not notification_channel_id:
97+
return
98+
99+
channel = client.get_channel(int(notification_channel_id))
100+
if not channel:
101+
return
102+
103+
# User joined a voice channel
77104
if after.channel:
78105
if len(after.channel.members) == 1:
79-
channel = client.get_channel(int(os.getenv('NOTIFICATION_CHANNEL')))
80-
await channel.send(f"{member.name} is in {after.channel.name}")
106+
# First person in the channel - mark with @everyone
107+
await channel.send(locale["user_joined_call"].format(member=member.mention))
81108

82109
# Update entry count and last call time in the database
83110
cursor.execute('''
@@ -89,26 +116,31 @@ async def on_voice_state_update(member, before, after):
89116
if show_log:
90117
print(f"{member.name} entered a channel.")
91118
else:
92-
cursor.execute('SELECT last_call_time FROM users WHERE id = ?', (member.id,))
93-
result = cursor.fetchone()
94-
last_call_time = datetime.fromisoformat(result[0]) if result else datetime.min
95-
if datetime.now() - last_call_time >= timedelta(minutes=60):
96-
cursor.execute('UPDATE users SET last_call_time = ? WHERE id = ?', (datetime.now(), member.id))
97-
conn.commit()
98-
channel = client.get_channel(1206713130353295450)
99-
if not before.channel:
100-
await channel.send(f"{member.mention} is in the call! @here")
119+
# Other people joining - just show channel info
120+
await channel.send(locale["user_in_channel"].format(member=member.name, channel=after.channel.name))
121+
122+
# User left a voice channel
123+
if before.channel and not after.channel:
124+
await channel.send(locale["user_left_channel"].format(member=member.name, channel=before.channel.name))
101125

102-
if before.channel and after.channel and before.channel != after.channel and show_log:
103-
print(f"{member.name} was moved from {before.channel.name} to {after.channel.name}")
126+
# User moved between channels
127+
if before.channel and after.channel and before.channel != after.channel:
128+
await channel.send(locale["user_moved_to_channel"].format(
129+
member=member.name,
130+
old_channel=before.channel.name,
131+
new_channel=after.channel.name
132+
))
133+
134+
if show_log:
135+
print(f"{member.name} was moved from {before.channel.name} to {after.channel.name}")
104136

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

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

133165
# Load the bot token from environment variables
134166
TOKEN = os.getenv('DISCORD_BOT_TOKEN')

docker-compose.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
services:
2+
bot:
3+
container_name: esk
4+
build:
5+
context: .
6+
restart: unless-stopped
7+
env_file:
8+
- .env

locales/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
## Locales
2+
3+
By default, the bot will use the English locale, and have the portuguese locale available as an alternative.
4+
5+
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.
6+
7+
The locale file must be a JSON file with the following structure as an example:
8+
9+
```json
10+
{
11+
"user_joined_call": "{member} joined the call! @everyone",
12+
"user_in_channel": "{member} joined {channel}",
13+
"user_left_channel": "{member} left {channel}",
14+
"user_moved_to_channel": "{member} left {old_channel} and went to {new_channel}",
15+
"leaderboard_title": "Entry Leaderboard:",
16+
"leaderboard_entry": "{position}. {name}: {count} times",
17+
"toggle_enabled": "Functionality to send a message when someone enters a call is now enabled.",
18+
"toggle_disabled": "Functionality to send a message when someone enters a call is now disabled.",
19+
"help_title": "Hello, {author}! Here's the list of available commands:",
20+
"help_leaders": "/leaders - Shows how many times each user entered calls.",
21+
"help_toggle": "/toggle - Turns on/off the functionality of sending a message when someone enters a call.",
22+
"help_help": "/help - Get a list of commands."
23+
}
24+
25+
```
26+
27+
[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.

locales/en_US.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"user_joined_call": "{member} joined the call! @everyone",
3+
"user_in_channel": "{member} joined {channel}",
4+
"user_left_channel": "{member} left {channel}",
5+
"user_moved_to_channel": "{member} left {old_channel} and went to {new_channel}",
6+
"leaderboard_title": "Entry Leaderboard:",
7+
"leaderboard_entry": "{position}. {name}: {count} times",
8+
"toggle_enabled": "Functionality to send a message when someone enters a call is now enabled.",
9+
"toggle_disabled": "Functionality to send a message when someone enters a call is now disabled.",
10+
"help_title": "Hello, {author}! Here's the list of available commands:",
11+
"help_leaders": "/leaders - Shows how many times each user entered calls.",
12+
"help_toggle": "/toggle - Turns on/off the functionality of sending a message when someone enters a call.",
13+
"help_help": "/help - Get a list of commands."
14+
}

locales/pt_BR.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"user_joined_call": "{member} entrou na call! @everyone",
3+
"user_in_channel": "{member} entrou em {channel}",
4+
"user_left_channel": "{member} saiu de {channel}",
5+
"user_moved_to_channel": "{member} saiu de {old_channel} e foi para {new_channel}",
6+
"leaderboard_title": "Ranking de Entradas:",
7+
"leaderboard_entry": "{position}. {name}: {count} vezes",
8+
"toggle_enabled": "Funcionalidade de enviar mensagem quando alguém entra na call foi ativada.",
9+
"toggle_disabled": "Funcionalidade de enviar mensagem quando alguém entra na call foi desativada.",
10+
"help_title": "Olá, {author}! Aqui está a lista de comandos disponíveis:",
11+
"help_leaders": "/leaders - Mostra quantas vezes cada usuário entrou em calls.",
12+
"help_toggle": "/toggle - Ativa/desativa a funcionalidade de enviar mensagem quando alguém entra na call.",
13+
"help_help": "/help - Obtém a lista de comandos."
14+
}

0 commit comments

Comments
 (0)