@spatulox/simplediscordbot 1.7.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -5248,7 +5248,7 @@ var InternetChecker = class {
5248
5248
  tries > 0 ? `Ping failed (${errorMsg}) - Attempt ${attempt}/${tries}` : `Ping failed (${errorMsg}) - Retrying in ${this.RETRY_TIME.toSeconds()} seconds...`
5249
5249
  );
5250
5250
  try {
5251
- await new Promise((resolve) => setTimeout(resolve, this.RETRY_TIME.toMilliseconds()));
5251
+ await new Promise((resolve2) => setTimeout(resolve2, this.RETRY_TIME.toMilliseconds()));
5252
5252
  } catch {
5253
5253
  Log.error("Retry delay failed.");
5254
5254
  }
@@ -5418,31 +5418,85 @@ var _BotLog = class _BotLog {
5418
5418
  Log.warn("Client not ready for Discord logging init");
5419
5419
  return;
5420
5420
  }
5421
- if (Bot.config.log?.logChannelId) {
5422
- try {
5423
- const logCh = await Bot.client.channels.fetch(Bot.config.log.logChannelId);
5424
- if (logCh?.isTextBased()) {
5425
- _BotLog.logChannel = logCh;
5426
- } else {
5427
- Log.warn(`Log channel ${Bot.config.log.logChannelId} invalid`);
5428
- }
5429
- } catch (error) {
5430
- Log.error(`Log channel fetch failed: ${error}`);
5431
- }
5432
- }
5433
- if (Bot.config.log?.errorChannelId) {
5421
+ const logTypes = [
5422
+ { config: "info", prop: "logChannel" },
5423
+ { config: "warn", prop: "warnChannel" },
5424
+ { config: "error", prop: "errorChannel" },
5425
+ { config: "debug", prop: "debugChannel" }
5426
+ ];
5427
+ for (const { config, prop } of logTypes) {
5428
+ const channelId = Bot.config.log?.[config]?.channelId;
5429
+ if (!channelId) continue;
5434
5430
  try {
5435
- const errorCh = await Bot.client.channels.fetch(Bot.config.log.errorChannelId);
5436
- if (errorCh?.isTextBased()) {
5437
- _BotLog.errorChannel = errorCh;
5431
+ const channel = await Bot.client.channels.fetch(channelId);
5432
+ if (channel?.isTextBased()) {
5433
+ _BotLog[prop] = channel;
5438
5434
  } else {
5439
- Log.warn(`Error channel ${Bot.config.log.errorChannelId} invalid`);
5435
+ Log.warn(`${config.charAt(0).toUpperCase() + config.slice(1)} channel ${channelId} invalid`);
5440
5436
  }
5441
5437
  } catch (error) {
5442
- Log.error(`Error channel fetch failed: ${error}`);
5438
+ Log.error(`${config.charAt(0).toUpperCase() + config.slice(1)} channel fetch failed: ${error}`);
5443
5439
  }
5444
5440
  }
5445
5441
  }
5442
+ /*public static async initDiscordLogging(): Promise<void> {
5443
+ if (!Bot.client.isReady()) {
5444
+ Log.warn('Client not ready for Discord logging init');
5445
+ return;
5446
+ }
5447
+
5448
+ if (Bot.config.log?.info.channelId) {
5449
+ try {
5450
+ const logCh = await Bot.client.channels.fetch(Bot.config.log.info.channelId) as TextChannel;
5451
+ if (logCh?.isTextBased()) {
5452
+ BotLog.logChannel = logCh;
5453
+ } else {
5454
+ Log.warn(`Log channel ${Bot.config.log.info.channelId} invalid`);
5455
+ }
5456
+ } catch (error) {
5457
+ Log.error(`Log channel fetch failed: ${error}`);
5458
+ }
5459
+ }
5460
+
5461
+ if (Bot.config.log?.warn.channelId) {
5462
+ try {
5463
+ const errorCh = await Bot.client.channels.fetch(Bot.config.log.warn.channelId) as TextChannel;
5464
+ if (errorCh?.isTextBased()) {
5465
+ BotLog.warnChannel = errorCh;
5466
+ } else {
5467
+ Log.warn(`Warn channel ${Bot.config.log.warn.channelId} invalid`);
5468
+ }
5469
+ } catch (error) {
5470
+ Log.error(`Warn channel fetch failed: ${error}`);
5471
+ }
5472
+ }
5473
+
5474
+ if (Bot.config.log?.error.channelId) {
5475
+ try {
5476
+ const errorCh = await Bot.client.channels.fetch(Bot.config.log.error.channelId) as TextChannel;
5477
+ if (errorCh?.isTextBased()) {
5478
+ BotLog.errorChannel = errorCh;
5479
+ } else {
5480
+ Log.warn(`Error channel ${Bot.config.log.error.channelId} invalid`);
5481
+ }
5482
+ } catch (error) {
5483
+ Log.error(`Error channel fetch failed: ${error}`);
5484
+ }
5485
+ }
5486
+
5487
+ if (Bot.config.log?.debug.channelId) {
5488
+ try {
5489
+ const errorCh = await Bot.client.channels.fetch(Bot.config.log.debug.channelId) as TextChannel;
5490
+ if (errorCh?.isTextBased()) {
5491
+ BotLog.debugChannel = errorCh;
5492
+ } else {
5493
+ Log.warn(`Debug channel ${Bot.config.log.debug.channelId} invalid`);
5494
+ }
5495
+ } catch (error) {
5496
+ Log.error(`Debug channel fetch failed: ${error}`);
5497
+ }
5498
+ }
5499
+ }*/
5446
5500
  /**
5447
5501
  * Send content to specific Discord channel
5448
5502
  */
@@ -5509,8 +5563,8 @@ var _BotLog = class _BotLog {
5509
5563
  Log.warn(content);
5510
5564
  }
5511
5565
  }
5512
- if (logConfig?.warn.discord && this.logChannel) {
5513
- return await this._sendToChannel(this.logChannel, content, "warn");
5566
+ if (logConfig?.warn.discord && this.warnChannel) {
5567
+ return await this._sendToChannel(this.warnChannel, content, "warn");
5514
5568
  }
5515
5569
  }
5516
5570
  /**
@@ -5523,12 +5577,14 @@ var _BotLog = class _BotLog {
5523
5577
  Log.debug(content);
5524
5578
  }
5525
5579
  }
5526
- if (logConfig?.debug.discord && this.logChannel) {
5527
- return await this._sendToChannel(this.logChannel, content, "debug");
5580
+ if (logConfig?.debug.discord && this.debugChannel) {
5581
+ return await this._sendToChannel(this.debugChannel, content, "debug");
5528
5582
  }
5529
5583
  }
5530
5584
  };
5531
5585
  _BotLog.logChannel = null;
5586
+ _BotLog.warnChannel = null;
5587
+ _BotLog.debugChannel = null;
5532
5588
  _BotLog.errorChannel = null;
5533
5589
  var BotLog = _BotLog;
5534
5590
 
@@ -5647,8 +5703,8 @@ var EmbedManager = class {
5647
5703
  /**
5648
5704
  * Quick field adder
5649
5705
  */
5650
- static field(embed, name, value, inline = false) {
5651
- return embed.addFields({ name, value, inline });
5706
+ static field(embed, field) {
5707
+ return embed.addFields({ name: field.name, value: field.value, inline: field.inline ?? false });
5652
5708
  }
5653
5709
  static fields(embed, fields) {
5654
5710
  fields.forEach((f3) => {
@@ -14309,7 +14365,7 @@ var _Bot = class _Bot {
14309
14365
  Log.error(`Connection error : ${error}. Trying again...`);
14310
14366
  tries++;
14311
14367
  await new Promise(
14312
- (resolve) => setTimeout(resolve, Time.second.SEC_03.toMilliseconds())
14368
+ (resolve2) => setTimeout(resolve2, Time.second.SEC_03.toMilliseconds())
14313
14369
  );
14314
14370
  }
14315
14371
  }
@@ -14472,88 +14528,104 @@ var FileManager = class {
14472
14528
 
14473
14529
  // src/manager/messages/WebhookManager.ts
14474
14530
  import {
14475
- ThreadChannel as ThreadChannel2
14531
+ TextChannel as TextChannel3
14476
14532
  } from "discord.js";
14533
+ import { readFile } from "fs/promises";
14534
+ import { resolve } from "path";
14477
14535
  var WebhookManager = class {
14478
- constructor(channel, name = Bot.config.botName || "", avatarURL) {
14479
- this.channel = channel;
14536
+ constructor(client, name, avatarPathOrUrl) {
14537
+ this.client = client;
14480
14538
  this.name = name;
14481
- this.avatarURL = avatarURL;
14539
+ this.avatarPathOrUrl = avatarPathOrUrl;
14482
14540
  this.webhook = null;
14483
14541
  }
14484
- get textChannel() {
14485
- return this.channel instanceof ThreadChannel2 ? this.channel.parent : this.channel;
14542
+ async getAvatar() {
14543
+ if (!this.avatarPathOrUrl) return null;
14544
+ if (this.avatarPathOrUrl.startsWith("http://") || this.avatarPathOrUrl.startsWith("https://")) {
14545
+ return this.avatarPathOrUrl;
14546
+ }
14547
+ try {
14548
+ const resolvedPath = resolve(process.cwd(), this.avatarPathOrUrl);
14549
+ return await readFile(resolvedPath);
14550
+ } catch (error) {
14551
+ Bot.log.warn(`Failed to load avatar from ${this.avatarPathOrUrl}: ${error}`);
14552
+ return null;
14553
+ }
14554
+ }
14555
+ /**
14556
+ * Récupère le channel à partir de l'ID ou utilise directement si TextChannel/ThreadChannel
14557
+ */
14558
+ async getTextChannel(channelId) {
14559
+ const channel = await this.client.channels.fetch(channelId);
14560
+ if (!channel || !(channel instanceof TextChannel3)) {
14561
+ throw new Error(`Channel ${channelId} is not a TextChannel`);
14562
+ }
14563
+ return channel;
14486
14564
  }
14487
14565
  /**
14488
14566
  * Get or create webhook (lazy initialization)
14489
14567
  */
14490
- async getWebhook() {
14568
+ async getWebhook(channelId) {
14491
14569
  if (this.webhook) return this.webhook;
14492
14570
  try {
14493
- const webhooks = await this.textChannel.fetchWebhooks();
14494
- this.webhook = webhooks.find((h3) => h3.name === this.name && h3.owner?.id == Bot.client.user?.id) ?? await this.textChannel.createWebhook({
14571
+ const textChannel = await this.getTextChannel(channelId);
14572
+ const webhooks = await textChannel.fetchWebhooks();
14573
+ this.webhook = webhooks.find((h3) => h3.name === this.name && h3.owner?.id == this.client.user?.id) ?? await textChannel.createWebhook({
14495
14574
  name: this.name,
14496
- avatar: this.avatarURL,
14575
+ avatar: await this.getAvatar(),
14497
14576
  reason: "Auto-created by WebhookManager"
14498
14577
  });
14499
- Log.info(`Webhook ${this.webhook.id} ready for ${this.textChannel.id}`);
14578
+ Bot.log.debug(`Webhook ${this.webhook.id} ready for channel ${channelId}`);
14500
14579
  return this.webhook;
14501
14580
  } catch (error) {
14502
- Log.error(`Failed to setup webhook: ${error}`);
14581
+ Bot.log.error(`Failed to setup webhook for ${channelId}: ${error}`);
14503
14582
  throw error;
14504
14583
  }
14505
14584
  }
14506
- async send(content) {
14507
- const webhook = await this.getWebhook();
14508
- const options = {};
14585
+ async send(channelId, content) {
14586
+ const webhook = await this.getWebhook(channelId);
14587
+ let options = {};
14509
14588
  if (SendableComponentBuilder.isSendableComponent(content)) {
14510
- const t3 = SendableComponentBuilder.buildMessage(content);
14511
- options.embeds = t3.embeds;
14512
- options.components = t3.components;
14513
- } else if (typeof content == "string") {
14589
+ options = SendableComponentBuilder.buildMessage(content);
14590
+ } else if (typeof content === "string") {
14514
14591
  options.content = content;
14515
14592
  } else if (typeof content === "object") {
14516
14593
  Object.assign(options, content);
14517
14594
  } else {
14518
- options.content = content;
14519
- }
14520
- if (this.channel instanceof ThreadChannel2) {
14521
- options.threadId = this.channel.id;
14595
+ options.content = String(content);
14522
14596
  }
14523
14597
  try {
14524
- const message = await webhook.send(options);
14525
- Log.info(`Webhook sent to ${this.channel.id}: ${content}`);
14526
- return message;
14598
+ return await webhook.send(options);
14527
14599
  } catch (error) {
14528
- Log.error(`Webhook send failed ${this.channel.id}: ${error}`);
14600
+ Bot.log.error(`Webhook send failed to ${channelId}: ${error}`);
14529
14601
  return null;
14530
14602
  }
14531
14603
  }
14532
14604
  /**
14533
14605
  * Quick success embed
14534
14606
  */
14535
- async success(message) {
14536
- return await this.send(EmbedManager.success(message));
14607
+ async success(channelId, message) {
14608
+ return await this.send(channelId, EmbedManager.success(message));
14537
14609
  }
14538
14610
  /**
14539
14611
  * Quick error embed
14540
14612
  */
14541
- async error(message) {
14542
- return await this.send(EmbedManager.error(message));
14613
+ async error(channelId, message) {
14614
+ return await this.send(channelId, EmbedManager.error(message));
14543
14615
  }
14544
14616
  /**
14545
14617
  * Delete webhook
14546
14618
  */
14547
- async delete(reason) {
14619
+ async delete(channelId, reason) {
14548
14620
  if (!this.webhook) return;
14549
14621
  try {
14550
14622
  await this.webhook.delete(reason ?? "Deleted by WebhookManager");
14551
- Log.info(`Webhook ${this.webhook.id} deleted`);
14623
+ Bot.log.info(`Webhook ${this.webhook.id} deleted from ${channelId}`);
14552
14624
  } catch (error) {
14553
14625
  if (error.message.includes("Unknown Webhook")) {
14554
- Log.warn("Webhook already deleted");
14626
+ Bot.log.warn(`Webhook already deleted from ${channelId}`);
14555
14627
  } else {
14556
- Log.error(`Failed to delete webhook: ${error}`);
14628
+ Bot.log.error(`Failed to delete webhook from ${channelId}: ${error}`);
14557
14629
  }
14558
14630
  } finally {
14559
14631
  this.webhook = null;
@@ -14859,11 +14931,7 @@ var ReactionManager = class {
14859
14931
  };
14860
14932
 
14861
14933
  // src/manager/guild/GuildManager.ts
14862
- import {
14863
- Guild as Guild3,
14864
- VoiceChannel as VoiceChannel2,
14865
- StageChannel as StageChannel2
14866
- } from "discord.js";
14934
+ import { Guild as Guild2, StageChannel as StageChannel2, VoiceChannel as VoiceChannel2 } from "discord.js";
14867
14935
 
14868
14936
  // src/manager/direct/BasicUserManager.ts
14869
14937
  import { GuildMember as GuildMember2 } from "discord.js";
@@ -14938,22 +15006,9 @@ var BasicUserManager = class {
14938
15006
  };
14939
15007
 
14940
15008
  // src/manager/guild/GuildUserManager.ts
14941
- import { Guild as Guild2 } from "discord.js";
14942
15009
  import { setTimeout as setTimeout2 } from "timers/promises";
14943
15010
  var MAX_NICKNAME_LENGTH = 32;
14944
15011
  var GuildUserManager = class extends BasicUserManager {
14945
- static async find(userId, guild) {
14946
- try {
14947
- if (guild instanceof Guild2) {
14948
- return await guild.members.fetch(userId);
14949
- } else {
14950
- return await (await GuildManager.find(guild)).members.fetch(userId);
14951
- }
14952
- } catch (error) {
14953
- Log.error(`UserManager: Member ${userId} not found`);
14954
- return null;
14955
- }
14956
- }
14957
15012
  static async rename(member, nickname, maxAttempts = 3) {
14958
15013
  if (nickname.length > MAX_NICKNAME_LENGTH) {
14959
15014
  nickname = nickname.slice(0, MAX_NICKNAME_LENGTH);
@@ -15470,7 +15525,14 @@ var GuildManager = class {
15470
15525
  return Array.from(Bot.client.guilds.cache.values());
15471
15526
  }
15472
15527
  static async find(guild_id) {
15473
- return await Bot.client.guilds.fetch(guild_id);
15528
+ try {
15529
+ const cached = Bot.client.guilds.cache.get(guild_id);
15530
+ if (cached) return cached;
15531
+ return await Bot.client.guilds.fetch(guild_id);
15532
+ } catch (error) {
15533
+ Log.error(`GuildManager: Guild ${guild_id} : ${error} `);
15534
+ return null;
15535
+ }
15474
15536
  }
15475
15537
  /**
15476
15538
  * Search channel by ID (TextChannel, DMChannel, ThreadChannel)
@@ -15509,7 +15571,7 @@ var GuildManager = class {
15509
15571
  */
15510
15572
  static async fetchAllMembers(guildId, MAX_ATTEMPTS = 3, RETRY_DELAY = Time.minute.MIN_05.toMilliseconds()) {
15511
15573
  let guild;
15512
- if (guildId instanceof Guild3) {
15574
+ if (guildId instanceof Guild2) {
15513
15575
  guild = guildId;
15514
15576
  } else {
15515
15577
  let tmp = Bot.client.guilds.cache.get(guildId);
@@ -16061,8 +16123,8 @@ var SimpleMutex = class {
16061
16123
  */
16062
16124
  async lock() {
16063
16125
  if (this._locked) {
16064
- return new Promise((resolve) => {
16065
- this.queue.push(resolve);
16126
+ return new Promise((resolve2) => {
16127
+ this.queue.push(resolve2);
16066
16128
  });
16067
16129
  }
16068
16130
  this._locked = true;
@@ -16089,7 +16151,7 @@ var SimpleMutex = class {
16089
16151
  // package.json
16090
16152
  var package_default = {
16091
16153
  name: "@spatulox/simplediscordbot",
16092
- version: "1.7.0",
16154
+ version: "2.0.0",
16093
16155
  author: "Spatulox",
16094
16156
  description: "Simple discord bot framework to set up a bot under 30 secondes",
16095
16157
  exports: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spatulox/simplediscordbot",
3
- "version": "1.7.1",
3
+ "version": "2.0.1",
4
4
  "author": "Spatulox",
5
5
  "description": "Simple discord bot framework to set up a bot under 30 secondes",
6
6
  "exports": {