This commit is contained in:
KillerBossOrig 2023-08-08 16:59:38 +02:00
parent af8e46110c
commit 54a5f33151
14 changed files with 223 additions and 38 deletions

View file

@ -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

View file

@ -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).

31
example/main.dart Normal file
View file

@ -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));
}
});
}

View file

@ -13,7 +13,7 @@ class Channel {
}
Future<MessageSent> 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"]);
}
}

View file

@ -5,13 +5,20 @@ import './channel.dart';
class ChannelManager {
final Collection cache = Collection();
final Sender _sender;
late bool main;
ChannelManager(this._sender, List<Channel> channels) {
ChannelManager(this._sender, List<Channel> 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<Channel> fetch(String id) async {
var res = await _sender.fetchChannel(id);
dynamic channel = Channel(_sender, res);

View file

@ -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";
}

View file

@ -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;
}
}

View file

@ -9,7 +9,6 @@ class Interaction {
Interaction(dynamic data) {
token = data["token"];
id = data["id"];
print(data);
}
reply(Message message) {

View file

@ -1 +1,61 @@
typedef Embed = Map<String, String>;
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<String, dynamic> exportable() {
Map<String, dynamic> 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;
}
}

View file

@ -1,12 +1,27 @@
import "embed.dart";
/// Represents a message on Discord.
class Message {
String? content;
Message({ this.content });
List<Embed>? embeds;
Message({ this.content, this.embeds });
/// Returns an object rapresentation of the message
Map<String, dynamic> exportable() {
return {
"content": content,
};
Map<String, dynamic> a = {};
List<Map<String, dynamic>> 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;
}
}

View file

@ -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);
}

View file

@ -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<Embed> 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) {

View file

@ -37,6 +37,7 @@ Future<String> requestWebSocketURL() async {
class Sender {
final String? _token;
Map<String, String> headers = {};
dynamic channels;
Sender(this._token) {
headers = {
@ -95,8 +96,7 @@ Future interactionReply(String id, String token, Map<String, dynamic> 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;
}

View file

@ -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