Compare commits
7 Commits
117cbea67f
...
ab929489b0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab929489b0 | ||
|
|
cf49ac414a | ||
|
|
94374b4d45 | ||
|
|
d18ffd4c11 | ||
|
|
a56c19a466 | ||
|
|
f4886f9fc5 | ||
|
|
e324ee1738 |
@@ -16,13 +16,13 @@ jobs:
|
||||
RUNNER_TOOL_CACHE: /toolcache
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker BuildX
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with: # replace it with your local IP
|
||||
config-inline: |
|
||||
[registry."git.vpn.cusano.net"]
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
insecure = false
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: git.vpn.cusano.net # replace it with your local IP
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
|
||||
@@ -2,25 +2,40 @@ import { DebugBuilder } from "../../modules/debugger.mjs";
|
||||
const log = new DebugBuilder("server", "discordBot.addons.linkCop");
|
||||
import { gptHandler } from "../modules/gptHandler.mjs";
|
||||
import dotenv from "dotenv";
|
||||
import {
|
||||
getGuildConfig,
|
||||
setGuildConfig,
|
||||
} from "../../modules/mongo-wrappers/mongoConfigWrappers.mjs";
|
||||
dotenv.config();
|
||||
|
||||
const approvedLinksChannel = "767303243285790721";
|
||||
const restrictedChannelIds =
|
||||
process.env.LINKCOP_RESTRICTED_CHANNEL_IDS.split(",");
|
||||
|
||||
const linkRegExp =
|
||||
/(?:http[s]?:\/\/)?(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)/g;
|
||||
const linkRegExp = /http[s]?:\/\/\S+/g;
|
||||
|
||||
export const linkCop = async (nodeIo, message) => {
|
||||
// Set the channel IDs based on the guild the message was sent in
|
||||
const approvedLinksChannel =
|
||||
(await getGuildConfig(message.guild.id, "approvedLinksChannel")) ||
|
||||
"767303243285790721";
|
||||
const restrictedChannelIds = await getGuildConfig(
|
||||
message.guild.id,
|
||||
"restrictedChannelIds",
|
||||
);
|
||||
|
||||
// Check if the message was sent in an restricted channel
|
||||
if (
|
||||
message.channel.id == approvedLinksChannel ||
|
||||
!Array.isArray(restrictedChannelIds) ||
|
||||
Array.isArray(restrictedChannelIds) ||
|
||||
!restrictedChannelIds.includes(message.channel.id)
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if there are URLs in the sent message
|
||||
const urls = [...message.content.matchAll(linkRegExp)];
|
||||
log.DEBUG("Parsed URLs from message:", urls);
|
||||
|
||||
const urls = String(message.content).matchAll(linkRegExp);
|
||||
if (!urls || urls.length === 0) return false;
|
||||
log.DEBUG("Found URLs: ", urls);
|
||||
log.INFO("Found URLs: ", urls);
|
||||
|
||||
let conversation = [];
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { RSSController } from "../rss-manager/rssController.mjs";
|
||||
import { join, dirname } from "path";
|
||||
import { readdirSync } from "fs";
|
||||
import { fileURLToPath } from "url";
|
||||
import PresenceManager from "./modules/presenceManager.mjs";
|
||||
|
||||
import dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
@@ -110,6 +111,10 @@ export const serverClient = new Client({
|
||||
serverClient.on("ready", async () => {
|
||||
log.INFO(`Logged in as ${serverClient.user.tag}!`);
|
||||
|
||||
// Set the presence to default
|
||||
const pm = new PresenceManager(serverClient);
|
||||
await pm.resetToDefault();
|
||||
|
||||
// Add and register commands
|
||||
await addEnabledCommands(serverClient);
|
||||
|
||||
|
||||
@@ -4,12 +4,20 @@ import dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
import { Events } from "discord.js";
|
||||
import { gptHandler } from "../modules/gptHandler.mjs";
|
||||
|
||||
const welcomeChannel = process.env.WELCOME_CHANNEL_ID; // TODO - Need to add a DB section for server configs so it's not static to one server
|
||||
import {
|
||||
getGuildConfig,
|
||||
setGuildConfig,
|
||||
getConfig,
|
||||
setConfig,
|
||||
} from "../../modules/mongo-wrappers/mongoConfigWrappers.mjs";
|
||||
|
||||
export const name = Events.GuildMemberAdd;
|
||||
|
||||
export async function execute(nodeIo, member) {
|
||||
const welcomeChannel = await getGuildConfig(
|
||||
message.guild.id,
|
||||
"welcomeChannelId",
|
||||
);
|
||||
log.INFO("New user joined the server", member);
|
||||
let conversation = [];
|
||||
conversation.push({
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { DebugBuilder } from "../../modules/debugger.mjs";
|
||||
const log = new DebugBuilder("server", "discordBot.events.interactionCreate");
|
||||
import { Events } from "discord.js";
|
||||
import PresenceManager from "../modules/presenceManager.mjs";
|
||||
|
||||
export const name = Events.InteractionCreate;
|
||||
|
||||
@@ -8,6 +9,10 @@ export async function execute(nodeIo, interaction) {
|
||||
const command = interaction.client.commands.get(interaction.commandName);
|
||||
log.INFO("Interaction created for command: ", command);
|
||||
|
||||
// Set the presence for handling interaction
|
||||
const interactionPm = new PresenceManager(interaction.client);
|
||||
await interactionPm.setPresence("online", "PLAYING", "handling interaction");
|
||||
|
||||
// Execute autocomplete if the user is checking autocomplete
|
||||
if (interaction.isAutocomplete()) {
|
||||
log.INFO("Running autocomplete for command: ", command.data.name);
|
||||
@@ -33,4 +38,7 @@ export async function execute(nodeIo, interaction) {
|
||||
|
||||
// Execute the command
|
||||
command.execute(nodeIo, interaction);
|
||||
|
||||
// Reset the presence
|
||||
await interactionPm.resetToDefault();
|
||||
}
|
||||
|
||||
@@ -5,25 +5,54 @@ dotenv.config();
|
||||
import { Events } from "discord.js";
|
||||
import { gptInteraction } from "../addons/gptInteraction.mjs";
|
||||
import { linkCop } from "../addons/linkCop.mjs";
|
||||
|
||||
const IGNORED_CHANNELS = process.env.IGNORED_CHANNEL_IDS.split(",");
|
||||
import PresenceManager from "../modules/presenceManager.mjs";
|
||||
import {
|
||||
getGuildConfig,
|
||||
setGuildConfig,
|
||||
} from "../../modules/mongo-wrappers/mongoConfigWrappers.mjs";
|
||||
|
||||
export const name = Events.MessageCreate;
|
||||
|
||||
export async function execute(nodeIo, message) {
|
||||
// Get the ignored channels from the server config
|
||||
const IGNORED_CHANNELS = await getGuildConfig(
|
||||
message.guild.id,
|
||||
"ignoredChannels",
|
||||
);
|
||||
|
||||
// Ignore ignored channels
|
||||
if (IGNORED_CHANNELS.includes(message.channel.id)) return;
|
||||
if (
|
||||
!Array.isArray(IGNORED_CHANNELS) ||
|
||||
(Array.isArray(IGNORED_CHANNELS) &&
|
||||
IGNORED_CHANNELS.includes(message.channel.id))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore messages from a bot
|
||||
if (message.author.bot) return;
|
||||
if (message.author.bot) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.INFO("Message create", message);
|
||||
|
||||
// Set presence for reading message
|
||||
const messagePm = new PresenceManager(message.client);
|
||||
await messagePm.setPresence("online", "WATCHING", "latest messages");
|
||||
|
||||
// Check if the message mentions the bot
|
||||
if (message.mentions.users.has(nodeIo.serverClient.user.id)) {
|
||||
return await gptInteraction(nodeIo, message);
|
||||
const interaction = await gptInteraction(nodeIo, message);
|
||||
|
||||
// Reset the presence
|
||||
await messagePm.resetToDefault();
|
||||
|
||||
return interaction;
|
||||
}
|
||||
|
||||
// Check if the message contains a link in a channel it shouldn't
|
||||
if (await linkCop(nodeIo, message)) return;
|
||||
await linkCop(nodeIo, message);
|
||||
|
||||
// Reset the presence
|
||||
await messagePm.resetToDefault();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { getConfig } from "./configHandler.mjs";
|
||||
import {
|
||||
getConfig,
|
||||
setConfig,
|
||||
} from "../../modules/mongo-wrappers/mongoConfigWrappers.mjs";
|
||||
import { ActivityType, PresenceUpdateStatus } from "discord.js";
|
||||
|
||||
class PresenceManager {
|
||||
/**
|
||||
@@ -7,10 +11,6 @@ class PresenceManager {
|
||||
*/
|
||||
constructor(client) {
|
||||
this.client = client;
|
||||
this.defaultStatus = "online";
|
||||
this.defaultActivityType = "LISTENING";
|
||||
this.defaultActivityName = "for your commands";
|
||||
this.defaultUrl = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -20,9 +20,9 @@ class PresenceManager {
|
||||
* @param {string} activityName - The name of the activity.
|
||||
* @param {string} [url=null] - The URL for STREAMING activity type (optional).
|
||||
*/
|
||||
setPresence(status, activityType, activityName, url = null) {
|
||||
async setPresence(status, activityType, activityName, url = null) {
|
||||
const activityOptions = {
|
||||
type: activityType.toUpperCase(),
|
||||
type: this.convertActivityType(activityType),
|
||||
name: activityName,
|
||||
};
|
||||
|
||||
@@ -30,8 +30,8 @@ class PresenceManager {
|
||||
activityOptions.url = url;
|
||||
}
|
||||
|
||||
this.client.user.setPresence({
|
||||
status: status,
|
||||
await this.client.user.setPresence({
|
||||
status: this.convertStatus(status),
|
||||
activities: [activityOptions],
|
||||
});
|
||||
}
|
||||
@@ -39,12 +39,73 @@ class PresenceManager {
|
||||
/**
|
||||
* Reset the bot's presence to the default state.
|
||||
*/
|
||||
resetToDefault() {
|
||||
const defaultPresence = getConfig("presence");
|
||||
async resetToDefault() {
|
||||
let defaultPresence = await getConfig("presence");
|
||||
|
||||
if (!defaultPresence) {
|
||||
defaultPresence = {
|
||||
status: "idle",
|
||||
activities: [
|
||||
{
|
||||
name: "your commands",
|
||||
type: "LISTENING",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
await setConfig("presence", defaultPresence);
|
||||
}
|
||||
|
||||
console.log("Default Presence:", defaultPresence);
|
||||
|
||||
// Update your bot's presence using this configuration
|
||||
this.client.user.setPresence(defaultPresence);
|
||||
await this.setPresence(
|
||||
defaultPresence.status,
|
||||
defaultPresence.activities[0].type,
|
||||
defaultPresence.activities[0].name,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string activity type to the corresponding ActivityType enum.
|
||||
* @param {string} activityType - The activity type string.
|
||||
* @returns {ActivityType} - The corresponding ActivityType enum.
|
||||
*/
|
||||
convertActivityType(activityType) {
|
||||
switch (activityType.toUpperCase()) {
|
||||
case "PLAYING":
|
||||
return ActivityType.Playing;
|
||||
case "STREAMING":
|
||||
return ActivityType.Streaming;
|
||||
case "LISTENING":
|
||||
return ActivityType.Listening;
|
||||
case "WATCHING":
|
||||
return ActivityType.Watching;
|
||||
case "COMPETING":
|
||||
return ActivityType.Competing;
|
||||
default:
|
||||
throw new Error("Invalid activity type");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string status to the corresponding PresenceUpdateStatus enum.
|
||||
* @param {string} status - The status string.
|
||||
* @returns {PresenceUpdateStatus} - The corresponding PresenceUpdateStatus enum.
|
||||
*/
|
||||
convertStatus(status) {
|
||||
switch (status.toLowerCase()) {
|
||||
case "online":
|
||||
return PresenceUpdateStatus.Online;
|
||||
case "idle":
|
||||
return PresenceUpdateStatus.Idle;
|
||||
case "dnd":
|
||||
return PresenceUpdateStatus.DoNotDisturb;
|
||||
case "invisible":
|
||||
return PresenceUpdateStatus.Invisible;
|
||||
default:
|
||||
throw new Error("Invalid status");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { FlatCompat } from "@eslint/eslintrc";
|
||||
import mjs from "@eslint/js";
|
||||
import prettierConfig from "eslint-config-prettier";
|
||||
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
|
||||
import unusedImports from "eslint-plugin-unused-imports";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
@@ -15,13 +16,25 @@ const compat = new FlatCompat({
|
||||
export default [
|
||||
...compat.extends().map((config) => ({
|
||||
...config,
|
||||
plugins: {
|
||||
"unused-imports": unusedImports,
|
||||
},
|
||||
files: ["**/*.mjs", "**/*.js", "**/*.cjs"],
|
||||
rules: {
|
||||
...config.rules,
|
||||
// ...other your custom rules
|
||||
"no-console": "warn",
|
||||
"no-unused-vars": "warn",
|
||||
"no-unused-vars": "off", // or "@typescript-eslint/no-unused-vars": "off",
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"unused-imports/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
vars: "all",
|
||||
varsIgnorePattern: "^_",
|
||||
args: "after-used",
|
||||
argsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
},
|
||||
})),
|
||||
prettierConfig, // Turns off all ESLint rules that have the potential to interfere with Prettier rules.
|
||||
|
||||
113
modules/mongo-wrappers/mongoConfigWrappers.mjs
Normal file
113
modules/mongo-wrappers/mongoConfigWrappers.mjs
Normal file
@@ -0,0 +1,113 @@
|
||||
import {
|
||||
getDocumentByField,
|
||||
deleteDocumentByField,
|
||||
getDocumentByFields,
|
||||
upsertDocumentByField,
|
||||
deleteDocumentByFields,
|
||||
upsertDocumentByFields,
|
||||
} from "./mongoHandler.mjs"; // Import your MongoDB handlers
|
||||
import { DebugBuilder } from "../debugger.mjs";
|
||||
|
||||
const log = new DebugBuilder("server", "mongoConfigWrappers");
|
||||
|
||||
const collectionName = "configurations";
|
||||
|
||||
// Function to get a configuration by key
|
||||
export const getConfig = async (key) => {
|
||||
try {
|
||||
const config = await getDocumentByField(collectionName, "key", key);
|
||||
log.DEBUG(`Configuration for key "${key}" retrieved:`, config);
|
||||
return config ? config[key] : null; // Return null if no configuration is found
|
||||
} catch (error) {
|
||||
log.ERROR("Error retrieving configuration:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Function to set a configuration by key
|
||||
export const setConfig = async (key, value) => {
|
||||
// Set the config object
|
||||
value = { key: value };
|
||||
try {
|
||||
const result = await upsertDocumentByField(
|
||||
collectionName,
|
||||
"key",
|
||||
key,
|
||||
value,
|
||||
);
|
||||
log.DEBUG(`Configuration for key "${key}" set:`, value, result);
|
||||
return result > 0 ? key : null; // Return key if updated successfully, otherwise null
|
||||
} catch (error) {
|
||||
log.ERROR("Error setting configuration:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Function to delete a configuration by key (optional)
|
||||
export const deleteConfig = async (key) => {
|
||||
try {
|
||||
const result = await deleteDocumentByField(collectionName, "key", key);
|
||||
log.DEBUG(`Configuration for key "${key}" deleted:`, result);
|
||||
return result; // Return the count of deleted documents
|
||||
} catch (error) {
|
||||
log.ERROR("Error deleting configuration:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Function to get a configuration by key for a specific guild
|
||||
export const getGuildConfig = async (guildId, key) => {
|
||||
try {
|
||||
const config = await getDocumentByFields(
|
||||
collectionName,
|
||||
["guildId", guildId],
|
||||
["key", key],
|
||||
);
|
||||
log.DEBUG(
|
||||
`Guild ${guildId} configuration for key "${key}" retrieved:`,
|
||||
config,
|
||||
);
|
||||
return config ? config[key] : null; // Return null if no configuration is found
|
||||
} catch (error) {
|
||||
log.ERROR("Error retrieving guild configuration:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Function to set a configuration by key for a specific guild
|
||||
export const setGuildConfig = async (guildId, key, value) => {
|
||||
// Set the config object
|
||||
value = { key: value };
|
||||
try {
|
||||
const result = await upsertDocumentByFields(
|
||||
collectionName,
|
||||
value,
|
||||
["guildId", guildId],
|
||||
["key", key],
|
||||
);
|
||||
log.DEBUG(`Guild ${guildId} configuration for key "${key}" set:`, value);
|
||||
return result > 0 ? key : null; // Return key if updated successfully, otherwise null
|
||||
} catch (error) {
|
||||
log.ERROR("Error setting guild configuration:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Function to delete a configuration by key for a specific guild (optional)
|
||||
export const deleteGuildConfig = async (guildId, key) => {
|
||||
try {
|
||||
const result = await deleteDocumentByFields(
|
||||
collectionName,
|
||||
["guildId", guildId],
|
||||
["key", key],
|
||||
);
|
||||
log.DEBUG(
|
||||
`Guild ${guildId} configuration for key "${key}" deleted:`,
|
||||
result,
|
||||
);
|
||||
return result; // Return the count of deleted documents
|
||||
} catch (error) {
|
||||
log.ERROR("Error deleting guild configuration:", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
@@ -59,10 +59,26 @@ export const getDocuments = async (collectionName) => {
|
||||
// Function to retrieve a document by a specific field
|
||||
export const getDocumentByField = async (collectionName, field, value) => {
|
||||
log.DEBUG("Getting document by field:", collectionName, field, value);
|
||||
return await getDocumentByFields(collectionName, [field, value]);
|
||||
};
|
||||
|
||||
// Function to retrieve a document by multiple fields
|
||||
export const getDocumentByFields = async (
|
||||
collectionName,
|
||||
...fieldValuePairs
|
||||
) => {
|
||||
log.DEBUG("Getting document by fields:", collectionName, fieldValuePairs);
|
||||
const db = await connectToDatabase();
|
||||
try {
|
||||
const collection = db.db().collection(collectionName);
|
||||
const document = await collection.findOne({ [field]: value });
|
||||
|
||||
// Convert the fieldValuePairs array into an object
|
||||
const query = fieldValuePairs.reduce((acc, [field, value]) => {
|
||||
acc[field] = value;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const document = await collection.findOne(query);
|
||||
return document;
|
||||
} catch (error) {
|
||||
console.error("Error retrieving document:", error);
|
||||
@@ -72,12 +88,55 @@ export const getDocumentByField = async (collectionName, field, value) => {
|
||||
}
|
||||
};
|
||||
|
||||
// Function to update a document by a specific field
|
||||
export const upsertDocumentByField = async (
|
||||
collectionName,
|
||||
field,
|
||||
value,
|
||||
updatedFields,
|
||||
) => {
|
||||
log.DEBUG(
|
||||
"Upsert document by field:",
|
||||
collectionName,
|
||||
field,
|
||||
value,
|
||||
updatedFields,
|
||||
);
|
||||
return await updateDocumentByFields(
|
||||
collectionName,
|
||||
updatedFields,
|
||||
{ upsert: true },
|
||||
[field, value],
|
||||
);
|
||||
};
|
||||
|
||||
// Function to update a document by a specific field
|
||||
export const upsertDocumentByFields = async (
|
||||
collectionName,
|
||||
updatedFields,
|
||||
...fieldValuePairs
|
||||
) => {
|
||||
log.DEBUG(
|
||||
"Upsert document by fields:",
|
||||
collectionName,
|
||||
updatedFields,
|
||||
fieldValuePairs,
|
||||
);
|
||||
return await updateDocumentByFields(
|
||||
collectionName,
|
||||
updatedFields,
|
||||
{ upsert: true },
|
||||
fieldValuePairs,
|
||||
);
|
||||
};
|
||||
|
||||
// Function to update a document by a specific field
|
||||
export const updateDocumentByField = async (
|
||||
collectionName,
|
||||
field,
|
||||
value,
|
||||
updatedFields,
|
||||
options = null,
|
||||
) => {
|
||||
log.DEBUG(
|
||||
"Update document by field:",
|
||||
@@ -85,13 +144,42 @@ export const updateDocumentByField = async (
|
||||
field,
|
||||
value,
|
||||
updatedFields,
|
||||
options,
|
||||
);
|
||||
return await updateDocumentByFields(collectionName, updatedFields, options, [
|
||||
field,
|
||||
value,
|
||||
]);
|
||||
};
|
||||
|
||||
// Function to update a document by multiple fields
|
||||
export const updateDocumentByFields = async (
|
||||
collectionName,
|
||||
updatedFields,
|
||||
options,
|
||||
...fieldValuePairs
|
||||
) => {
|
||||
log.DEBUG(
|
||||
"Update document by fields:",
|
||||
collectionName,
|
||||
updatedFields,
|
||||
options,
|
||||
fieldValuePairs,
|
||||
);
|
||||
const db = await connectToDatabase();
|
||||
try {
|
||||
const collection = db.db().collection(collectionName);
|
||||
|
||||
// Convert the fieldValuePairs array into an object
|
||||
const query = fieldValuePairs.reduce((acc, [field, value]) => {
|
||||
acc[field] = value;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const result = await collection.updateOne(
|
||||
{ [field]: value },
|
||||
query,
|
||||
{ $set: updatedFields },
|
||||
options,
|
||||
);
|
||||
log.DEBUG("Document updated:", result.modifiedCount);
|
||||
return result.modifiedCount;
|
||||
@@ -106,10 +194,26 @@ export const updateDocumentByField = async (
|
||||
// Function to delete a document by a specific field
|
||||
export const deleteDocumentByField = async (collectionName, field, value) => {
|
||||
log.DEBUG("Delete document by field:", collectionName, field, value);
|
||||
return await deleteDocumentByFields(collectionName, [field, value]);
|
||||
};
|
||||
|
||||
// Function to delete a document by multiple fields
|
||||
export const deleteDocumentByFields = async (
|
||||
collectionName,
|
||||
...fieldValuePairs
|
||||
) => {
|
||||
log.DEBUG("Delete document by fields:", collectionName, fieldValuePairs);
|
||||
const db = await connectToDatabase();
|
||||
try {
|
||||
const collection = db.db().collection(collectionName);
|
||||
const result = await collection.deleteOne({ [field]: value });
|
||||
|
||||
// Convert the fieldValuePairs array into an object
|
||||
const query = fieldValuePairs.reduce((acc, [field, value]) => {
|
||||
acc[field] = value;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const result = await collection.deleteOne(query);
|
||||
log.DEBUG("Document deleted:", result.deletedCount);
|
||||
return result.deletedCount;
|
||||
} catch (error) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import { DebugBuilder } from "../modules/debugger.mjs";
|
||||
import { removeSource } from "./sourceManager.mjs";
|
||||
import UserAgent from "user-agents";
|
||||
import Parser from "rss-parser";
|
||||
import PresenceManager from "../discordBot/modules/presenceManager.mjs";
|
||||
|
||||
import dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
@@ -41,6 +42,10 @@ export const returnHash = (...stringsIncluded) => {
|
||||
export const updateFeeds = async (client) => {
|
||||
if (!client) throw new Error("Client object not passed");
|
||||
|
||||
// Setup presence manager
|
||||
const feedPm = new PresenceManager(client);
|
||||
await feedPm.setPresence("online", "WATCHING", "for RSS feed updates");
|
||||
|
||||
try {
|
||||
const records = await getAllFeeds();
|
||||
|
||||
@@ -106,6 +111,7 @@ export const updateFeeds = async (client) => {
|
||||
|
||||
await Promise.all(sourcePromiseArray);
|
||||
log.DEBUG("All sources processed");
|
||||
await feedPm.resetToDefault();
|
||||
} catch (error) {
|
||||
log.ERROR("Error updating feeds:", error);
|
||||
throw error;
|
||||
|
||||
Reference in New Issue
Block a user