din 0.1.0-alpha+8

  • Readme
  • Changelog
  • Installing
  • 0


An unofficial Dart library for Discord.

Uses Dart 1.25.0-dev License Pub Package Build Status

GitHub Issues GitHub Forks GitHub Stars

Install #

The current pre-release of din does not require other runtime dependencies.

  din: ^0.1.0-alpha+5

To get started, it's recommended to read the Discord documentation and create an application for API access.

Usage #

It's recommended to import din prefixed whenever possible:

import 'package:din/din.dart' as din;

Platforms #

Currently this library is only supported on the standalone VM and Flutter, but can be easily expanded by implementing a custom HttpClient. See the VM implementation at lib/platform/vm.dart for an example. You can then pass the client in:

void main() {
  final client = const din.ApiClient(
    rest: const din.RestClient(
      auth: const din.AuthScheme.asBot('YOUR_TOKEN_HERE'),
      http: const CustomHttpClient(),

class CustomHttpClient implements din.HttpClient { /* TODO: Implement. */ }

Contributing #

Discord API Changes #

As explained below, the REST API endpoints for Discord are manually specified but much/almost all of the boilerplate code around JSON encoding and generating URLs is handled by offline code generation, and published as part of this package.


  • tool/codegen/resource.dart
  • tool/codegen/structure.dart

The current implementation is fairly ad-hoc, and does not yet support all the different use-cases in the Discord API. That is also OK; the API is flexible in that some of the methods can be implemented by hand if needed, and the others are generated.

If you make a change to anything in lib/src/schema/** or the code generators re-run the build script at tool/build.dart to update <file>.g.dart files:

$ dart tool/build.dart

Or, leave a watcher open to automatically rebuild:

$ dart tool/build.dart --watch

Testing #

The easiest way to run all the unit tests with the precise configuration needed is to run tool/test.dart. This in turn runs a series of web servers (as needed) for local testing, and pub run test to execute the test cases:

$ dart tool/test.dart

For manual testing, (i.e. running/debugging a specific test):

  • Run tool/servers/static.dart before running any HTTP client tests:
$ dart tool/servers/static.dart


$ pub run test test/clients/http_client_vm_test.dart

End-to-end testing #

Sometimes when changing the API, or releasing a new version of this library it is important to verify that the entire end-to-end story still works connected to the real Discord API server.

Tests in the e2e/** folder do this, but are part of tool/test.dart in order to avoid overloading Discord's servers from continuous integration systems like travis. In order to run manually, or on something like a cron-job, run:

$ DISCORD_API_TOKEN='1234' DISCORD_CHANNEL_ID='1234' DISCORD_USER_NAME='...' pub run test e2e

Note that all variables above must be set as an environment variable to use these tests. If you do not have one, login to discord and create an application. Do not share this token with others, it should remain private. Make sure to add access for your bot to connect and interact with the channel specified by DISCORD_CHANNEL_ID.

You may optionally add a config.yaml file to e2e/config.yaml instead; it is ignored by .gitignore and is for convenience while developing locally.

api_token:  "..."
channel_id: "..."
user_name:  "..."

Design #

The din package is built to be layered, customizable, and easily hackable, both for direct contributors to the package, and for packages built on top of din. There are three "tiers" of APIs available, each with high-level functionality:


Din provides a minimal, platform-independent HTTP interface, or HttpClient:

abstract class HttpClient {
  /// Sends an HTTP request to [path] using [method].
  /// May optionally define a [payload] and HTTP [headers].
  /// Unlike a standard [Future], a [CancelableOperation] may be cancelled if
  /// the in-flight request is no longer valid or wanted. In that event, the
  /// [CancelableOperation.value] may never complete.
  CancelableOperation<Map<String, Object>> requestJson(
    String path, {
    String method: 'GET',
    Map<String, Object> payload,
    Map<String, String> headers,

While this itself is not that useful for building a bot or application, it does provide a very simple way to create custom HTTP implementations, such as those that do caching, offline support, or work on a variety of platforms. The built-in/default implementation works on the standalone Dart VM and Flutter.


The official Discord API is REST-based, and requires a series of HTTP headers in order to communicate. This is encapsulated as RestClient, which in turn can make an HTTP request to any given REST endpoint. It does not have knowledge of the precise endpoints of the Discord API, though, and only communicates in raw/untyped JSON.

Creating one is required to use ApiClient, the highest-level API provided:

final rest = const din.RestClient(
  auth: const din.AuthScheme.asBot('YOUR_TOKEN_HERE'),

For clients or libraries that do not want to use ApiClient, they can use RestClient in order to remove much of the boiler-plate around how to connect and utilize the REST API.


A semi-automatically updated high-level API for communicating with precise REST endpoints in the Discord API used strongly-typed methods, returning strongly typed Dart objects. There is no official schema provided by the Discord team, so instead the schema is hand-maintained as metadata annotations, and the exact API is generated from that.

See tool/build.dart, and lib/src/schema/** for more information.

0.1.0-alpha+8 #

  • Made JSON parse failures more debuggable - throws a FormatException.
  • Fixed a number of subtle bugs in the generated JSON parsers.

0.1.0-alpha+7 #

  • Updated to code_builder: ^2.0.0-alpha+3.

  • Fixed a bug where List<Structure> types always returned List<Map>. #11

  • Split most of the Gateway events into GatewayClient.events.

  • Renamed GatewayReady to Ready, and moved to GatewayEvents.ready.

  • Add support for resuming a connection (ApiClient.resume).

0.1.0-alpha+6 #

  • Added FakeHttpClient in platform/test.dart for simple testing.
  • Changed GatewayClient.onMessage to emit a Message payload.
  • Fixed a bug in the heartbeat mechanic.
  • Added Message#channelId.

0.1.0-alpha+5 #

  • HttpClient now throws an HttpClientException on an HTTP or network error.
  • WebSocketClient, GatewayClient now support Future<String> get onClose.
  • Added ability to customize the initial identification to GatewayClient:
doConnect() async {
  await apiClient.connect(gateway.url, onIdentify: (strategy) {
    return strategy.asBrowser('...');
  • GatewayClient#onReady now returns a GatewayReady event.
  • GatewayClient#onSequence emits sequence codes, when received. These are used internally to reply to heartbeats, but will also be usable in a future release to do a resume action (instead of an initial connection).

0.1.0-alpha+4 #

  • Added incomplete web socket and gateway support:
test('should return a WSS gateway and be able to connect to it', () async {
  final gateway = await apiClient.gateway.getGatewayBot();
  expect(gateway.url, isNotEmpty);
  expect(gateway.shards, greaterThan(0));

  final connection = await apiClient.connect(gateway.url);
  expect(await connection.onHello, isList);
  expect(await connection.onReady, isNotNull);
  await connection.close();

0.1.0-alpha+3 #

  • Now exporting structures and resources via the main din.dart import.
  • Changes the definition of REST/requestJson to Object (may be a List)
  • Renamed Field#nullable to Field#optional.
  • Removed Field.type and FieldType which was not used.
  • Added channels.getMessages, adding support for APIs that return List<T>.
  • Added more fields to Channel, ChannelType, and support for enum types.
  • Added support for DateTime from an ISO date string.

0.1.0-alpha+2 #

  • Added support for channels.createMessage.
  • Added support for users.getCurrentUser.
  • Fixed a bug where JSON payloads did not have the right Content-Type.
  • Added the User and Message structures.

0.1.0-alpha+1 #

  • Small change to REAMDE.md.

0.1.0-alpha #

  • Initial release, mostly as a proof-of-concept only. See README.md.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  din: ^0.1.0-alpha+8

2. Install it

You can install packages from the command line:

with pub:

$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:din/din.dart';
Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

The package version is not analyzed, because it does not support Dart 2. Until this is resolved, the package will receive a health and maintenance score of 0.

Analysis issues and suggestions

Support Dart 2 in pubspec.yaml.

The SDK constraint in pubspec.yaml doesn't allow the Dart 2.0.0 release. For information about upgrading it to be Dart 2 compatible, please see https://dart.dev/dart-2#migration.

Maintenance issues and suggestions

Make sure dartdoc successfully runs on your package's source files. (-10 points)

Dependencies were not resolved.


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.25.0-dev <2.0.0-dev.infinity