Finished writing the main function. Detects cheese keywords in messages and added user/server blacklist/whitelist.

This commit is contained in:
2026-01-12 16:05:48 -03:00
parent 903ccf91b2
commit c8e77e1cff
7 changed files with 368 additions and 7 deletions

View File

@@ -7,14 +7,10 @@ Without storing some aspects of your user data, the bot would not be able to run
We collect the following:
* User IDs
* User IDs and Guild IDs
Required for functionality of the blacklist command.
* Guild/Channel ID pairs
Required for the functionality of the announcements and announcements command.
* Messages
Messages are not stored, but they are used for the main functionality of cheeseBot.

View File

@@ -16,18 +16,31 @@
require 'discordrb'
require 'securerandom'
require_relative 'events/message_check'
class CheeseBot
def initialize
puts "Initializing bot..."
@bot = Discordrb::Bot.new(
token: ENV['BOT_TOKEN'],
intents: [:servers, :server_messages]
intents: [:servers, :server_messages],
)
puts "Registering the Message Checker..."
MessageCheck.register(@bot)
puts "Initializing database..."
Database.setup
puts "Loading commands..."
load_commands
puts "Starting bot..."
start_bot
end
def run
@bot.run
end

View File

@@ -0,0 +1,60 @@
# cheeseBot
# 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_relative '../../modules/database'
module Commands
module Blacklist
extend self
def register(bot)
cmd_key = :blacklist
cmd_desc = "Blacklist yourself from the trigger DMs (using the command again will whitelist you.)"
bot.register_application_command(cmd_key, cmd_desc, server_id: ENV['SERVER_ID'])
bot.application_command(cmd_key) do |event|
added = Database.toggle_user_blacklist(event.user.id)
if added
event.respond(content: "You have been added to the blacklist. You will no longer receive DMs.")
else
event.respond(content: "You have been removed from the blacklist. You will now receive DMs.")
end
end
cmd_key_server = :server_blacklist
cmd_desc_server = "Blacklist the server from the trigger DMs (using the command again will whitelist the server.)"
bot.register_application_command(cmd_key_server, cmd_desc_server, server_id: ENV['SERVER_ID'])
bot.application_command(cmd_key_server) do |event|
unless event.user.permission?(:administrator)
event.respond(content: "You're not an admin. You can't use this command.", ephemeral: true)
next
end
added = Database.toggle_server_blacklist(event.server.id)
if added
event.respond(content: "Server has been added to the blacklist. This server will no longer receive DMs.")
else
event.respond(content: "Server has been removed from the blacklist. This server will now receive DMs.")
end
end
end
end
end

View File

@@ -0,0 +1,50 @@
# cheeseBot
# 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_relative '../modules/cheese_checker'
require_relative '../modules/database'
module MessageCheck
def self.register(bot)
bot.message do |event|
next if event.user.bot_account || event.server.nil?
cheese_content = CheeseChecker.check_content(event.content)
next unless cheese_content
event.message.react("🧀")
next if Database.server_blacklisted?(event.server.id)
next if Database.user_blacklisted?(event.user.id)
begin
event.user.pm.send_embed do |embed|
embed.title = "Cheese Detected!"
embed.description = cheese_content
embed.color = rand(0xFFFFFF)
embed.timestamp = Time.now
embed.footer = Discordrb::Webhooks::EmbedFooter.new(
text: "Use /blacklist to not receive DMs anymore"
)
end
rescue Discordrb::Errors::NoPermission
puts "Could not DM user #{event.user.username} (#{event.user.id})"
end
end
end
end

86
src/lists/cheese_words.rb Normal file
View File

@@ -0,0 +1,86 @@
module Lists
CHEESE_WORDS = [
"abertam",
"abondance",
"acapella",
"accasciato",
"ackawi",
"acorn",
"adelost",
"backstein",
"bergader",
"bonifaz",
"brie",
"burrata",
"butterkäse",
"cambozola",
"camembert",
"caseus",
"casgiu",
"cheddar",
"cheese",
"chiiz",
"chisi",
"chizi",
"colby",
"cottage",
"cuku",
"cáis",
"djathë",
"edelpilzkäse",
"farmaajo",
"feta",
"formaggio",
"formatge",
"fromage",
"fromazy",
"fromaĝo",
"fwomaj",
"gazta",
"gorgonzola",
"gouda",
"halloumi",
"handkäse",
"harzer",
"hirtenkäse",
"hohenheim",
"juust",
"juusto",
"kaas",
"kashkaval",
"keju",
"keso",
"kochkäse",
"käse",
"limburger",
"milbenkäse",
"mozzarella",
"nieheimer",
"obatzda",
"ostur",
"paneer",
"parmesan",
"pendir",
"penêr",
"pepperjack",
"provolone",
"quark",
"queijo",
"queixo",
"queso",
"raclette",
"rauchkäse",
"ricotta",
"roquefort",
"sajt",
"sires",
"sisi",
"spundekäs",
"swiss",
"sūris",
"tsiis",
"ziegel",
"チーズ",
"\N{CHEESE WEDGE}"
].freeze
end

View File

@@ -0,0 +1,38 @@
# cheeseBot
# 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_relative '../lists/cheese_words'
module CheeseChecker
WORDS_LIST = Lists::CHEESE_WORDS
PUNCTUATION = "!\"£$%^&*()[]{}'@#~;:,<.>/?-+\\|`¬"
NO_CHEESE = /[\s#{Regexp.escape(PUNCTUATION)}]*/
pattern_strings = WORDS_LIST.map do |word|
Regexp.escape(word).chars.map { |char| char + NO_CHEESE.source }.join
end
CHEESE_REGEX = /((?:#{pattern_strings.join('|')}))/im
def self.check_content(content)
changed_content = content.gsub(CHEESE_REGEX, "**\\1**")
return nil if changed_content == content
changed_content
end
end

118
src/modules/database.rb Normal file
View File

@@ -0,0 +1,118 @@
# cheeseBot
# 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 'pg'
module Database
DB_NAME = ENV['DB_NAME']
DB_USER = ENV['DB_USER']
DB_HOST = ENV['DB_HOST']
DB_PASSWORD = ENV['DB_PASSWORD']
def self.setup
create_database_if_not_exists
create_tables
end
def self.connect(db_name = DB_NAME)
PG.connect(
dbname: db_name,
user: DB_USER,
host: DB_HOST,
password: DB_PASSWORD
)
rescue PG::Error => e
puts "Database connection error: #{e.message}"
exit
end
def self.user_blacklisted?(user_id)
exists?("blacklist", user_id)
end
def self.server_blacklisted?(server_id)
exists?("server_blacklist", server_id)
end
def self.toggle_user_blacklist(user_id)
toggle("blacklist", user_id)
end
def self.toggle_server_blacklist(server_id)
toggle("server_blacklist", server_id)
end
private
def self.exists?(table, id)
conn = connect
result = conn.exec_params("SELECT 1 FROM #{table} WHERE id = $1", [id])
conn.close
!result.ntuples.zero?
end
def self.toggle(table, id)
conn = connect
if exists?(table, id)
conn.exec_params("DELETE FROM #{table} WHERE id = $1", [id])
conn.close
return false
else
conn.exec_params("INSERT INTO #{table} (id) VALUES ($1)", [id])
conn.close
return true
end
end
def self.create_database_if_not_exists
begin
conn = connect('postgres')
rescue PG::Error
puts "Could not connect to 'postgres' system database. Please create '#{DB_NAME}' manually."
return
end
result = conn.exec_params("SELECT 1 FROM pg_database WHERE datname = $1", [DB_NAME])
if result.ntuples.zero?
puts "Database '#{DB_NAME}' not found. Creating it..."
conn.exec("CREATE DATABASE \"#{DB_NAME}\"")
puts "Database '#{DB_NAME}' created successfully!"
end
conn.close
end
def self.create_tables
conn = connect
conn.exec(<<~SQL)
CREATE TABLE IF NOT EXISTS blacklist (
id BIGINT PRIMARY KEY
);
SQL
conn.exec(<<~SQL)
CREATE TABLE IF NOT EXISTS server_blacklist (
id BIGINT PRIMARY KEY
);
SQL
puts "Tables verified."
conn.close
end
end