beniocord.js 2.1.3 → 2.1.4
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 +217 -40
- package/package.json +1 -1
- package/structures/Util.js +83 -1
package/Client.js
CHANGED
|
@@ -11,7 +11,7 @@ const Channel = require("./structures/Channel");
|
|
|
11
11
|
const Emoji = require("./structures/Emoji");
|
|
12
12
|
const Sticker = require("./structures/Sticker");
|
|
13
13
|
|
|
14
|
-
const { MessageEmbed, MessageAttachment } = require("./structures/Util");
|
|
14
|
+
const { MessageEmbed, MessageAttachment, MessageImageAttachment, MessageAudioAttachment, MessageVideoAttachment } = require("./structures/Util");
|
|
15
15
|
const { formatUrl, stripDomain } = require("./helpers");
|
|
16
16
|
|
|
17
17
|
let global = {
|
|
@@ -541,20 +541,16 @@ class Client extends EventEmitter {
|
|
|
541
541
|
|
|
542
542
|
// Handle MessageAttachment as opts (backward compatibility)
|
|
543
543
|
if (opts instanceof MessageAttachment) {
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
messageType: detectedType
|
|
555
|
-
};
|
|
556
|
-
messageType = detectedType;
|
|
557
|
-
}
|
|
544
|
+
const fileData = await this._handleFileUpload(opts.buffer, opts.name);
|
|
545
|
+
const detectedType = opts.type || fileData.detectedType;
|
|
546
|
+
|
|
547
|
+
opts = {
|
|
548
|
+
fileUrl: fileData.url,
|
|
549
|
+
fileName: fileData.originalName,
|
|
550
|
+
fileSize: fileData.size,
|
|
551
|
+
messageType: detectedType
|
|
552
|
+
};
|
|
553
|
+
messageType = detectedType;
|
|
558
554
|
}
|
|
559
555
|
|
|
560
556
|
// Handle file upload
|
|
@@ -671,6 +667,155 @@ class Client extends EventEmitter {
|
|
|
671
667
|
});
|
|
672
668
|
}
|
|
673
669
|
|
|
670
|
+
// ============================================================================
|
|
671
|
+
// PUBLIC API METHODS - File/Media Sending
|
|
672
|
+
// ============================================================================
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Sends a file to a channel
|
|
676
|
+
* @param {string} channelId - Channel ID
|
|
677
|
+
* @param {Buffer|string} file - Buffer, base64 string, or file path
|
|
678
|
+
* @param {Object} options - Send options
|
|
679
|
+
* @param {string} options.fileName - File name (required for Buffer/base64)
|
|
680
|
+
* @param {string} options.content - Optional text content to send with the file
|
|
681
|
+
* @param {string} options.replyTo - Optional message ID to reply to
|
|
682
|
+
* @returns {Promise<Message>} Sent message object
|
|
683
|
+
* @example
|
|
684
|
+
* // Send from file path
|
|
685
|
+
* client.sendFile(channelId, './document.pdf');
|
|
686
|
+
*
|
|
687
|
+
* // Send from buffer
|
|
688
|
+
* client.sendFile(channelId, buffer, { fileName: 'document.pdf' });
|
|
689
|
+
*
|
|
690
|
+
* // Send with message
|
|
691
|
+
* client.sendFile(channelId, './photo.png', { content: 'Check this out!' });
|
|
692
|
+
*/
|
|
693
|
+
async sendFile(channelId, file, options = {}) {
|
|
694
|
+
const { fileName, content = '', replyTo } = options;
|
|
695
|
+
|
|
696
|
+
try {
|
|
697
|
+
const fileData = await this._handleFileUpload(file, fileName);
|
|
698
|
+
|
|
699
|
+
return this.sendMessage(channelId, content, {
|
|
700
|
+
file: null, // Already uploaded
|
|
701
|
+
fileUrl: fileData.url,
|
|
702
|
+
fileName: fileData.originalName,
|
|
703
|
+
fileSize: fileData.size,
|
|
704
|
+
messageType: fileData.detectedType,
|
|
705
|
+
replyTo,
|
|
706
|
+
});
|
|
707
|
+
} catch (error) {
|
|
708
|
+
throw error instanceof ClientError ? error : new ClientError(error.message, "SEND_FILE_ERROR");
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Sends an image to a channel
|
|
714
|
+
* @param {string} channelId - Channel ID
|
|
715
|
+
* @param {Buffer|string} image - Buffer, base64 string, or file path
|
|
716
|
+
* @param {Object} options - Send options
|
|
717
|
+
* @param {string} options.fileName - File name (required for Buffer/base64)
|
|
718
|
+
* @param {string} options.content - Optional text content to send with the image
|
|
719
|
+
* @param {string} options.replyTo - Optional message ID to reply to
|
|
720
|
+
* @returns {Promise<Message>} Sent message object
|
|
721
|
+
* @example
|
|
722
|
+
* // Send from file path
|
|
723
|
+
* client.sendImage(channelId, './photo.png');
|
|
724
|
+
*
|
|
725
|
+
* // Send from buffer
|
|
726
|
+
* client.sendImage(channelId, imageBuffer, { fileName: 'screenshot.png' });
|
|
727
|
+
*
|
|
728
|
+
* // Send from base64
|
|
729
|
+
* client.sendImage(channelId, 'data:image/png;base64,...');
|
|
730
|
+
*/
|
|
731
|
+
async sendImage(channelId, image, options = {}) {
|
|
732
|
+
const { fileName, content = '', replyTo } = options;
|
|
733
|
+
|
|
734
|
+
try {
|
|
735
|
+
const fileData = await this._handleFileUpload(image, fileName);
|
|
736
|
+
|
|
737
|
+
return this.sendMessage(channelId, content, {
|
|
738
|
+
fileUrl: fileData.url,
|
|
739
|
+
fileName: fileData.originalName,
|
|
740
|
+
fileSize: fileData.size,
|
|
741
|
+
messageType: 'image',
|
|
742
|
+
replyTo,
|
|
743
|
+
});
|
|
744
|
+
} catch (error) {
|
|
745
|
+
throw error instanceof ClientError ? error : new ClientError(error.message, "SEND_IMAGE_ERROR");
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Sends an audio file to a channel
|
|
751
|
+
* @param {string} channelId - Channel ID
|
|
752
|
+
* @param {Buffer|string} audio - Buffer, base64 string, or file path
|
|
753
|
+
* @param {Object} options - Send options
|
|
754
|
+
* @param {string} options.fileName - File name (required for Buffer/base64)
|
|
755
|
+
* @param {string} options.content - Optional text content to send with the audio
|
|
756
|
+
* @param {string} options.replyTo - Optional message ID to reply to
|
|
757
|
+
* @returns {Promise<Message>} Sent message object
|
|
758
|
+
* @example
|
|
759
|
+
* // Send from file path
|
|
760
|
+
* client.sendAudio(channelId, './song.mp3');
|
|
761
|
+
*
|
|
762
|
+
* // Send from buffer (voice recording for example)
|
|
763
|
+
* client.sendAudio(channelId, audioBuffer, { fileName: 'voice_message.ogg' });
|
|
764
|
+
*
|
|
765
|
+
* // Send with content
|
|
766
|
+
* client.sendAudio(channelId, './podcast.mp3', { content: 'New episode!' });
|
|
767
|
+
*/
|
|
768
|
+
async sendAudio(channelId, audio, options = {}) {
|
|
769
|
+
const { fileName, content = '', replyTo } = options;
|
|
770
|
+
|
|
771
|
+
try {
|
|
772
|
+
const fileData = await this._handleFileUpload(audio, fileName);
|
|
773
|
+
|
|
774
|
+
return this.sendMessage(channelId, content, {
|
|
775
|
+
fileUrl: fileData.url,
|
|
776
|
+
fileName: fileData.originalName,
|
|
777
|
+
fileSize: fileData.size,
|
|
778
|
+
messageType: 'audio',
|
|
779
|
+
replyTo,
|
|
780
|
+
});
|
|
781
|
+
} catch (error) {
|
|
782
|
+
throw error instanceof ClientError ? error : new ClientError(error.message, "SEND_AUDIO_ERROR");
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* Sends a video to a channel
|
|
788
|
+
* @param {string} channelId - Channel ID
|
|
789
|
+
* @param {Buffer|string} video - Buffer, base64 string, or file path
|
|
790
|
+
* @param {Object} options - Send options
|
|
791
|
+
* @param {string} options.fileName - File name (required for Buffer/base64)
|
|
792
|
+
* @param {string} options.content - Optional text content to send with the video
|
|
793
|
+
* @param {string} options.replyTo - Optional message ID to reply to
|
|
794
|
+
* @returns {Promise<Message>} Sent message object
|
|
795
|
+
* @example
|
|
796
|
+
* // Send from file path
|
|
797
|
+
* client.sendVideo(channelId, './video.mp4');
|
|
798
|
+
*
|
|
799
|
+
* // Send from buffer
|
|
800
|
+
* client.sendVideo(channelId, videoBuffer, { fileName: 'clip.mp4' });
|
|
801
|
+
*/
|
|
802
|
+
async sendVideo(channelId, video, options = {}) {
|
|
803
|
+
const { fileName, content = '', replyTo } = options;
|
|
804
|
+
|
|
805
|
+
try {
|
|
806
|
+
const fileData = await this._handleFileUpload(video, fileName);
|
|
807
|
+
|
|
808
|
+
return this.sendMessage(channelId, content, {
|
|
809
|
+
fileUrl: fileData.url,
|
|
810
|
+
fileName: fileData.originalName,
|
|
811
|
+
fileSize: fileData.size,
|
|
812
|
+
messageType: 'video',
|
|
813
|
+
replyTo,
|
|
814
|
+
});
|
|
815
|
+
} catch (error) {
|
|
816
|
+
throw error instanceof ClientError ? error : new ClientError(error.message, "SEND_VIDEO_ERROR");
|
|
817
|
+
}
|
|
818
|
+
}
|
|
674
819
|
|
|
675
820
|
/**
|
|
676
821
|
* Deletes a message
|
|
@@ -715,7 +860,28 @@ class Client extends EventEmitter {
|
|
|
715
860
|
}
|
|
716
861
|
|
|
717
862
|
const res = await this._axios.get(`/api/channels/${channelId}/messages`, { params });
|
|
718
|
-
|
|
863
|
+
|
|
864
|
+
const messages = res.data.map(raw => {
|
|
865
|
+
let userData = raw.user;
|
|
866
|
+
if (!userData && raw.user_id) {
|
|
867
|
+
userData = {
|
|
868
|
+
id: raw.user_id,
|
|
869
|
+
username: raw.username,
|
|
870
|
+
display_name: raw.display_name,
|
|
871
|
+
avatar_url: raw.avatar_url,
|
|
872
|
+
status: raw.status || 'online',
|
|
873
|
+
emblems: raw.emblems || [],
|
|
874
|
+
is_bot: raw.is_bot ?? false,
|
|
875
|
+
last_seen: raw.last_seen ?? raw.created_at,
|
|
876
|
+
created_at: raw.created_at,
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
const messageData = { ...raw, user: userData };
|
|
881
|
+
const msg = new Message(messageData, this);
|
|
882
|
+
if (msg.author) this.cache.users.set(msg.author.id, msg.author);
|
|
883
|
+
return msg;
|
|
884
|
+
});
|
|
719
885
|
|
|
720
886
|
if (!this.cache.messages.has(channelId)) {
|
|
721
887
|
this.cache.messages.set(channelId, []);
|
|
@@ -728,6 +894,24 @@ class Client extends EventEmitter {
|
|
|
728
894
|
}
|
|
729
895
|
});
|
|
730
896
|
|
|
897
|
+
let channel = this.cache.channels.get(channelId);
|
|
898
|
+
if (!channel) {
|
|
899
|
+
const id = String(channelId);
|
|
900
|
+
for (const [key, val] of this.cache.channels) {
|
|
901
|
+
if (String(key) === id) {
|
|
902
|
+
channel = val;
|
|
903
|
+
break;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
if (channel) {
|
|
909
|
+
messages.forEach(msg => {
|
|
910
|
+
if (!msg.channel) msg.channel = channel;
|
|
911
|
+
channel.messages.set(msg.id, msg);
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
|
|
731
915
|
return messages;
|
|
732
916
|
} catch (error) {
|
|
733
917
|
throw error instanceof ClientError ? error : new ClientError(error.message, "FETCH_MESSAGES_ERROR");
|
|
@@ -933,30 +1117,6 @@ class Client extends EventEmitter {
|
|
|
933
1117
|
}
|
|
934
1118
|
}
|
|
935
1119
|
|
|
936
|
-
// ============================================================================
|
|
937
|
-
// PUBLIC API METHODS - File Upload
|
|
938
|
-
// ============================================================================
|
|
939
|
-
|
|
940
|
-
/**
|
|
941
|
-
* Uploads a file to the server
|
|
942
|
-
* @param {MessageAttachment} file - File attachment to upload
|
|
943
|
-
* @returns {Promise<Object>} Upload response with file URL
|
|
944
|
-
*/
|
|
945
|
-
async uploadFile(file) {
|
|
946
|
-
try {
|
|
947
|
-
const formData = new FormData();
|
|
948
|
-
formData.append('file', file.buffer, { filename: file.name });
|
|
949
|
-
const res = await this._axios.post('/api/upload', formData, {
|
|
950
|
-
headers: formData.getHeaders(),
|
|
951
|
-
timeout: 30000
|
|
952
|
-
});
|
|
953
|
-
|
|
954
|
-
return res.data;
|
|
955
|
-
} catch (error) {
|
|
956
|
-
throw error instanceof ClientError ? error : new ClientError(error.message, "UPLOAD_ERROR");
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
|
|
960
1120
|
// ============================================================================
|
|
961
1121
|
// PUBLIC API METHODS - Cache Management
|
|
962
1122
|
// ============================================================================
|
|
@@ -1531,6 +1691,16 @@ class Client extends EventEmitter {
|
|
|
1531
1691
|
'image/webp': '.webp',
|
|
1532
1692
|
'video/mp4': '.mp4',
|
|
1533
1693
|
'video/webm': '.webm',
|
|
1694
|
+
'audio/mpeg': '.mp3',
|
|
1695
|
+
'audio/mp3': '.mp3',
|
|
1696
|
+
'audio/wav': '.wav',
|
|
1697
|
+
'audio/wave': '.wav',
|
|
1698
|
+
'audio/ogg': '.ogg',
|
|
1699
|
+
'audio/webm': '.weba',
|
|
1700
|
+
'audio/aac': '.aac',
|
|
1701
|
+
'audio/flac': '.flac',
|
|
1702
|
+
'audio/m4a': '.m4a',
|
|
1703
|
+
'audio/x-m4a': '.m4a',
|
|
1534
1704
|
};
|
|
1535
1705
|
|
|
1536
1706
|
const ext = mimeToExt[mimeType] || '.bin';
|
|
@@ -1557,11 +1727,14 @@ class Client extends EventEmitter {
|
|
|
1557
1727
|
const ext = path.extname(finalFileName).toLowerCase();
|
|
1558
1728
|
const imageExts = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.svg'];
|
|
1559
1729
|
const videoExts = ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv', '.webm'];
|
|
1730
|
+
const audioExts = ['.mp3', '.wav', '.ogg', '.flac', '.aac', '.m4a', '.weba', '.opus', '.wma'];
|
|
1560
1731
|
|
|
1561
1732
|
if (imageExts.includes(ext)) {
|
|
1562
1733
|
detectedType = 'image';
|
|
1563
1734
|
} else if (videoExts.includes(ext)) {
|
|
1564
1735
|
detectedType = 'video';
|
|
1736
|
+
} else if (audioExts.includes(ext)) {
|
|
1737
|
+
detectedType = 'audio';
|
|
1565
1738
|
} else {
|
|
1566
1739
|
detectedType = 'file';
|
|
1567
1740
|
}
|
|
@@ -1634,5 +1807,9 @@ class ClientError extends Error {
|
|
|
1634
1807
|
}
|
|
1635
1808
|
|
|
1636
1809
|
Client.MessageEmbed = MessageEmbed;
|
|
1810
|
+
Client.MessageAttachment = MessageAttachment;
|
|
1811
|
+
Client.MessageImageAttachment = MessageImageAttachment;
|
|
1812
|
+
Client.MessageAudioAttachment = MessageAudioAttachment;
|
|
1813
|
+
Client.MessageVideoAttachment = MessageVideoAttachment;
|
|
1637
1814
|
// Client.ClientError = ClientError;
|
|
1638
1815
|
module.exports = Client;
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"socket.io-client": "^4.8.1"
|
|
6
6
|
},
|
|
7
7
|
"name": "beniocord.js",
|
|
8
|
-
"version": "2.1.
|
|
8
|
+
"version": "2.1.4",
|
|
9
9
|
"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.",
|
|
10
10
|
"main": "Client.js",
|
|
11
11
|
"scripts": {
|
package/structures/Util.js
CHANGED
|
@@ -586,7 +586,89 @@ class MessageAttachment {
|
|
|
586
586
|
}
|
|
587
587
|
this.buffer = buffer;
|
|
588
588
|
this.name = name;
|
|
589
|
+
this.type = this._detectType();
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Detects the file type based on extension
|
|
594
|
+
* @private
|
|
595
|
+
* @returns {string} The detected type
|
|
596
|
+
*/
|
|
597
|
+
_detectType() {
|
|
598
|
+
const ext = this.name.split('.').pop().toLowerCase();
|
|
599
|
+
|
|
600
|
+
const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'];
|
|
601
|
+
const videoExts = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm'];
|
|
602
|
+
const audioExts = ['mp3', 'wav', 'ogg', 'flac', 'aac', 'm4a', 'weba', 'opus', 'wma'];
|
|
603
|
+
|
|
604
|
+
if (imageExts.includes(ext)) return 'image';
|
|
605
|
+
if (videoExts.includes(ext)) return 'video';
|
|
606
|
+
if (audioExts.includes(ext)) return 'audio';
|
|
607
|
+
return 'file';
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* @class
|
|
613
|
+
*/
|
|
614
|
+
class MessageImageAttachment extends MessageAttachment {
|
|
615
|
+
/**
|
|
616
|
+
* Creates a new MessageImageAttachment instance.
|
|
617
|
+
*
|
|
618
|
+
* @param {Buffer|Uint8Array|string} buffer - The image data.
|
|
619
|
+
* @param {string} name - The name of the image file (e.g., "screenshot.png").
|
|
620
|
+
*
|
|
621
|
+
* @example
|
|
622
|
+
* const image = new MessageImageAttachment(imageBuffer, "screenshot.png");
|
|
623
|
+
*/
|
|
624
|
+
constructor(buffer, name) {
|
|
625
|
+
super(buffer, name);
|
|
626
|
+
this.type = 'image';
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* @class
|
|
632
|
+
*/
|
|
633
|
+
class MessageAudioAttachment extends MessageAttachment {
|
|
634
|
+
/**
|
|
635
|
+
* Creates a new MessageAudioAttachment instance.
|
|
636
|
+
*
|
|
637
|
+
* @param {Buffer|Uint8Array|string} buffer - The audio data.
|
|
638
|
+
* @param {string} name - The name of the audio file (e.g., "voice_message.mp3").
|
|
639
|
+
*
|
|
640
|
+
* @example
|
|
641
|
+
* const audio = new MessageAudioAttachment(audioBuffer, "song.mp3");
|
|
642
|
+
*/
|
|
643
|
+
constructor(buffer, name) {
|
|
644
|
+
super(buffer, name);
|
|
645
|
+
this.type = 'audio';
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* @class
|
|
651
|
+
*/
|
|
652
|
+
class MessageVideoAttachment extends MessageAttachment {
|
|
653
|
+
/**
|
|
654
|
+
* Creates a new MessageVideoAttachment instance.
|
|
655
|
+
*
|
|
656
|
+
* @param {Buffer|Uint8Array|string} buffer - The video data.
|
|
657
|
+
* @param {string} name - The name of the video file (e.g., "video.mp4").
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* const video = new MessageVideoAttachment(videoBuffer, "clip.mp4");
|
|
661
|
+
*/
|
|
662
|
+
constructor(buffer, name) {
|
|
663
|
+
super(buffer, name);
|
|
664
|
+
this.type = 'video';
|
|
589
665
|
}
|
|
590
666
|
}
|
|
591
667
|
|
|
592
|
-
module.exports = {
|
|
668
|
+
module.exports = {
|
|
669
|
+
MessageEmbed,
|
|
670
|
+
MessageAttachment,
|
|
671
|
+
MessageImageAttachment,
|
|
672
|
+
MessageAudioAttachment,
|
|
673
|
+
MessageVideoAttachment
|
|
674
|
+
};
|