fetchChatbotConfig function

Future<ChatbotConfig?> fetchChatbotConfig({
  1. required String apiKey,
  2. required String clientUserId,
  3. String? token,
})

Implementation

Future<ChatbotConfig?> fetchChatbotConfig({
  required String apiKey,
  required String clientUserId,
  String? token,
}) async {
  try {
    final url = Uri.parse('$sdkApiUrl/chat/chatbot/get/');
    logDebug(
      '[ChatbotConfig] fetching config',
      {
        'url': url.toString(),
        'clientUserId': clientUserId,
        'hasToken': token != null,
      },
    );
    final body = jsonEncode({
      'client_user_id': clientUserId,
      'org_id': apiKey,
      'token': token,
      'extra_info': {},
    });
    logDebug('[ChatbotConfig] request payload (last call before fetch)', {'body': body});
    final response = await http.post(
      url,
      headers: {'Content-Type': 'application/json'},
      body: body,
    );
    logDebug(
      '[ChatbotConfig] response',
      {
        'status': response.statusCode,
        'ok': response.statusCode == 200,
      },
    );
    if (response.statusCode != 200) {
      logError(
        '[ChatbotConfig] non-200 response',
        {
          'status': response.statusCode,
          'body': response.body,
        },
      );
      throw Exception('Failed to fetch chatbot configuration');
    }
    final data = jsonDecode(response.body) as Map<String, dynamic>?;
    final orgInfo = data?['user']?['org_info'] as Map<String, dynamic>?;
    if (orgInfo == null) {
      logWarn('[ChatbotConfig] org_info missing in response');
      return null;
    }
    final brand = orgInfo['brand_config'] as Map<String, dynamic>?;
    if (brand == null) {
      logWarn('[ChatbotConfig] brand_config missing in response');
      return null;
    }
    final colors = brand['colors'] as Map<String, dynamic>?;
    final interfaceProps = brand['interface_properties'] as Map<String, dynamic>?;
    final images = brand['images'] as Map<String, dynamic>?;
    final launcherImg = images?['launcher_image_url'] as Map<String, dynamic>?;
    final positionStr = interfaceProps?['position']?.toString() ?? 'Right';
    final config = ChatbotConfig(
      brandColour: (colors?['brand_color'] ?? '') as String,
      imageUrl: (brand['launcher_logo_url']) as String?,
      chatInterfaceConfig: ChatInterfaceConfig(
        displayName: (brand['display_name']) as String?,
        welcomeMessage: (brand['welcome_message'] ?? 'Hey! What can we help you with today?') as String?,
        redirectUrl: (brand['redirect_url']) as String?,
      ),
      interfaceType: _parseInterfaceType(brand['interface_type']),
      interfaceProperties: WidgetInterfaceProperties(
        position: positionStr.toLowerCase() == 'left' ? WidgetPositionEnums.left : WidgetPositionEnums.right,
        sideSpacing: (interfaceProps?['side_spacing'] as num?)?.toDouble() ?? 20,
        bottomSpacing: (interfaceProps?['bottom_spacing'] as num?)?.toDouble() ?? 20,
      ),
      launcherType: _parseLauncherType(brand['launcher_type']),
      launcherProperties: {'text': (brand['launcher_properties'] is Map ? (brand['launcher_properties'] as Map)['text'] : null) ?? ''},
      images: {
        'launcher_image_url': {
          'url':
              (launcherImg?['url'] ?? sdkDefaultLauncherImage) as String,
        },
      },
      chatIframeUrl: (brand['chat_iframe_url'] ?? '') as String,
    );
    logDebug(
      '[ChatbotConfig] parsed config',
      {
        'interfaceType': brand['interface_type']?.toString(),
        'launcherType': brand['launcher_type']?.toString(),
        'position': positionStr,
      },
    );
    return config;
  } catch (e) {
    await errorTracker.trackError(
      e is Exception ? e : Exception(e.toString()),
      'ChatbotConfigRepository',
      {
        'type': ErrorTypes.networkError,
        'context': {
          'api_key_suffix':
              apiKey.isNotEmpty ? apiKey.substring(apiKey.length - 4) : '',
        },
      },
    );
    return null;
  }
}