From 54a5f3315168bb8c3fc9a3b357bc2997004ec24b Mon Sep 17 00:00:00 2001 From: KillerBossOrig Date: Tue, 8 Aug 2023 16:59:38 +0200 Subject: [PATCH] 1.2.0 --- CHANGELOG.md | 11 ++++ README.md | 20 +----- example/main.dart | 31 +++++++++ lib/src/classes/channel/channel.dart | 4 +- lib/src/classes/channel/channel_manager.dart | 9 ++- lib/src/classes/events.dart | 9 +++ lib/src/classes/guild/unavailable_guild.dart | 4 +- lib/src/classes/interaction.dart | 1 - lib/src/classes/message/embed.dart | 62 +++++++++++++++++- lib/src/classes/message/message.dart | 23 +++++-- lib/src/classes/message/message_sent.dart | 9 +-- lib/src/main.dart | 69 +++++++++++++++++++- lib/src/requests.dart | 4 +- pubspec.yaml | 5 +- 14 files changed, 223 insertions(+), 38 deletions(-) create mode 100644 example/main.dart create mode 100644 lib/src/classes/events.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index e088f75..5b7c523 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# 1.2.0 +- Add `client` +- Add Event Emitter/Listener (`client.on`) +- Add GatewayIntentsBits class +- Add Event Class +- Add Event `Ready` +- Add Event `GuildCreate` +- Add Event `GuildDelete` +- Add Event `InteractionCreate` +- Add many classes + # 1.1.1 - Fix readme diff --git a/README.md b/README.md index f361c27..c1a51bc 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,8 @@ # discord.dart -[![Pub](https://img.shields.io/pub/v/tn_discord?color=red&logo=dart)](https://github.com/ThunderNetworkRaD/discord.dart) +[![Pub](https://img.shields.io/pub/v/tn_discord?color=red&logo=dart)](https://github.com/ThunderNetworkRaD/discord-dart) -This package is work in progress. - -## Webhooks - -### Initializations -```dart -import 'package:tn_discord/tn_discord.dart'; -main() { - const webhook = WebookClient(/*Webhook Options*/); -} -``` -### Webhook Options -- url: String -- id: String -- token: String -url overrides id and token +⚠️ We don't have tested on Flutter & on Web. +⚠️ This package is work in progress. ## Credits We took inspiration from [discord.js](https://github.com/discordjs/discord.js) and [Grapes-discord.grapes](https://github.com/BlackdestinyXX/Grapes-discord.grapes). diff --git a/example/main.dart b/example/main.dart new file mode 100644 index 0000000..74be1c8 --- /dev/null +++ b/example/main.dart @@ -0,0 +1,31 @@ +import 'package:tn_discord/src/classes/events.dart'; +import 'package:tn_discord/src/classes/message/message.dart'; +import 'package:tn_discord/src/classes/message/message_sent.dart'; +import 'package:tn_discord/tn_discord.dart'; + +main() async { + var client = Client( + intents: calculateIntents([ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.MessageContent + // What do you want from GatewayIntentBits + ]) + ); + + client.login("Your Bot Token"); + + client.on("READY", (data) async { + // Let we get a guild name + var a = await client.guilds.fetch("a guild id"); + print(a.name); + }); + + client.on(Events.MessageCreate, (MessageSent message) async { + // When a message is sent print author id and reply with the same message + print(message.authorID); + if (message.authorID != client.user.id) { + client.channels.cache.get(message.id).send(Message(content: message.content)); + } + }); +} diff --git a/lib/src/classes/channel/channel.dart b/lib/src/classes/channel/channel.dart index b401ba4..27e9396 100644 --- a/lib/src/classes/channel/channel.dart +++ b/lib/src/classes/channel/channel.dart @@ -13,7 +13,7 @@ class Channel { } Future send(Message message) async { - await _sender.send(message, id); - return MessageSent(message, id: id); + var res = await _sender.send(message, id); + return MessageSent(message, res["author"]["id"], id, res["id"]); } } \ No newline at end of file diff --git a/lib/src/classes/channel/channel_manager.dart b/lib/src/classes/channel/channel_manager.dart index b8b60b6..e83c744 100644 --- a/lib/src/classes/channel/channel_manager.dart +++ b/lib/src/classes/channel/channel_manager.dart @@ -5,13 +5,20 @@ import './channel.dart'; class ChannelManager { final Collection cache = Collection(); final Sender _sender; + late bool main; - ChannelManager(this._sender, List channels) { + ChannelManager(this._sender, List channels, { this.main = false }) { for (var channel in channels) { cache.set(channel.id, channel); + if (!main) { + _sender.channels.cache.set(channel.id, channel); + } } } + /// Fetch a channel from discord + /// If you use the [fetch] method with client.channels, guild channels manager + /// will not be updated Future fetch(String id) async { var res = await _sender.fetchChannel(id); dynamic channel = Channel(_sender, res); diff --git a/lib/src/classes/events.dart b/lib/src/classes/events.dart new file mode 100644 index 0000000..bb71bc0 --- /dev/null +++ b/lib/src/classes/events.dart @@ -0,0 +1,9 @@ +// ignore_for_file: constant_identifier_names + +class Events { + static const Ready = "READY"; + static const GuildCreate = "GUILD_CREATE"; + static const GuildDelete = "GUILD_DELETE"; + static const InteractionCreate = "INTERACTION_CREATE"; + static const MessageCreate = "MESSAGE_CREATE"; +} \ No newline at end of file diff --git a/lib/src/classes/guild/unavailable_guild.dart b/lib/src/classes/guild/unavailable_guild.dart index 9e777c4..e977dcf 100644 --- a/lib/src/classes/guild/unavailable_guild.dart +++ b/lib/src/classes/guild/unavailable_guild.dart @@ -3,9 +3,9 @@ import "guild.dart"; class UnavailableGuild { late String id; late bool unavailable; - late Guild? notUpdatedData; + late Guild? notUpdatedGuild; - UnavailableGuild(this.id, { this.notUpdatedData }) { + UnavailableGuild(this.id, { this.notUpdatedGuild }) { unavailable = true; } } \ No newline at end of file diff --git a/lib/src/classes/interaction.dart b/lib/src/classes/interaction.dart index 3c3ca36..f71047e 100644 --- a/lib/src/classes/interaction.dart +++ b/lib/src/classes/interaction.dart @@ -9,7 +9,6 @@ class Interaction { Interaction(dynamic data) { token = data["token"]; id = data["id"]; - print(data); } reply(Message message) { diff --git a/lib/src/classes/message/embed.dart b/lib/src/classes/message/embed.dart index 516f986..6f4d7dd 100644 --- a/lib/src/classes/message/embed.dart +++ b/lib/src/classes/message/embed.dart @@ -1 +1,61 @@ -typedef Embed = Map; \ No newline at end of file +class Embed { + String? title; + String? description; + String type = "rich"; + String? url; + String? timestamp; + String? color; + String? footer; + String? image; + String? thumbnail; + String? author; + String? fields; + + Embed({ + this.title, + this.description, + this.url, + this.timestamp, + this.color, + this.footer, + this.image, + this.thumbnail, + this.author, + this.fields + }); + + Map exportable() { + Map a = {}; + if (title != null) { + a["title"] = title; + } + if (description != null) { + a["description"] = description; + } + if (url != null) { + a["url"] = url; + } + if (timestamp != null) { + a["timestamp"] = timestamp; + } + if (color != null) { + a["color"] = color; + } + if (footer != null) { + a["footer"] = footer; + } + if (image != null) { + a["image"] = image; + } + if (thumbnail != null) { + a["thumbnail"] = thumbnail; + } + if (author != null) { + a["author"] = author; + } + if (fields != null) { + a["fields"] = fields; + } + return a; + } +} \ No newline at end of file diff --git a/lib/src/classes/message/message.dart b/lib/src/classes/message/message.dart index f852f5e..253bc84 100644 --- a/lib/src/classes/message/message.dart +++ b/lib/src/classes/message/message.dart @@ -1,12 +1,27 @@ +import "embed.dart"; + /// Represents a message on Discord. class Message { String? content; - Message({ this.content }); + List? embeds; + + Message({ this.content, this.embeds }); /// Returns an object rapresentation of the message Map exportable() { - return { - "content": content, - }; + Map a = {}; + List> e = []; + if (embeds != null && embeds!.isNotEmpty) { + for (var embed in embeds!) { + e.add(embed.exportable()); + } + } + if (e.isNotEmpty) { + a["embeds"] = e; + } + if (content != null) { + a["content"] = content; + } + return a; } } \ No newline at end of file diff --git a/lib/src/classes/message/message_sent.dart b/lib/src/classes/message/message_sent.dart index a200b4f..960808e 100644 --- a/lib/src/classes/message/message_sent.dart +++ b/lib/src/classes/message/message_sent.dart @@ -2,8 +2,9 @@ import 'message.dart'; /// Represents a sent message on Discord. class MessageSent extends Message { - String id = ''; - MessageSent(Message msg, { required this.id }) { - content = msg.content; - } + late String id; + late String channelID; + late String authorID; + + MessageSent(Message msg, this.authorID, this.id, this.channelID): super(content: msg.content, embeds: msg.embeds); } diff --git a/lib/src/main.dart b/lib/src/main.dart index 9dddcac..9c5f6f8 100644 --- a/lib/src/main.dart +++ b/lib/src/main.dart @@ -1,11 +1,17 @@ import "dart:async"; -import "dart:io"; +import 'dart:io' if (dart.library.html) 'dart:html'; import "dart:convert"; import "package:events_emitter/events_emitter.dart"; +import "package:tn_discord/src/classes/channel/channel_manager.dart"; import "classes/guild/guild.dart"; import "classes/guild/guild_manager.dart"; import "classes/interaction.dart"; +import "classes/message/embed.dart"; +import "classes/message/message.dart"; +import "classes/guild/unavailable_guild.dart"; +import "classes/message/message_sent.dart"; +import "classes/user/user.dart"; import "requests.dart"; final version = "10"; @@ -33,6 +39,9 @@ class Client extends EventEmitter { String resumeGatewayURL = ""; String sessionID = ""; late GuildManager guilds; + late ChannelManager channels; + bool ready = false; + late User user; /// Create a new Client. /// [intents] Intents to enable for this connection, it's a multiple of two. @@ -94,6 +103,9 @@ class Client extends EventEmitter { gg.add(Guild(sender, g)); } + channels = ChannelManager(sender, [], main: true); + + sender.channels = channels; guilds = GuildManager(sender, gg); int n = i.length; @@ -120,6 +132,8 @@ class Client extends EventEmitter { case "READY": resumeGatewayURL = event["d"]["resume_gateway_url"]; sessionID = event["d"]["session_id"]; + user = User(event["d"]["user"]); + ready = true; break; case "GUILD_CREATE": if (guilds.cache.has(event["d"]["id"])) { @@ -141,9 +155,62 @@ class Client extends EventEmitter { emit("GUILD_CREATE"); } break; + case "GUILD_DELETE": + dynamic guild; + if (guilds.cache.has(event["d"]["id"])) { + guild = guilds.cache.get(event["d"]["id"]); + guilds.cache.set(event["d"]["id"], UnavailableGuild(event["d"]["id"], notUpdatedGuild: guild)); + } else { + guild = event["d"]; + } + emit("GUILD_DELETE", guild); + break; case "INTERACTION_CREATE": + if (!ready) return; emit("INTERACTION_CREATE", Interaction(event["d"])); break; + case "MESSAGE_CREATE": + if (!ready) return; + var content = event["d"]["content"]; + var embeds = event["d"]["embeds"]; + List e = []; + for (var embed in embeds) { + var title = embed["title"]; + var description = embed["description"]; + var url = embed["url"]; + var timestamp = embed["timestamp"]; + var color = embed["color"]; + var footer = embed["footer"]; + var image = embed["image"]; + var thumbnail = embed["thumbnail"]; + var author = embed["author"]; + var fields = embed["fields"]; + e.add(Embed( + author: author, + fields: fields, + footer: footer, + image: image, + thumbnail: thumbnail, + title: title, + description: description, + url: url, + timestamp: timestamp, + color: color + )); + } + emit( + "MESSAGE_CREATE", + MessageSent( + Message( + content: content, + embeds: e + ), + event["d"]["author"]["id"], + event["d"]["channel_id"], + event["d"]["id"] + ) + ); + break; } }, onDone: () { switch (ws.closeCode) { diff --git a/lib/src/requests.dart b/lib/src/requests.dart index 775017b..3aa9269 100644 --- a/lib/src/requests.dart +++ b/lib/src/requests.dart @@ -37,6 +37,7 @@ Future requestWebSocketURL() async { class Sender { final String? _token; Map headers = {}; + dynamic channels; Sender(this._token) { headers = { @@ -95,8 +96,7 @@ Future interactionReply(String id, String token, Map content) a dynamic res = await http.post(Uri.parse("$apiURL/interactions/$id/$token/callback"), body: json.encode(bd), headers: { "Content-Type": "application/json" }); if (res.statusCode != 204) { - throw Exception("Error ${res.statusCode} replying to the interaction"); + throw Exception("Error ${res.statusCode} replying to the interaction\nBody: ${json.encode(res.body)}"); } - res = json.decode(res.body); return res; } \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 3499b16..197731e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,8 +1,7 @@ name: tn_discord description: A powerful Dart library for interacting with the Discord API. -version: 1.1.1 -repository: https://github.com/ThunderNetworkRaD/discord.dart - +version: 1.2.0 +repository: https://github.com/ThunderNetworkRaD/discord-dart environment: sdk: ^3.0.6