handleAutocomplete method
Implementation
@override
Future<void> handleAutocomplete(Map<String, dynamic> payload) async {
final data = payload['data'] as Map<String, dynamic>?;
if (data == null) {
_marshaller.logger.warn('Autocomplete payload missing "data" field');
return;
}
final rootName = data['name'] as String?;
if (rootName == null) {
_marshaller.logger.warn('Autocomplete payload missing command name');
return;
}
final rawOptions = data['options'];
if (rawOptions == null) {
_marshaller.logger.warn('Autocomplete payload has no options');
return;
}
// Find focused option recursively.
final focused = _findFocused(rawOptions as Iterable<dynamic>);
if (focused == null) {
_marshaller.logger.warn(
'No focused option found in autocomplete payload',
);
return;
}
final optionName = focused['name'] as String;
final optionValue = '${focused['value'] ?? ''}';
// Collect other options (non-focused).
final otherOptions = <String, dynamic>{};
_collectNonFocused(rawOptions, otherOptions);
// Look up handler.
final commandHandlers = _autocompleteHandlers[rootName];
final handler = commandHandlers?[optionName];
if (handler == null) {
_marshaller.logger.warn(
'No autocomplete handler for command "$rootName" option "$optionName"',
);
return;
}
final ctx = AutocompleteContext(
name: optionName,
value: optionValue,
options: otherOptions,
);
final choices = await handler(ctx);
// Discord allows max 25 choices.
final capped = choices.length > 25 ? choices.take(25).toList() : choices;
final id = Snowflake.parse(payload['id'] as String);
final token = payload['token'] as String;
await _dataStore.interaction.sendAutocompleteResult(id, token, capped);
}