beniocord.js 2.0.4 → 2.0.5

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/Client.js CHANGED
@@ -194,11 +194,13 @@ class Client extends EventEmitter {
194
194
  this.isConnected = true;
195
195
  this.retryCount = 0;
196
196
  this._setupSocketHandlers();
197
+ this._startHeartbeat(); // Inicia o heartbeat
197
198
  resolve();
198
199
  });
199
200
 
200
201
  this.socket.on("disconnect", (reason) => {
201
202
  this.isConnected = false;
203
+ this._stopHeartbeat(); // Para o heartbeat
202
204
  this.emit("disconnect", reason);
203
205
 
204
206
  if (reason === "io server disconnect") {
@@ -239,6 +241,7 @@ class Client extends EventEmitter {
239
241
 
240
242
  this.socket.on("reconnect", (attemptNumber) => {
241
243
  this.isConnected = true;
244
+ this._startHeartbeat(); // Reinicia o heartbeat após reconexão
242
245
  this.emit("reconnect", attemptNumber);
243
246
  });
244
247
 
@@ -247,6 +250,7 @@ class Client extends EventEmitter {
247
250
  });
248
251
 
249
252
  this.socket.on("reconnect_failed", () => {
253
+ this._stopHeartbeat();
250
254
  this.emit("error", new ClientError(
251
255
  "Failed to reconnect after maximum attempts",
252
256
  "RECONNECT_FAILED"
@@ -255,6 +259,88 @@ class Client extends EventEmitter {
255
259
  });
256
260
  }
257
261
 
262
+ /**
263
+ * Inicia o sistema de heartbeat
264
+ * @private
265
+ */
266
+ _startHeartbeat() {
267
+ // Para qualquer heartbeat existente
268
+ this._stopHeartbeat();
269
+
270
+ // Intervalo de 30 segundos (mesmo do frontend)
271
+ const HEARTBEAT_INTERVAL = 30000;
272
+
273
+ this.heartbeatInterval = setInterval(() => {
274
+ if (this.socket && this.isConnected) {
275
+ // Envia heartbeat simples para bots
276
+ // Bots não precisam de isPageVisible/isAppFocused
277
+ this.socket.emit("presence:heartbeat", {
278
+ status: this.status || "online",
279
+ clientType: "bot" // Identifica como bot
280
+ });
281
+ }
282
+ }, HEARTBEAT_INTERVAL);
283
+
284
+ // Envia primeiro heartbeat imediatamente
285
+ if (this.socket && this.isConnected) {
286
+ this.socket.emit("presence:heartbeat", {
287
+ status: this.status || "online",
288
+ clientType: "bot"
289
+ });
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Para o sistema de heartbeat
295
+ * @private
296
+ */
297
+ _stopHeartbeat() {
298
+ if (this.heartbeatInterval) {
299
+ clearInterval(this.heartbeatInterval);
300
+ this.heartbeatInterval = null;
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Define o status do bot (se o servidor suportar)
306
+ * @param {string} status - Status: "online", "away", "dnd", "offline"
307
+ */
308
+ setStatus(status) {
309
+ if (!["online", "away", "dnd", "offline"].includes(status)) {
310
+ throw new ClientError("Invalid status", "INVALID_STATUS");
311
+ }
312
+
313
+ this.status = status;
314
+
315
+ if (this.socket && this.isConnected) {
316
+ this.socket.emit("status:update", { status });
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Desconecta o cliente e limpa recursos
322
+ */
323
+ disconnect() {
324
+ this._stopHeartbeat();
325
+
326
+ if (this.socket) {
327
+ // Notifica o servidor antes de desconectar
328
+ if (this.isConnected) {
329
+ this.socket.emit("presence:update", {
330
+ isPageVisible: false,
331
+ isAppFocused: false,
332
+ status: "offline",
333
+ clientType: "bot"
334
+ });
335
+ }
336
+
337
+ this.socket.disconnect();
338
+ this.socket = null;
339
+ }
340
+
341
+ this.isConnected = false;
342
+ }
343
+
258
344
  _setupSocketHandlers() {
259
345
  this.socket.on("message:new", async (data) => {
260
346
  try {
@@ -0,0 +1,8 @@
1
+ function formatUrl(url) {
2
+ const base = 'https://api.beniocord.site';
3
+ if (!url) return undefined;
4
+ if (url.startsWith(base) || url.startsWith('http')) return url;
5
+ return base + (url.startsWith('/') ? url : '/' + url);
6
+ }
7
+
8
+ module.exports = { formatUrl }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "socket.io-client": "^4.8.1"
5
5
  },
6
6
  "name": "beniocord.js",
7
- "version": "2.0.4",
7
+ "version": "2.0.5",
8
8
  "description": "Uma biblioteca leve e intuitiva para integração com APIs de bots em plataformas de mensagens, como Discord. Facilita o envio de mensagens, gerenciamento de canais e interação com usuários, proporcionando uma experiência de desenvolvimento ágil e eficiente.",
9
9
  "main": "Client.js",
10
10
  "devDependencies": {},
@@ -1,3 +1,4 @@
1
+ const { formatUrl } = require('../helpers');
1
2
  const MessageCollector = require('./MessageCollector');
2
3
 
3
4
  let client;
@@ -11,7 +12,7 @@ class Channel {
11
12
  this.type = data.type || "text";
12
13
  this.isPrivate = data.is_private;
13
14
  this.isDm = data.is_dm;
14
- this.iconUrl = data.icon_url ? 'https://api.beniocord.site' + data.icon_url : undefined;
15
+ this.iconUrl = formatUrl(data.icon_url);
15
16
  this.createdBy = data.created_by;
16
17
  this.createdAt = data.created_at;
17
18
  this.updatedAt = data.updated_at;
@@ -1,9 +1,11 @@
1
+ const { formatUrl } = require("../helpers");
2
+
1
3
  class Emoji {
2
4
  constructor(data) {
3
5
  this.id = data.id;
4
6
  this.userId = data.user_id;
5
7
  this.name = data.name;
6
- this.url = data.url ? 'https://api.beniocord.site' + data.url : undefined;
8
+ this.url = formatUrl(data.url);
7
9
  this.createdAt = data.created_at;
8
10
  this.updatedAt = data.updated_at;
9
11
  }
@@ -1,5 +1,6 @@
1
1
  const User = require("./User");
2
2
  const Channel = require("./Channel");
3
+ const { formatUrl } = require('../helpers/index');
3
4
 
4
5
  let client;
5
6
  class Message {
@@ -7,7 +8,7 @@ class Message {
7
8
  this.id = data.id;
8
9
  this.content = data.content;
9
10
  this.messageType = data.message_type || "text";
10
- this.fileUrl = data.file_url ? 'https://api.beniocord.site' + data.file_url : undefined;
11
+ this.fileUrl = formatUrl(data.file_url);
11
12
  this.fileName = data.file_name;
12
13
  this.fileSize = data.file_size;
13
14
  this.replyTo = data.reply_to;
@@ -1,9 +1,11 @@
1
+ const { formatUrl } = require("../helpers");
2
+
1
3
  class User {
2
4
  constructor(data, client) {
3
5
  this.id = data.id;
4
6
  this.username = data.username;
5
7
  this.displayName = data.display_name;
6
- this.avatarUrl = data.avatar_url ? 'https://api.beniocord.site' + data.avatar_url : undefined;
8
+ this.avatarUrl = formatUrl(data.avatar_url);
7
9
  this.status = data.status || "offline";
8
10
  this.emblems = data.emblems || [];
9
11
  this.lastSeen = data.last_seen;
@@ -1,6 +1,5 @@
1
1
  /**
2
- * MessageEmbed - Criar embeds com validação ultra rigorosa
3
- * Mesmas validações do backend para evitar rejeições
2
+ * MessageEmbed - Criar embeds
4
3
  * @class
5
4
  */
6
5
  class MessageEmbed {
@@ -483,7 +482,6 @@ class MessageEmbed {
483
482
  }
484
483
  }
485
484
 
486
- // Cores predefinidas para facilitar o uso
487
485
  MessageEmbed.Colors = {
488
486
  DEFAULT: '#5865F2',
489
487
  BLUE: '#3498DB',