An Accord protocol client library for Dart. AccordKit gives you a typed REST client, a resilient gateway WebSocket client (with automatic heartbeating, resume, and reconnect), and data models for building bots, tools, and apps against Daccord servers.
This is a Dart port of the GDScript accordkit addon and tracks the same API
surface and wire behaviour.
- REST client covering every endpoint group: users, spaces, channels, messages, members, roles, bans, reports, invites, emojis, soundboard, reactions, interactions, plugins, applications, auth, voice, audit logs, admin, and the master-server directory.
- Gateway client with IDENTIFY/RESUME handshake, heartbeating, exponential backoff reconnect, and ~50 typed event streams.
- Typed models with lenient JSON parsing (
fromJson) andtoJson. - Voice manager that ties the voice REST endpoints to gateway voice events.
- Helpers for snowflakes, CDN URLs, permissions, intents, multipart uploads, and cursor pagination.
- Testable by design — inject an
http.Clientfor REST and a connection factory for the gateway.
Add the dependency to your pubspec.yaml:
dependencies:
accordkit:
git:
url: https://github.com/DaccordProject/accordkit-dart.gitThen run dart pub get (or flutter pub get).
import 'package:accordkit/accordkit.dart';
Future<void> main() async {
final client = AccordClient(
token: 'YOUR_BOT_TOKEN',
tokenType: 'Bot',
baseUrl: 'https://your.daccord.server',
gatewayUrl: 'wss://your.daccord.server/ws',
intents: [
GatewayIntents.spaces,
GatewayIntents.messages,
GatewayIntents.messageContent,
],
);
client.onMessageCreate.listen((message) async {
if (message.content == '!ping') {
await client.messages.create(message.channelId, {'content': 'pong'});
}
});
client.login();
}See example/accordkit_example.dart for a
complete sample.
Every endpoint group hangs off AccordClient, and every call returns a
RestResult:
final result = await client.spaces.fetch('space_id');
if (result.ok) {
final space = result.data as AccordSpace;
print(space.name);
} else {
print('Error: ${result.error}'); // AccordError(code, message)
}RestResult.data is the deserialized model (or list of models) on success, and
RestResult.error is an AccordError on failure. Cursor-paginated endpoints
expose RestResult.hasMore and RestResult.cursor; wrap them with
AccordPaginator to page through results:
final first = await client.messages.list('channel_id', query: {'limit': 50});
var page = AccordPaginator.fromResult(
first, client.rest, '/channels/channel_id/messages', {'limit': 50},
fromJson: AccordMessage.fromJson,
);
while (page.hasMore) {
page = await page.next();
}await client.messages.createWithAttachments(
'channel_id',
{'content': 'Here is a file'},
[
{
'filename': 'image.png',
'content': bytes, // List<int> / Uint8List
'content_type': 'image/png',
},
],
);Subscribe to typed broadcast streams on the client (or on client.gateway):
client.onReady.listen((data) => print('session ${data['session_id']}'));
client.onMessageCreate.listen((m) => print('${m.authorId}: ${m.content}'));
client.onPresenceUpdate.listen((p) => print('${p.userId} is ${p.status}'));
// Catch-all for any event:
client.onRawEvent.listen((e) => print('event ${e.type}'));Lifecycle and presence:
client.login(); // open the gateway
client.updatePresence('online', activity: {'name': 'a game'});
await client.logout(); // close the gatewayThe gateway reconnects automatically with exponential backoff and resumes the session when possible. Fatal close codes (e.g. authentication failures) stop reconnection.
final vm = client.voiceManager;
vm.onVoiceConnected.listen((info) => print('joined ${info.channelId}'));
vm.onVoiceDisconnected.listen((channelId) => print('left $channelId'));
await vm.join('voice_channel_id', selfMute: false);
await vm.leave();// Snowflakes
final created = AccordSnowflake.decodeToDateTime(message.id);
// CDN URLs
final url = AccordCDN.avatar(user.id, user.avatar!, cdnUrl: client.config.cdnUrl);
// Permissions
if (AccordPermission.has(member.roles, AccordPermission.banMembers)) { /* ... */ }The REST client accepts any http.Client, and the gateway accepts a
connection factory, so you can test without real network access:
final client = AccordClient(
token: 'tok',
httpClient: myMockHttpClient, // package:http/testing.dart MockClient
connectionFactory: myFakeConnection, // GatewayConnection factory
);dart pub get
dart analyze
dart testMIT © Daccord Project