Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
Merge pull request #47 from nyxx-discord/hotfix/application-overrides
Browse files Browse the repository at this point in the history
Implement application level permission overrides
  • Loading branch information
abitofevrything authored May 3, 2022
2 parents 5fa84ea + 953c7e1 commit 4c21707
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 4.2.1
__02.05.2022__

- bug: Allow application level permission overrides

## 4.2.0
__29.04.2022__

Expand Down
7 changes: 7 additions & 0 deletions lib/src/interactions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ abstract class IInteractions {
/// Fetches all guild commands for given guild
Stream<ISlashCommand> fetchGuildCommands(Snowflake guildId);

/// Returns the global overrides for commands in a guild.
Cacheable<Snowflake, ISlashCommandPermissionOverrides> getGlobalOverridesInGuild(Snowflake guildId);

static IInteractions create(InteractionBackend backend) => Interactions(backend);
}

Expand Down Expand Up @@ -312,6 +315,10 @@ class Interactions implements IInteractions {
@override
Stream<ISlashCommand> fetchGuildCommands(Snowflake guildId) => interactionsEndpoints.fetchGuildCommands(client.appId, guildId);

@override
Cacheable<Snowflake, ISlashCommandPermissionOverrides> getGlobalOverridesInGuild(Snowflake guildId) =>
SlashCommandPermissionOverridesCacheable(client.appId, guildId, this);

void _extractCommandIds(List<ISlashCommand> commands) {
for (final slashCommand in commands) {
_commandBuilders.firstWhere((element) => element.name == slashCommand.name && element.guild == slashCommand.guild?.id).setId(slashCommand.id);
Expand Down
45 changes: 42 additions & 3 deletions lib/src/internal/interaction_endpoints.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import 'dart:convert';

import 'package:logging/logging.dart';
import 'package:nyxx/nyxx.dart';
import 'package:nyxx/src/core/message/message.dart';
import 'package:nyxx_interactions/nyxx_interactions.dart';
Expand Down Expand Up @@ -82,12 +85,17 @@ abstract class IInteractionsEndpoints {

/// Fetch the command permission overrides for a command in a guild.
Future<ISlashCommandPermissionOverrides> fetchCommandOverrides(Snowflake commandId, Snowflake guildId);

/// Fetch the permission overrides for all commands in a guild. The global overrides for that guild have an ID which is equal to the application ID.
Future<Iterable<ISlashCommandPermissionOverrides>> fetchPermissionOverrides(Snowflake guildId);
}

class InteractionsEndpoints implements IInteractionsEndpoints {
final INyxx _client;
final Interactions _interactions;

final Logger _logger = Logger('Interactions');

InteractionsEndpoints(this._client, this._interactions);

@override
Expand Down Expand Up @@ -378,15 +386,46 @@ class InteractionsEndpoints implements IInteractionsEndpoints {
}
}

/// Fetch the command permission overrides for a command in a guild.
@override
Future<SlashCommandPermissionOverrides> fetchCommandOverrides(Snowflake commandId, Snowflake guildId) async {
final response = await _client.httpEndpoints.sendRawRequest("/applications/${_client.appId}/guilds/$guildId/commands/$commandId/permissions", "GET");
try {
final response =
await _client.httpEndpoints.sendRawRequest("/applications/${_client.appId}/guilds/$guildId/commands/$commandId/permissions", "GET", auth: true);

return SlashCommandPermissionOverrides((response as IHttpResponseSucess).jsonBody as Map<String, dynamic>, _client);
} on IHttpResponseError catch (response) {
try {
// 10066 = Unknown application command permissions
// Means there are no overrides for this command... why is this an error, Discord?
if (jsonDecode(response.errorMessage)['code'] == 10066) {
_logger.finest('Got error code 10066 on permissions for command $commandId in guild $guildId, returning empty permission overrides.');
return SlashCommandPermissionOverrides.empty(commandId, _client);
}
} on Exception {
// We got invalid JSON. The request is probably invalid, so we ignore it and return an error.
_logger.warning('Invalid JSON in response: ${response.errorMessage}');
}

return Future.error(response);
}
}

@override
Future<List<ISlashCommandPermissionOverrides>> fetchPermissionOverrides(Snowflake guildId) async {
final response = await _client.httpEndpoints.sendRawRequest("/applications/${_client.appId}/guilds/$guildId/commands/permissions", "GET", auth: true);

if (response is IHttpResponseError) {
return Future.error(response);
}

return SlashCommandPermissionOverrides((response as IHttpResponseSucess).jsonBody as Map<String, dynamic>, _client);
List<SlashCommandPermissionOverrides> overrides =
((response as IHttpResponseSucess).jsonBody as List<dynamic>).cast<RawApiMap>().map((d) => SlashCommandPermissionOverrides(d, _client)).toList();

for (final override in overrides) {
_interactions.permissionOverridesCache[guildId] ??= {};
_interactions.permissionOverridesCache[guildId]![override.id] = override;
}

return overrides;
}
}
12 changes: 12 additions & 0 deletions lib/src/models/slash_command_permission.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,29 @@ class SlashCommandPermissionOverride implements ISlashCommandPermissionOverride
abstract class ISlashCommandPermissionOverrides implements SnowflakeEntity {
/// The permissions attached to the command.
List<SlashCommandPermissionOverride> get permissionOverrides;

/// Whether these overrideas are global across all commands in a guild.
bool get isGlobal;
}

class SlashCommandPermissionOverrides extends SnowflakeEntity implements ISlashCommandPermissionOverrides {
@override
late final List<SlashCommandPermissionOverride> permissionOverrides;
@override
late final bool isGlobal;

SlashCommandPermissionOverrides(RawApiMap raw, INyxx client) : super(Snowflake(raw['id'])) {
permissionOverrides = [
for (final override in (raw['permissions'] as List<dynamic>).cast<Map<String, dynamic>>())
SlashCommandPermissionOverride(override, Snowflake(raw["guild_id"]), client),
];

isGlobal = id == client.appId;
}

SlashCommandPermissionOverrides.empty(Snowflake commandId, INyxx client) : super(commandId) {
permissionOverrides = [];
isGlobal = id == client.appId;
}
}

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: nyxx_interactions
version: 4.2.0
version: 4.2.1
description: Nyxx Interactions Module. Discord library for Dart. Simple, robust framework for creating discord bots for Dart language.
homepage: https://github.com/nyxx-discord/nyxx
repository: https://github.com/nyxx-discord/nyxx
Expand Down

0 comments on commit 4c21707

Please sign in to comment.