Skip to content

Commit

Permalink
Deploy 4.2.0 (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
l7ssha authored Oct 4, 2024
2 parents b49b661 + 0305498 commit fb5d6bd
Show file tree
Hide file tree
Showing 44 changed files with 1,031 additions and 164 deletions.
1 change: 1 addition & 0 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ jobs:
env:
TEST_TOKEN: ${{ secrets.TEST_TOKEN }}
TEST_GUILD: ${{ secrets.TEST_GUILD }}
TEST_TEXT_CHANNEL: ${{ secrets.TEST_TEXT_CHANNEL }}
steps:
- name: Setup Dart Action
uses: dart-lang/setup-dart@v1
Expand Down
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
## 4.2.0
__04.10.2024__

- feat: Add an alternative method for formatting dates (#27)
- feat: Add methods to stream entities from paginated endpoints (#28)
- feat: Add methods for computing permissions in a channel. (#29)
- bug: Update README.md (#32)
- feat: Restructure nyxx_extensions (#31)
- feat: Add a plugin for detecting when the client joins or leaves a guild (#33)
- feat: Add a method for fetching the children of a `CategoryChannel` (#34)
- feat: Add endpoint pagination for reactions (#35)
- feat: Add getter for everyone role in a guild (#36)
- feat: Add .toBuilder() method to GuildChannel (#39)
- feat: Add extension getter for cdn assets (#37)
- feat: Add support for sanitizing slash commands mentions (#40)
- feat: Add getInviteUrl extension for PartialApplications (#41)
- feat: Add utilities for fetching lists of entities (#42)
- feat: Add extension to get a member's highest role (#43)

## 4.1.0
__15.11.2023__

- Added a helper to reply to a message.
- Fixed an issue with paginating back to a page that had already been seen.

## 4.0.0
__20.10.2023__

- Fixed an issue with link formatting.

## 4.0.0-dev.1
__17.09.2023__

- Bump nyxx to `6.0.0`. See the changelog at https://pub.dev/packages/nyxx for more information.
- Removed helpers now in the nyxx package.
- Added pagination support.

## 3.2.0
__10.09.2023__

- Bump nyxx to `4.2.0`
- Correctly export `acronym` property on guild
Expand Down
56 changes: 20 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,40 @@
# nyxx_extensions

[![Discord Shield](https://discordapp.com/api/guilds/846136758470443069/widget.png?style=shield)](https://discord.gg/nyxx)
[![pub](https://img.shields.io/pub/v/nyxx.svg)](https://pub.dartlang.org/packages/nyxx_extensions)
[![documentation](https://img.shields.io/badge/Documentation-nyxx_interactions-yellow.svg)](https://www.dartdocs.org/documentation/nyxx_extensions/latest/)
[![Discord](https://discordapp.com/api/guilds/846136758470443069/widget.png?style=shield)](https://discord.gg/nyxx)
[![pub](https://img.shields.io/pub/v/nyxx_extensions.svg)](https://pub.dev/packages/nyxx_extensions)
[![documentation](https://img.shields.io/badge/Documentation-nyxx__extensions-yellow.svg)](https://pub.dev/documentation/nyxx_extensions/latest/)

Simple, robust framework for creating discord bots for Dart language.
Additional utilities and helpers for working with [nyxx](https://pub.dev/packages/nyxx).

<hr />
While the main [nyxx](https://pub.dev/packages/nyxx) package focuses on providing a wrapper only for the features described in [Discord's developer documentation](https://discord.com/developers/docs/intro), this package contains a collection of commonly used functions and plugins when making Discord bots, such as [pagination](https://pub.dev/documentation/nyxx_extensions/latest/nyxx_extensions/Pagination-class.html), [sanitization](https://pub.dev/documentation/nyxx_extensions/latest/nyxx_extensions/sanitizeContent.html) or [endpoint pagination](https://pub.dev/documentation/nyxx_extensions/latest/search.html?q=stream).

### Features

Additional extensions and subpackages to ease out developing bots in nyxx framework.
This package is very open to contributions as it is built upon the needs of developers using [nyxx](https://pub.dev/packages/nyxx). If you find yourself implementing a feature that isn't specific to your bot, please consider [opening a pull request](https://github.com/nyxx-discord/nyxx_extensions/pulls) and add your code to this package. Read our [contribution document](https://github.com/nyxx-discord/nyxx_extensions/blob/dev/CONTRIBUTING.md) for more information.

## Other nyxx packages

- [nyxx](https://github.com/nyxx-discord/nyxx)
- [nyxx_interactions](https://github.com/nyxx-discord/nyxx_interactions)
- [nyxx_commander](https://github.com/nyxx-discord/nyxx_commander)
- [nyxx_lavalink](https://github.com/nyxx-discord/nyxx_lavalink)
- [nyxx_pagination](https://github.com/nyxx-discord/nyxx_pagination)

## More examples

Nyxx examples can be found [here](https://github.com/nyxx-discord/nyxx_extensions/tree/dev/example).
- [nyxx](https://pub.dev/packages/nyxx): The main package wrapping Discord's developer API.
- [nyxx_commands](https://pub.dev/packages/nyxx_commands): A command framework for handling both simple & complex commands.
- [nyxx_lavalink](https://pub.dev/packages/nyxx_lavalink): Lavalink support for playing audio in voice channels.

### Example bots
- [Running on Dart](https://github.com/l7ssha/running_on_dart)
## Additional documentation & help

## Documentation, help and examples
The API documentation for the latest stable version can be found on [pub](https://pub.dev/documentation/nyxx).

**Dartdoc documentation for latest stable version is hosted on [pub](https://www.dartdocs.org/documentation/nyxx_extensions/latest/)**
### [Docs and wiki](https://nyxx.l7ssha.xyz)
Tutorials and wiki articles are hosted here, as well as API documentation for development versions from GitHub.

#### [Docs and wiki](https://nyxx.l7ssha.xyz)
You can read docs and wiki articles for latest stable version on my website. This website also hosts docs for latest
dev changes to framework (`dev` branch)
### [Official nyxx Discord server](https://discord.gg/nyxx)
Our Discord server is where you can get help for any nyxx packages, as well as release announcements and discussions about the library.

#### [Official nyxx discord server](https://discord.gg/nyxx)
If you need assistance in developing bot using nyxx you can join official nyxx discord guild.
### [Discord API docs](https://discord.dev/)
Discord's API documentation details what nyxx implements & provides more detailed explanations of certain topics.

#### [Discord API docs](https://discordapp.com/developers/docs/intro)
Discord API documentation features rich descriptions about all topics that nyxx covers.

#### [Discord API Guild](https://discord.gg/discord-api)
### [Discord API Server](https://discord.gg/discord-api)
The unofficial guild for Discord Bot developers. To get help with nyxx check `#dart_nyxx` channel.

#### [Dartdocs](https://www.dartdocs.org/documentation/nyxx_extensions/latest/)
### [Pub.dev docs](https://pub.dev/documentation/nyxx)
The dartdocs page will always have the documentation for the latest release.

## Contributing to Nyxx

Read [contributing document](https://github.com/nyxx-discord/nyxx_extensions/blob/dev/CONTRIBUTING.md)

## Credits

* [Hackzzila's](https://github.com/Hackzzila) for [nyx](https://github.com/Hackzzila/nyx).
Read the [contributing document](https://github.com/nyxx-discord/nyxx/blob/dev/CONTRIBUTING.md)
12 changes: 11 additions & 1 deletion example/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void main() async {
// Sanitizing content makes it safe to send to Discord without triggering any mentions
client.onMessageCreate.listen((event) async {
if (event.message.content.startsWith('!sanitize')) {
event.message.channel.sendMessage(MessageBuilder(
await event.message.channel.sendMessage(MessageBuilder(
content: 'Sanitized content: ${await sanitizeContent(event.message.content, channel: event.message.channel)}',
));
}
Expand Down Expand Up @@ -67,5 +67,15 @@ ullamcorper morbi tincidunt ornare.
}
});

client.onMessageCreate.listen((event) async {
if (event.message.content.startsWith('!avatar') && event.message.mentions.isNotEmpty) {
// Display the first mentioned user's avatar with the specified size.
final user = event.message.mentions.first;
await event.message.channel.sendMessage(MessageBuilder(
content: 'Avatar URL: ${user.avatar.get(format: CdnFormat.jpeg, size: 3072)}',
));
}
});

// ...and more!
}
41 changes: 31 additions & 10 deletions lib/nyxx_extensions.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
/// Extensions and additional utilities for working with [nyxx](https://pub.dev/packages/nyxx).
library nyxx_extensions;

export 'src/channel.dart';
export 'src/date_time.dart';
export 'src/embed_builder.dart';
export 'src/emoji.dart';
export 'src/guild.dart';
export 'src/message.dart';
export 'src/pagination.dart';
export 'src/role.dart';
export 'src/sanitizer.dart';
export 'src/user.dart';
export 'src/utils/emoji.dart';
export 'src/utils/endpoint_paginator.dart' hide streamPaginatedEndpoint;
export 'src/utils/formatters.dart';
export 'src/utils/guild_joins.dart';
export 'src/utils/pagination.dart';
export 'src/utils/permissions.dart';
export 'src/utils/sanitizer.dart';

export 'src/extensions/cdn_asset.dart' hide getRequest;
export 'src/extensions/channel.dart';
export 'src/extensions/client.dart';
export 'src/extensions/date_time.dart';
export 'src/extensions/embed.dart';
export 'src/extensions/emoji.dart';
export 'src/extensions/guild.dart';
export 'src/extensions/managers/audit_log_manager.dart';
export 'src/extensions/managers/channel_manager.dart';
export 'src/extensions/managers/entitlement_manager.dart';
export 'src/extensions/managers/guild_manager.dart';
export 'src/extensions/managers/member_manager.dart';
export 'src/extensions/managers/message_manager.dart';
export 'src/extensions/managers/scheduled_event_manager.dart';
export 'src/extensions/managers/user_manager.dart';
export 'src/extensions/member.dart';
export 'src/extensions/message.dart';
export 'src/extensions/role.dart';
export 'src/extensions/scheduled_event.dart';
export 'src/extensions/snowflake_entity.dart';
export 'src/extensions/user.dart';
export 'src/extensions/list.dart';
export 'src/extensions/application.dart';
12 changes: 0 additions & 12 deletions lib/src/channel.dart

This file was deleted.

23 changes: 23 additions & 0 deletions lib/src/extensions/application.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'package:nyxx/nyxx.dart';

/// Extensions on [PartialApplication]s.
extension ApplicationExtensions on PartialApplication {
/// Get a URL users can visit to add this bot to a guild.
Uri getInviteUri({
List<String> scopes = const ['bot', 'application.commands'],
Flags<Permissions>? permissions,
Snowflake? guildId,
bool? disableGuildSelect,
}) =>
Uri.https(
'discord.com',
'/oauth2/authorize',
{
'client_id': id.toString(),
'scope': scopes.join(' '),
if (permissions != null) 'permissions': permissions.value.toString(),
if (guildId != null) 'guild_id': guildId.toString(),
if (disableGuildSelect != null) 'disable_guild_select': disableGuildSelect,
},
);
}
22 changes: 22 additions & 0 deletions lib/src/extensions/cdn_asset.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'package:nyxx/nyxx.dart';

extension CdnAssetExtensions on CdnAsset {
Uri get({CdnFormat? format, int? size}) => getRequest(this, format ?? defaultFormat, size).prepare(client).url;
}

// Re-implementing the private method from CdnAsset
CdnRequest getRequest(CdnAsset asset, CdnFormat format, int? size) {
final route = HttpRoute();

for (final part in asset.base.parts) {
route.add(part);
}
route.add(HttpRoutePart('${asset.hash}.${format.extension}'));

return CdnRequest(
route,
queryParameters: {
if (size != null) 'size': size.toString(),
},
);
}
128 changes: 128 additions & 0 deletions lib/src/extensions/channel.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import 'package:nyxx/nyxx.dart';
import 'package:nyxx_extensions/src/extensions/guild.dart';
import 'package:nyxx_extensions/src/extensions/managers/channel_manager.dart';
import 'package:nyxx_extensions/src/utils/formatters.dart';
import 'package:nyxx_extensions/src/utils/permissions.dart';

/// Extensions on [PartialChannel]s.
extension PartialChannelExtensions on PartialChannel {
/// A mention of this channel.
String get mention => channelMention(id);
}

/// Extensions on [Channel]s.
extension ChannelExtensions on Channel {
/// A URL clients can visit to navigate to this channel.
Uri get url => Uri.https(manager.client.apiOptions.host, '/channels/${this is GuildChannel ? '${(this as GuildChannel).guildId}' : '@me'}/$id');
}

/// Extensions on [GuildChannel]s.
extension GuildChannelExtensions on GuildChannel {
/// Compute [member]'s permissions in this channel.
///
/// {@macro compute_permissions_detail}
Future<Permissions> computePermissionsFor(PartialMember member) async => await computePermissions(this, await member.get());
}

/// Extensions on all [GuildChannel] types
extension GuildChannelsExtension<T extends GuildChannel> on T {
/// Create a builder with the properties of this channel
GuildChannelBuilder<T> toBuilder() => switch (this) {
GuildTextChannel channel => GuildTextChannelBuilder(
name: channel.name,
defaultAutoArchiveDuration: channel.defaultAutoArchiveDuration,
isNsfw: channel.isNsfw,
parentId: channel.parentId,
permissionOverwrites: channel.permissionOverwrites
.map((e) => PermissionOverwriteBuilder(
id: e.id,
type: e.type,
allow: e.allow,
deny: e.deny,
))
.toList(),
position: channel.position,
rateLimitPerUser: channel.rateLimitPerUser,
topic: channel.topic,
) as GuildChannelBuilder<T>,
GuildVoiceChannel channel => GuildVoiceChannelBuilder(
name: channel.name,
permissionOverwrites:
channel.permissionOverwrites.map((e) => PermissionOverwriteBuilder(id: e.id, type: e.type, allow: e.allow, deny: e.deny)).toList(),
position: channel.position,
isNsfw: channel.isNsfw,
parentId: channel.parentId,
bitRate: channel.bitrate,
rtcRegion: channel.rtcRegion,
userLimit: channel.userLimit,
videoQualityMode: channel.videoQualityMode,
) as GuildChannelBuilder<T>,
GuildStageChannel channel => GuildStageChannelBuilder(
name: channel.name,
bitRate: channel.bitrate,
isNsfw: channel.isNsfw,
parentId: channel.parentId,
permissionOverwrites:
channel.permissionOverwrites.map((e) => PermissionOverwriteBuilder(id: e.id, type: e.type, allow: e.allow, deny: e.deny)).toList(),
position: channel.position,
rtcRegion: channel.rtcRegion,
userLimit: channel.userLimit,
videoQualityMode: channel.videoQualityMode,
) as GuildChannelBuilder<T>,
PrivateThread thread => ThreadBuilder.privateThread(
name: thread.name,
autoArchiveDuration: thread.autoArchiveDuration,
invitable: thread.isInvitable,
rateLimitPerUser: thread.rateLimitPerUser,
) as GuildChannelBuilder<T>,
PublicThread thread => ThreadBuilder.publicThread(
name: thread.name,
autoArchiveDuration: thread.autoArchiveDuration,
rateLimitPerUser: thread.rateLimitPerUser,
) as GuildChannelBuilder<T>,
GuildCategory category => GuildCategoryBuilder(
name: category.name,
permissionOverwrites:
category.permissionOverwrites.map((e) => PermissionOverwriteBuilder(id: e.id, type: e.type, allow: e.allow, deny: e.deny)).toList(),
position: category.position,
) as GuildChannelBuilder<T>,
GuildAnnouncementChannel channel => GuildAnnouncementChannelBuilder(
name: channel.name,
defaultAutoArchiveDuration: channel.defaultAutoArchiveDuration,
isNsfw: channel.isNsfw,
parentId: channel.parentId,
permissionOverwrites:
channel.permissionOverwrites.map((e) => PermissionOverwriteBuilder(id: e.id, type: e.type, allow: e.allow, deny: e.deny)).toList(),
position: channel.position,
topic: channel.topic,
) as GuildChannelBuilder<T>,
_ => GuildChannelBuilder(
name: name,
type: type,
position: position,
permissionOverwrites: permissionOverwrites.map((e) => PermissionOverwriteBuilder(id: e.id, type: e.type, allow: e.allow, deny: e.deny)).toList(),
),
};
}

/// Extensions on [Thread]s.
extension ThreadExtensions on Thread {
/// Same as [listThreadMembers], but has no limit on the number of members returned.
///
/// {@macro paginated_endpoint_streaming_parameters}
Stream<ThreadMember> streamThreadMembers({bool? withMembers, Snowflake? after, Snowflake? before, int? pageSize}) =>
manager.streamThreadMembers(id, withMembers: withMembers, after: after, before: before, pageSize: pageSize);
}

/// Extensions on [GuildCategory]s.
extension GuildCategoryExtensions on GuildCategory {
/// Fetch the channels in this category.
Future<List<GuildChannel>> fetchChannels() async {
final guildChannels = await guild.fetchChannels();

return guildChannels.where((element) => element.parentId == id).toList();
}

/// Return a list of channels in the client's cache that are in this category.
List<GuildChannel> get cachedChannels => guild.cachedChannels.where((element) => element.parentId == id).toList();
}
Loading

0 comments on commit fb5d6bd

Please sign in to comment.