trackEvent method
Track an event with Mixpanel including geolocation
Implementation
Future<void> trackEvent(
String eventName, {
Map<String, dynamic>? properties,
Duration timeout = const Duration(seconds: 3),
bool includeGeo = true,
}) async {
try {
final userId = _generateUserId();
// Get geolocation data
var geoData = <String, dynamic>{};
if (includeGeo) {
try {
geoData = await _getGeolocationData();
} catch (e) {
// Don't fail the event if geo lookup fails
log('Geolocation lookup failed (non-critical): $e');
}
}
final eventData = {
'event': eventName,
'properties': {
'token': _mixpanelToken,
'distinct_id': userId,
'time': DateTime.now().millisecondsSinceEpoch,
r'$insert_id':
'${userId}_${eventName}_${DateTime.now().millisecondsSinceEpoch}',
// Add CLI-specific properties
'cli_version': Platform.version,
'platform': Platform.operatingSystem,
'platform_version': Platform.operatingSystemVersion,
// Add geolocation properties with $ prefix for Mixpanel's built-in properties
if (geoData.isNotEmpty) ...{
r'$city': geoData['city'],
r'$region': geoData['region'],
r'$country_code': geoData['country_code'],
'country': geoData['country'],
'timezone': geoData['timezone'],
'isp': geoData['isp'] ?? geoData['org'],
'geo_service': geoData['service_used'],
},
// Add custom properties
if (properties != null) ...properties,
},
};
final encodedData = base64Encode(utf8.encode(json.encode(eventData)));
final response = await _httpClient
.post(
Uri.parse(_mixpanelUrl),
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'data=$encodedData',
)
.timeout(timeout);
// Mixpanel returns "1" for success
if (response.statusCode == 200 && response.body == '1') {
// Success - event tracked
return;
} else {
// Log error but don't fail the command
log(
'Mixpanel tracking failed: ${response.statusCode} - ${response.body}',
);
}
} catch (e) {
// Silently fail - don't let analytics break the CLI
log('Analytics error (non-critical): $e');
}
}