Compare commits

...

34 Commits

Author SHA1 Message Date
5ca1bf798e I removed the name, run-name and on, why am I like this
Some checks failed
Compile / Compile (push) Failing after 1m1s
2026-01-06 18:26:22 -03:00
24dbb16ad7 One last attempt, removing the creating of pgsql and adding password to the services 2026-01-06 18:23:44 -03:00
e037333da1 Added "sudo" to please the Gods
Some checks failed
Compile / Compile (push) Failing after 16s
2026-01-06 18:21:41 -03:00
ffa982eb74 Removed the "-u" of the command line, sob
Some checks failed
Compile / Compile (push) Failing after 17s
2026-01-06 18:20:16 -03:00
6c0c15d3fa Added postgres user and db creation to workflow
Some checks failed
Compile / Compile (push) Failing after 18s
2026-01-06 18:19:05 -03:00
d8fc36bffb Changed host to IP address to see if workflow works now
Some checks failed
Compile / Compile (push) Failing after 22s
2026-01-06 18:16:55 -03:00
f516f0cf00 Forgot the comma, oopsies
Some checks failed
Compile / Compile (push) Failing after 20s
2026-01-06 18:13:54 -03:00
1253471fc3 Updated database code to see if it aligns with workflow requirements
Some checks failed
Compile / Compile (push) Failing after 22s
2026-01-06 18:12:55 -03:00
77d992720d Added postgres to the workflow just to see if it works
Some checks failed
Compile / Compile (push) Failing after 31s
2026-01-06 18:10:45 -03:00
eed6a9d9f6 Changed "export" to env
Some checks failed
Compile / Compile (push) Failing after 18s
2026-01-06 18:05:30 -03:00
9dc1cf10c7 Updated Set Token workflow to correct variables
Some checks failed
Compile / Compile (push) Failing after 23s
2026-01-06 17:56:04 -03:00
70e21fd118 Testing Gitea's Secrets
Some checks failed
Compile / Compile (push) Failing after 25s
2026-01-06 17:52:54 -03:00
4c06e3fbbd Added "gem install bundler" because it does not come with Ruby by default
Some checks failed
Compile / Compile (push) Failing after 19s
2026-01-06 17:41:49 -03:00
28529158e5 Added "apt-get update" to Install Ruby workflow
Some checks failed
Compile / Compile (push) Failing after 15s
2026-01-06 17:39:49 -03:00
13dbb86d38 Updated workflow: Install ruby first -> Install dependencies -> Run main file
Some checks failed
Compile / Compile (push) Failing after 5s
2026-01-06 17:37:33 -03:00
504773b1ca Changed "uses" to "run" 'cause I'm a bit dummy
Some checks failed
Compile / Compile (push) Failing after 4s
2026-01-06 17:33:14 -03:00
659bd70c75 Workflow added for testing purposes
Some checks failed
Compile / Compile (push) Failing after 4s
2026-01-06 17:31:10 -03:00
fc3c4787fe Localization added, but not implemented yet. 2026-01-06 17:18:29 -03:00
1035b3d0ab Just added a newline to separate boilerplate from start of the code 2026-01-06 15:11:26 -03:00
98c854929d Updated load_commands. Now it can load commands inside src/commands and subfolders inside commands folder. 2026-01-06 15:07:48 -03:00
f5ec2f38fc Updated note to explain further about "TEST_SERVER_ID". 2026-01-06 18:42:20 +01:00
ba22833413 Updated README based on current state of the bot. 2026-01-06 14:40:38 -03:00
1365491c13 Merge branch 'main' of https://git.thenight.club/csxkdv/FrugalityBot 2026-01-06 14:37:37 -03:00
741762856d Statements are now generated via embed. Gruff & Prawn/Prawn-Table are no longer needed. 2026-01-06 14:37:35 -03:00
4a535d4080 Updated markdown for "License" to point at the website instead of the LICENSE file 2026-01-06 03:23:57 +01:00
d5e727c358 Renamed "COPYING" to "LICENSE". That's it. 2026-01-06 03:18:41 +01:00
d824afc5da Added boilerplate notice 'cause I forgot to add it 2026-01-05 20:30:16 -03:00
Eri
f841f6ec95 Updated README based on current state of the bot 2026-01-06 00:29:07 +01:00
689079ce21 Added a way to see report/statements. Added more gems to the Gemfile. 2026-01-05 20:20:25 -03:00
d08af2f294 Fixed markdown being weird on README 2026-01-05 19:34:58 -03:00
4586295e62 Updated README. 2026-01-05 19:34:08 -03:00
a923fce12e Added a way to spend money. 2026-01-05 19:27:23 -03:00
6588d68cc4 Merge branch 'main' of https://git.thenight.club/csxkdv/FrugalityBot 2026-01-05 19:17:55 -03:00
86e1af1a66 Updated database content, new "add" command for earnings. 2026-01-05 19:16:04 -03:00
17 changed files with 503 additions and 46 deletions

View File

@@ -0,0 +1,45 @@
name: Compile
run-name: Compiling software (Ubuntu)
on: [push]
jobs:
Compile:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: fgbot_db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: test_password
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install Ruby and Bundler
run: |
apt-get update
apt-get install -y ruby-full libsodium-dev libpq-dev
gem install bundler
- name: Install dependencies
run: bundle install
- name: Execute program
env:
BOT_TOKEN: ${{ secrets.TOKEN }}
TEST_SERVER_ID: ${{ secrets.SERVER_ID }}
DB_HOST: 127.0.0.1
DB_USER: postgres
DB_PASS: test_password
DB_NAME: fgbot_db
run: bundle exec ruby main.rb

View File

@@ -3,4 +3,5 @@ source 'https://rubygems.org'
gem 'discordrb', git: 'https://github.com/shardlab/discordrb.git', branch: 'main'
gem 'dotenv'
gem 'pg'
gem 'pg'
gem 'i18n'

View File

@@ -17,6 +17,7 @@ GEM
remote: https://rubygems.org/
specs:
base64 (0.3.0)
concurrent-ruby (1.3.6)
domain_name (0.6.20240107)
dotenv (3.2.0)
event_emitter (0.2.6)
@@ -34,6 +35,8 @@ GEM
http-accept (1.7.0)
http-cookie (1.1.0)
domain_name (~> 0.5)
i18n (1.14.8)
concurrent-ruby (~> 1.0)
logger (1.7.0)
mime-types (3.7.0)
logger
@@ -78,10 +81,12 @@ PLATFORMS
DEPENDENCIES
discordrb!
dotenv
i18n
pg
CHECKSUMS
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
discordrb (3.7.2)
discordrb-webhooks (3.7.2)
domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933
@@ -100,6 +105,7 @@ CHECKSUMS
ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56
http-accept (1.7.0) sha256=c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126
http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19
i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56
mime-types-data (3.2025.0924) sha256=f276bca15e59f35767cbcf2bc10e023e9200b30bd6a572c1daf7f4cc24994728

View File

View File

@@ -1,12 +1,12 @@
# FrugalityBot
Frugality is a Discord Bot written in Ruby using `discordrb` and PostgreSQL. Its usage is meant to track your own finances, with monthly reports. Work in progress.
Frugality is a Discord Bot written in Ruby using `discordrb` and PostgreSQL. Its usage is meant to track your own finances, with monthly and/or yearly reports. Work in progress.
## Features
1. Commands are separated into individual files in `src/commands`. This is the only place you'll need to add a new command.
2. Automatically loads and registers new command files on startup.
3. Uses PostgreSQL to store user data.
4. Supports Discord's slash commands.
3. Uses PostgreSQL to store data (User IDs, coins amount, reason, timestamps).
4. Supports Discord's slash commands, and embeds for financial reports.
## Prerequisites
Before running the bot, ensure you have the following installed on your system:
@@ -46,8 +46,8 @@ The bot requires a PostgreSQL database.
createdb database
```
**The database name is also specified [here](https://git.thenight.club/csxkdv/FrugalityBot/src/branch/main/src/database.rb). Ensure it's the same as the one you'll use.**
*Note: The bot will automatically create the necessary tables (like `total_money`) the first time it connects. If you want new tables, update the database file as desired.*
*Note: The bot will automatically create the necessary tables (like `wallets` and `transactions`) the first time it connects. If you want new tables, update the database file as desired.*
## Configuration
@@ -59,13 +59,17 @@ The bot requires a PostgreSQL database.
2. Add your secrets to the `.env` file:
```env
BOT_TOKEN=your_discord_bot_token_here
TEST_SERVER_ID=your_discord_server_id
```
*Note: Add a Server ID only if you're planning on updating the bot frequently, and want instant changes to be seen. Otherwise, remove it from the .env file and every `server_id: ENV['TEST_SERVER_ID']` line from the `register_application_command` on every `src/commands/*.rb` file.*
## Usage
To start the bot, you must use `bundle exec` to load the local dependencies:
```bash
bundle exec ruby main.rb
```
Wait for the bot to connect, and that's it, you can start using it.
## License
This project is licensed under the [GNU General Public License v3.0](COPYING).
This project is licensed under the [GNU General Public License v3.0](https://spdx.org/licenses/GPL-3.0-or-later.html).

View File

@@ -15,10 +15,22 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
require 'discordrb'
require 'i18n'
require_relative 'database'
require_relative 'utils/locales_helper'
class FrugalityBot
def initialize
I18n.config.enforce_available_locales = false
locales_path = File.join(File.dirname(__dir__), 'locales')
I18n.load_path += Dir["#{locales_path}/*.yml"]
I18n.backend.load_translations
I18n.default_locale = :en
@bot = Discordrb::Bot.new(
token: ENV['BOT_TOKEN'],
intents: [:servers, :server_messages]
@@ -27,7 +39,7 @@ class FrugalityBot
@db = Database.new
load_commands
setup_events
startup_bot
end
def run
@@ -37,35 +49,22 @@ class FrugalityBot
private
def load_commands
# 1. We look for all .rb files in "src/commands/..."
comm_files = Dir[File.join(__dir__, 'commands', '*.rb')]
comm_files.each do |file|
require file # We import the file
# We convert filename to module name
# This mean that 'echo.rb' turns into 'Echo'
# 'server_info' would turn into 'ServerInfo'
filename = File.basename(file, '.rb')
module_name = filename.split('_').map(&:capitalize).join
begin
# We find the module inside 'Commands' namespace
comm_module = Commands.const_get(module_name)
# Register the command
comm_module.register(@bot, @db)
puts "Loaded command: #{module_name}"
rescue NameError => e
puts "Could not load #{filename}: Module 'Commands::#{module_name}' was not found."
rescue StandardError => e
puts "Error loading: #{filename}: #{e.message}"
end
Dir["#{File.dirname(__FILE__)}/commands/**/*.rb"].each do |file|
require file
end
Commands.constants.each do |const|
cmd = Commands.const_get(const)
if cmd.is_a?(Module) && cmd.respond_to?(:register)
cmd.register(@bot, @db)
puts "Loaded command: #{const}"
sleep(1.5)
end
end
puts "Commands loaded."
end
def setup_events
def startup_bot
@bot.ready do
puts "#{@bot.profile.username} is online"
@bot.update_status("online", "Checking the economy...", nil, 0, false, 0)

53
src/commands/add.rb Normal file
View File

@@ -0,0 +1,53 @@
# FrugalityBot
# Copyright (C) 2026 Eri (csxkdv/nxkdv) nxkdv@thenight.club
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
require 'i18n'
module Commands
module Add
extend self
def register(bot, db)
command_key = :add
arg_amount_key = :amount
arg_reason_key = :reason
cmd_desc = I18n.t('commands.add.description', locale: :en)
amount_desc = I18n.t('commands.add.args.amount_desc', locale: :en)
reason_desc = I18n.t('commands.add.args.reason_desc', locale: :en)
bot.register_application_command(command_key, cmd_desc, server_id: ENV['TEST_SERVER_ID']) do |cmd|
cmd.integer(arg_amount_key, amount_desc, required: true)
cmd.string(arg_reason_key, reason_desc, required: false)
end
bot.application_command(command_key) do |event|
db_lang = db.get_language(event.user.id)
discord_lang = event.locale.to_s[0..1]
I18n.locale = db_lang || (I18n.available_locales.include?(discord_lang.to_sym) ? discord_lang : :en)
user_id = event.user.id
amount = event.options['amount']
reason = event.options['reason'] || 'income'
db.update_balance(user_id, amount, reason)
msg = I18n.t('responses.add.success', amount: amount, reason: reason, default: "Added #{amount} (Reason: #{reason})")
event.respond(content: msg)
end
end
end
end

View File

@@ -15,13 +15,13 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
module Commands
module Currency
module Balance
extend self
def register(bot, db)
bot.register_application_command(:currency, 'Get your currency', server_id: ENV['TEST_SERVER_ID'])
bot.register_application_command(:balance, 'Get your currency', server_id: ENV['TEST_SERVER_ID'])
bot.application_command(:currency) do |event|
bot.application_command(:balance) do |event|
# 1. Get the User ID from the event
user_id = event.user.id

88
src/commands/statement.rb Normal file
View File

@@ -0,0 +1,88 @@
# FrugalityBot
# Copyright (C) 2026 Eri (csxkdv/nxkdv) nxkdv@thenight.club
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
require 'net/http'
require 'uri'
require 'json'
module Commands
module Statement
extend self
def register(bot, db)
bot.register_application_command(:statement, "Get a report of your incomes and expenses", server_id: ENV['TEST_SERVER_ID']) do |cmd|
cmd.string('period', 'Select time range', required: true, choices: {
'Last Month' => '1 month',
'Last Year' => '1 year'
})
end
bot.application_command(:statement) do |event|
event.defer
user_id = event.user.id
period = event.options['period']
# For income we fetch the data as stats[:income]
# For expenses we fetch the data as stats[:expenses]
# For net income we fetch the data as stats[:net]
stats = db.fetch_report(user_id, period)
chart_config = {
type: 'doughnut',
data: {
labels: ['Income', 'Expenses'],
datasets: [{
data: [stats[:income], stats[:expenses].abs],
backgroundColor: ['#9AF5AA', '#F55D5D'],
borderWidth: 1
}]
},
options: {
plugins: {
doughnutlabel: {
labels: [
{ text: stats[:net].to_s, font: { size: 20}},
{ text: 'Net', font: { size: 10 }}
]
}
}
}
}
encoded_config = URI.encode_www_form_component(chart_config.to_json)
chart_url = "https://quickchart.io/chart?c=#{encoded_config}&w=500&h=300&bkg=rgb(255,255,255)"
color_generated = ("0x" + Random.bytes(3).unpack1('H*')).to_i(16)
embed_generated = {
title: "Financial Statement",
description: "Report generated for **#{event.user.name}** (#{period})",
color: color_generated,
fields: [
{ name: "Income", value: "#{stats[:income]} coins", inline: true },
{ name: "Expenses", value: "#{stats[:expenses].abs} coins", inline: true },
{ name: "Net Change", value: "#{stats[:net]} coins", inline: false }
],
image: { url: chart_url },
footer: { text: "By FrugalityBot with QuickChart." }
}
event.edit_response(embeds: [embed_generated])
end
end
end
end

52
src/commands/subtract.rb Normal file
View File

@@ -0,0 +1,52 @@
# FrugalityBot
# Copyright (C) 2026 Eri (csxkdv/nxkdv) nxkdv@thenight.club
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
module Commands
module Subtract
extend self
def register(bot, db)
bot.register_application_command(:subtract, 'Take money from the wallet', server_id: ENV['TEST_SERVER_ID']) do |cmd|
cmd.integer('amount', "The amount you're spending.", required: true)
cmd.string('reason', "Reason you're spending money. Leave empty for default.", required: false)
end
bot.application_command(:subtract) do |event|
amount = event.options['amount'].to_i
reason = event.options['reason'] ||= 'expense'
if amount <= 0
event.respond(content: "You either have 0, or you can't spend negative money.", ephemeral: true)
next
end
user_id = event.user.id
current_balance = db.get_currency(user_id)
if current_balance < amount
event.respond(content: "You can't buy that, you have **#{current_balance}** coins.", ephemeral: true)
next
end
db.update_balance(user_id, -amount, reason)
new_balance = current_balance - amount
event.respond(content: "You spent **#{amount}** coins.\nReason: #{reason}\nYou now have: #{new_balance}")
end
end
end
end

View File

@@ -17,6 +17,7 @@
module Commands
module Echo
extend self
def register(bot, _db)
bot.register_application_command(:echo, 'Repeats what you say', server_id: ENV['TEST_SERVER_ID']) do |cmd|
cmd.string('message', 'The text you want the bot to repeat', required: true)

View File

@@ -0,0 +1,45 @@
# FrugalityBot
# Copyright (C) 2026 Eri (csxkdv/nxkdv) nxkdv@thenight.club
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
require 'securerandom'
module Commands
module Embed
extend self
def register(bot, _db)
bot.register_application_command(:embed, 'This is an embed testing', server_id: ENV['TEST_SERVER_ID']) do |cmd|
end
bot.application_command(:embed) do |event|
color_generated = ("0x" + Random.bytes(3).unpack1('H*')).to_i(16)
embed_generated = {
title: "Title testing.",
description: "Description testing.",
color: color_generated,
fields: [
{ name: "Field 1", value: "Value for field 1", inline: true },
{ name: "Field 2", value: "Value for field 2", inline: false }
],
image: { url: "https://i.kym-cdn.com/photos/images/original/002/349/700/e38.jpg" },
footer: { text: "Footer testing." }
}
event.respond(embeds: [embed_generated])
end
end
end
end

View File

@@ -19,34 +19,118 @@ require 'pg'
class Database
def initialize
# Connect once when the bot starts
@conn = PG.connect(dbname: 'frugality_database')
@conn = PG.connect(
host: ENV['DB_HOST'] || 'localhost',
dbname: ENV['DB_NAME'] || 'fgbot_db',
user: ENV['DB_USER'] || 'postgres'
)
init_tables
end
def init_tables
sql = <<~SQL
CREATE TABLE IF NOT EXISTS total_money (
sql_wallet = <<~SQL
CREATE TABLE IF NOT EXISTS wallets (
user_id BIGINT PRIMARY KEY,
amount BIGINT DEFAULT 0
);
SQL
@conn.exec(sql)
sql_ledger = <<~SQL
CREATE TABLE IF NOT EXISTS transactions (
id SERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
amount BIGINT NOT NULL,
reason VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
SQL
sql_index = <<~SQL
CREATE INDEX IF NOT EXISTS idx_user_history
ON transactions(user_id, created_at);
SQL
@conn.exec(sql_wallet)
@conn.exec(sql_ledger)
@conn.exec(sql_index)
begin
@conn.exec("ALTER TABLE wallets ADD COLUMN IF NOT EXISTS locale VARCHAR(5) DEFAULT 'en'")
rescue PG::Error => e
puts "Migration note: #{e.message}"
end
puts "Database tables have been initialized."
end
# We pass the user_id
def get_currency(user_id)
# 1. Run the query using parameters ($1) to prevent SQL injection
result = @conn.exec_params("SELECT amount FROM total_money WHERE user_id = $1", [user_id])
# Run the query using parameters ($1) to prevent SQL injection
result = @conn.exec_params("SELECT amount FROM wallets WHERE user_id = $1", [user_id])
# 2. Check if the user exists
if result.num_tuples.zero?
return 0 # User has no money/row yet
else
# 3. Return the value (don't print it)
return result[0]['amount'].to_i
end
end
def update_balance(user_id, amount, reason = "transaction")
@conn.transaction do
@conn.exec_params(
"INSERT INTO transactions (user_id, amount, reason) VALUES ($1, $2, $3)",
[user_id, amount, reason]
)
# We update the user's wallet
sql_update = <<~SQL
INSERT INTO wallets (user_id, amount)
VALUES ($1, $2)
ON CONFLICT (user_id)
DO UPDATE SET amount = wallets.amount + $2
SQL
@conn.exec_params(sql_update, [user_id, amount])
end
end
def fetch_report(user_id, interval_string)
sql = <<~SQL
SELECT
SUM(CASE WHEN amount > 0 THEN amount ELSE 0 END) as income,
SUM(CASE WHEN amount < 0 THEN amount ELSE 0 END) as expenses,
SUM(amount) AS net_change
FROM transactions
WHERE user_id = $1
AND created_at >= NOW() - $2::INTERVAL
SQL
result = @conn.exec_params(sql, [user_id, interval_string])
row = result[0]
{
income: row['income'].to_i,
expenses: row['expenses'].to_i,
net: row['net_change'].to_i
}
end
def get_language(user_id)
result = @conn.exec("SELECT locale FROM wallets WHERE user_id = $1", [user_id])
return nil if result.num_tuples.zero?
return result[0]['locale']
end
def set_language(user_id, locale)
sql = <<~SQL
INSERT INTO wallets(user_id, amount, locale)
VALUES ($1, 0, $2)
ON CONFLICT (user_id)
DO UPDATE SET locale = $2
SQL
@conn.exec(sql, [user_id, locale])
end
end

19
src/locales/en.yml Normal file
View File

@@ -0,0 +1,19 @@
en:
commands:
add:
name: "add"
description: "Add money to the wallet."
args:
amount: "amount"
amount_desc: "How much money you're adding to the wallet."
reason: "reason"
reason_desc: "Reason you're adding money. Leave blank for deafult."
balance:
name: "balance"
description: "Check your wallet."
responses:
add:
success: "Added **%{amount}** coins to the wallet. Reason: **%{reason}**"
balance:
view: "You have **%{balance}** coins."

19
src/locales/es.yml Normal file
View File

@@ -0,0 +1,19 @@
es:
commands:
add:
name: "añadir"
description: "Añade monedas a la billetera."
args:
amount: "cantidad"
amount_desc: "La cantidad de monedas que añades."
reason: "motivo"
reason_desc: "El motivo por el cual añades monedas. Déjalo vacío para default."
balance:
name: "saldo"
description: "Revisa tu billetera."
responses:
add:
success: "Se añadieron **%{amount}** monedas a la billetera. Motivo: **%{reason}**"
balance:
view: "Tienes **%{balance}** monedas."

View File

@@ -0,0 +1,41 @@
# FrugalityBot
# Copyright (C) 2026 Eri (csxkdv/nxkdv) nxkdv@thenight.club
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
require 'i18n'
module LocalesHelper
def self.generate(key_path)
locales_map = {}
discord_map = {
:en => 'en-US',
:es => 'es-ES'
}
I18n.available_locales.each do |lang|
next if lang == :en
text = I18n.t(key_path, locale: lang, default: nil)
if text && text != 'nil'
discord_code = discord_map[lang] || lang.to_s
locales_map[discord_code] = text
end
end
return locales_map
end
end