1.2.0
This commit is contained in:
parent
af8e46110c
commit
54a5f33151
14 changed files with 223 additions and 38 deletions
11
CHANGELOG.md
11
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
|
# 1.1.1
|
||||||
- Fix readme
|
- Fix readme
|
||||||
|
|
||||||
|
|
20
README.md
20
README.md
|
@ -1,22 +1,8 @@
|
||||||
# discord.dart
|
# 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.
|
⚠️ We don't have tested on Flutter & on Web.
|
||||||
|
⚠️ 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
|
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
We took inspiration from [discord.js](https://github.com/discordjs/discord.js) and [Grapes-discord.grapes](https://github.com/BlackdestinyXX/Grapes-discord.grapes).
|
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
31
example/main.dart
Normal 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));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ class Channel {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<MessageSent> send(Message message) async {
|
Future<MessageSent> send(Message message) async {
|
||||||
await _sender.send(message, id);
|
var res = await _sender.send(message, id);
|
||||||
return MessageSent(message, id: id);
|
return MessageSent(message, res["author"]["id"], id, res["id"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,13 +5,20 @@ import './channel.dart';
|
||||||
class ChannelManager {
|
class ChannelManager {
|
||||||
final Collection cache = Collection();
|
final Collection cache = Collection();
|
||||||
final Sender _sender;
|
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) {
|
for (var channel in channels) {
|
||||||
cache.set(channel.id, channel);
|
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 {
|
Future<Channel> fetch(String id) async {
|
||||||
var res = await _sender.fetchChannel(id);
|
var res = await _sender.fetchChannel(id);
|
||||||
dynamic channel = Channel(_sender, res);
|
dynamic channel = Channel(_sender, res);
|
||||||
|
|
9
lib/src/classes/events.dart
Normal file
9
lib/src/classes/events.dart
Normal 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";
|
||||||
|
}
|
|
@ -3,9 +3,9 @@ import "guild.dart";
|
||||||
class UnavailableGuild {
|
class UnavailableGuild {
|
||||||
late String id;
|
late String id;
|
||||||
late bool unavailable;
|
late bool unavailable;
|
||||||
late Guild? notUpdatedData;
|
late Guild? notUpdatedGuild;
|
||||||
|
|
||||||
UnavailableGuild(this.id, { this.notUpdatedData }) {
|
UnavailableGuild(this.id, { this.notUpdatedGuild }) {
|
||||||
unavailable = true;
|
unavailable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,7 +9,6 @@ class Interaction {
|
||||||
Interaction(dynamic data) {
|
Interaction(dynamic data) {
|
||||||
token = data["token"];
|
token = data["token"];
|
||||||
id = data["id"];
|
id = data["id"];
|
||||||
print(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reply(Message message) {
|
reply(Message message) {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,27 @@
|
||||||
|
import "embed.dart";
|
||||||
|
|
||||||
/// Represents a message on Discord.
|
/// Represents a message on Discord.
|
||||||
class Message {
|
class Message {
|
||||||
String? content;
|
String? content;
|
||||||
Message({ this.content });
|
List<Embed>? embeds;
|
||||||
|
|
||||||
|
Message({ this.content, this.embeds });
|
||||||
|
|
||||||
/// Returns an object rapresentation of the message
|
/// Returns an object rapresentation of the message
|
||||||
Map<String, dynamic> exportable() {
|
Map<String, dynamic> exportable() {
|
||||||
return {
|
Map<String, dynamic> a = {};
|
||||||
"content": content,
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,8 +2,9 @@ import 'message.dart';
|
||||||
|
|
||||||
/// Represents a sent message on Discord.
|
/// Represents a sent message on Discord.
|
||||||
class MessageSent extends Message {
|
class MessageSent extends Message {
|
||||||
String id = '';
|
late String id;
|
||||||
MessageSent(Message msg, { required this.id }) {
|
late String channelID;
|
||||||
content = msg.content;
|
late String authorID;
|
||||||
}
|
|
||||||
|
MessageSent(Message msg, this.authorID, this.id, this.channelID): super(content: msg.content, embeds: msg.embeds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
import "dart:async";
|
import "dart:async";
|
||||||
import "dart:io";
|
import 'dart:io' if (dart.library.html) 'dart:html';
|
||||||
import "dart:convert";
|
import "dart:convert";
|
||||||
import "package:events_emitter/events_emitter.dart";
|
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.dart";
|
||||||
import "classes/guild/guild_manager.dart";
|
import "classes/guild/guild_manager.dart";
|
||||||
import "classes/interaction.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";
|
import "requests.dart";
|
||||||
|
|
||||||
final version = "10";
|
final version = "10";
|
||||||
|
@ -33,6 +39,9 @@ class Client extends EventEmitter {
|
||||||
String resumeGatewayURL = "";
|
String resumeGatewayURL = "";
|
||||||
String sessionID = "";
|
String sessionID = "";
|
||||||
late GuildManager guilds;
|
late GuildManager guilds;
|
||||||
|
late ChannelManager channels;
|
||||||
|
bool ready = false;
|
||||||
|
late User user;
|
||||||
|
|
||||||
/// Create a new Client.
|
/// Create a new Client.
|
||||||
/// [intents] Intents to enable for this connection, it's a multiple of two.
|
/// [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));
|
gg.add(Guild(sender, g));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channels = ChannelManager(sender, [], main: true);
|
||||||
|
|
||||||
|
sender.channels = channels;
|
||||||
guilds = GuildManager(sender, gg);
|
guilds = GuildManager(sender, gg);
|
||||||
|
|
||||||
int n = i.length;
|
int n = i.length;
|
||||||
|
@ -120,6 +132,8 @@ class Client extends EventEmitter {
|
||||||
case "READY":
|
case "READY":
|
||||||
resumeGatewayURL = event["d"]["resume_gateway_url"];
|
resumeGatewayURL = event["d"]["resume_gateway_url"];
|
||||||
sessionID = event["d"]["session_id"];
|
sessionID = event["d"]["session_id"];
|
||||||
|
user = User(event["d"]["user"]);
|
||||||
|
ready = true;
|
||||||
break;
|
break;
|
||||||
case "GUILD_CREATE":
|
case "GUILD_CREATE":
|
||||||
if (guilds.cache.has(event["d"]["id"])) {
|
if (guilds.cache.has(event["d"]["id"])) {
|
||||||
|
@ -141,9 +155,62 @@ class Client extends EventEmitter {
|
||||||
emit("GUILD_CREATE");
|
emit("GUILD_CREATE");
|
||||||
}
|
}
|
||||||
break;
|
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":
|
case "INTERACTION_CREATE":
|
||||||
|
if (!ready) return;
|
||||||
emit("INTERACTION_CREATE", Interaction(event["d"]));
|
emit("INTERACTION_CREATE", Interaction(event["d"]));
|
||||||
break;
|
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: () {
|
}, onDone: () {
|
||||||
switch (ws.closeCode) {
|
switch (ws.closeCode) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ Future<String> requestWebSocketURL() async {
|
||||||
class Sender {
|
class Sender {
|
||||||
final String? _token;
|
final String? _token;
|
||||||
Map<String, String> headers = {};
|
Map<String, String> headers = {};
|
||||||
|
dynamic channels;
|
||||||
|
|
||||||
Sender(this._token) {
|
Sender(this._token) {
|
||||||
headers = {
|
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" });
|
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) {
|
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;
|
return res;
|
||||||
}
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
name: tn_discord
|
name: tn_discord
|
||||||
description: A powerful Dart library for interacting with the Discord API.
|
description: A powerful Dart library for interacting with the Discord API.
|
||||||
version: 1.1.1
|
version: 1.2.0
|
||||||
repository: https://github.com/ThunderNetworkRaD/discord.dart
|
repository: https://github.com/ThunderNetworkRaD/discord-dart
|
||||||
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.0.6
|
sdk: ^3.0.6
|
||||||
|
|
Reference in a new issue