wait method

Future<CTX> wait([
  1. Duration? timeout
])

Waits for the next update from the user with optional timeout.

This method pauses the conversation and waits for the user to send another message, press a button, etc. If no update is received within the timeout period, a ConversationTimeoutException is thrown.

Parameters:

  • timeout: Custom timeout for this wait operation. Defaults to plugin's defaultTimeout.

Returns the context of the next update.

Throws ConversationTimeoutException if the timeout is exceeded.

Example:

try {
  await ctx.reply('What is your favorite color?');
  final response = await conversation.wait(Duration(minutes: 2));
  await response.reply('${response.text} is a great color!');
} on ConversationTimeoutException {
  await ctx.reply('You took too long to respond!');
}

Implementation

Future<CTX> wait([Duration? timeout]) async {
  final effectiveTimeout = timeout ?? _defaultTimeout;

  // Create completer for this wait
  final completer = Completer<CTX>();

  // Set up timeout timer
  Timer? timeoutTimer;
  if (effectiveTimeout != Duration.zero) {
    timeoutTimer = Timer(effectiveTimeout, () {
      if (!completer.isCompleted) {
        _plugin._waitingConversations.remove(_storageKey);
        completer
            .completeError(ConversationTimeoutException(_conversationName));

        // Notify about timeout if callback is provided
        _plugin.onConversationTimeout?.call(_conversationName, null);
      }
    });
  }

  // Store the waiting conversation
  _plugin._waitingConversations[_storageKey] = _WaitingConversation<CTX>(
    completer: completer,
    timeoutTimer: timeoutTimer,
    conversationName: _conversationName,
  );

  // Mark conversation as waiting with expiry time
  final expiresAt = DateTime.now().add(effectiveTimeout);
  final state = ConversationState(
    conversationName: _conversationName,
    isActive: true,
    lastUpdated: DateTime.now(),
    expiresAt: expiresAt,
  );
  await _storage.set(_storageKey, state);

  try {
    // Wait for the next update
    final ctx = await completer.future;
    return ctx;
  } catch (e) {
    // Clean up on any error
    timeoutTimer?.cancel();
    _plugin._waitingConversations.remove(_storageKey);
    rethrow;
  }
}