Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add telemetry [#81] #94

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/clerk_auth/lib/clerk_auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export 'src/clerk_api/api.dart';
export 'src/clerk_auth/auth.dart';
export 'src/clerk_auth/persistor.dart';
export 'src/models/models.dart';
export 'src/models/telemetry/telemetric_event.dart';
export 'src/utils/extensions.dart';
export 'src/utils/logging.dart';
6 changes: 6 additions & 0 deletions packages/clerk_auth/lib/clerk_constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ sealed class ClerkConstants {

/// value for the `x-flutter-sdk-version` header in API requests
static const flutterSdkVersion = '0.0.4-dev';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's auto-generate this.


/// Name of the SDK
static const sdkName = '@clerk/flutter';
shinyford marked this conversation as resolved.
Show resolved Hide resolved

/// JsVersion of API
static const jsVersion = '4.70.0';
}
24 changes: 21 additions & 3 deletions packages/clerk_auth/lib/src/clerk_api/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class Api with Logging {

static const _defaultPollDelay = Duration(seconds: 55);

static final _telemetryEndpoint =
Uri.parse('https://clerk-telemetry.com/v1/event');

/// Initialise the API
Future<void> initialize() async {
await _tokenCache.initialize();
Expand All @@ -91,6 +94,21 @@ class Api with Logging {
///
String get domain => _domain;

/// Sends a map of data to the telemtry endpoint
shinyford marked this conversation as resolved.
Show resolved Hide resolved
///
Future<void> sendTelemetry(List<TelemetricEvent> events) async {
await _client.send(
HttpMethod.post,
_telemetryEndpoint,
body: json.encode({
'events': [...events.map((e) => e.toJson())],
}),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
},
);
}

/// Returns the latest [Environment] from Clerk.
///
Future<Environment> environment() async {
Expand Down Expand Up @@ -210,7 +228,7 @@ class Api with Logging {
'code': code,
'token': token,
if (metadata is Map) //
'unsafe_metadata': jsonEncode(metadata!),
'unsafe_metadata': json.encode(metadata!),
},
);
}
Expand Down Expand Up @@ -246,7 +264,7 @@ class Api with Logging {
'code': code,
'token': token,
if (metadata is Map) //
'unsafe_metadata': jsonEncode(metadata!),
'unsafe_metadata': json.encode(metadata!),
},
);
}
Expand Down Expand Up @@ -650,7 +668,7 @@ class Api with Logging {
}) =>
{
_kIsNative: true,
_kClerkJsVersion: Auth.jsVersion,
_kClerkJsVersion: ClerkConstants.jsVersion,
if (withSession) //
_kClerkSessionId: _tokenCache.sessionId,
if (method.isGet) //
Expand Down
45 changes: 41 additions & 4 deletions packages/clerk_auth/lib/src/clerk_auth/auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ export 'persistor.dart';
class Auth {
/// Create an [Auth] object using appropriate Clerk credentials
shinyford marked this conversation as resolved.
Show resolved Hide resolved
Auth({
required String publishableKey,
required this.publishableKey,
required Persistor persistor,
this.telemetry = true,
HttpClient? client,
SessionTokenPollMode pollMode = SessionTokenPollMode.onDemand,
}) : _api = Api(
Expand All @@ -35,16 +36,26 @@ class Auth {
pollMode: pollMode,
);

/// The injected Clerk publishable key
final String publishableKey;

/// Whether or not to send telemetry data (default true)
final bool telemetry;

final Api _api;

static const _codeLength = 6;

/// JsVersion of API
static const jsVersion = '4.70.0';

/// default redirect URL for use with oAuth
static const oauthRedirect = 'https://www.clerk.com/oauth-redirect';

/// Are we in development mode?
bool get isDevMode => env.display.instanceEnvironmentType.isDevelopment;

static const _telemetryPeriod = Duration(seconds: 27);
shinyford marked this conversation as resolved.
Show resolved Hide resolved
static final _telemetricEvents = <TelemetricEvent>[];
shinyford marked this conversation as resolved.
Show resolved Hide resolved
static Timer? _telemetryTimer;

/// The [Environment] object
///
/// configuration of the Clerk account - rarely changes
Expand Down Expand Up @@ -121,6 +132,32 @@ class Auth {
return resp;
}

/// Send a telemetry event to the backend.
///
Future<void> sendTelemetry(
String event, {
required Map<String, dynamic> payload,
}) async {
if (isDevMode && telemetry) {
_telemetricEvents.add(
TelemetricEvent(
event: event,
it: env.display.instanceEnvironmentType.toString(),
pk: publishableKey,
payload: payload,
),
);
_telemetryTimer ??= Timer(_telemetryPeriod, _sendTelemetry);
shinyford marked this conversation as resolved.
Show resolved Hide resolved
}
}

Future<void> _sendTelemetry() async {
final events = [..._telemetricEvents];
_telemetricEvents.clear();
_telemetryTimer = null;
await _api.sendTelemetry(events);
shinyford marked this conversation as resolved.
Show resolved Hide resolved
}

/// Sign out of all [Session]s and delete the current [Client]
///
Future<void> signOut() async {
Expand Down
6 changes: 6 additions & 0 deletions packages/clerk_auth/lib/src/clerk_auth/http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ abstract class HttpClient {
Uri uri, {
Map<String, String>? headers,
Map<String, dynamic>? params,
String? body,
});

/// Upload a [File] to the back end, and receive a [Response]
Expand All @@ -71,6 +72,7 @@ class DefaultHttpClient implements HttpClient {
Uri uri, {
Map<String, String>? headers,
Map<String, dynamic>? params,
String? body,
}) async {
final request = Request(method.toString(), uri);

Expand All @@ -82,6 +84,10 @@ class DefaultHttpClient implements HttpClient {
request.bodyFields = params.toStringMap();
}

if (body case String body) {
request.body = body;
}

final streamedResponse = await request.send();
return Response.fromStream(streamedResponse);
}
Expand Down
30 changes: 12 additions & 18 deletions packages/clerk_auth/lib/src/models/client.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 11 additions & 18 deletions packages/clerk_auth/lib/src/models/email.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions packages/clerk_auth/lib/src/models/enums.dart
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,25 @@ enum Field {
String toString() => _$FieldEnumMap[this]!;
}

/// [InstanceType] Clerk object
@JsonEnum(alwaysCreate: true)
enum InstanceType {
/// unknown
unknown,

/// development
development,

/// production
production;

/// Is this a development instance?
bool get isDevelopment => this == development;

@override
String toString() => _$InstanceTypeEnumMap[this]!;
}

/// [IdentifierType] object
enum IdentifierType {
/// phone number
Expand Down
6 changes: 6 additions & 0 deletions packages/clerk_auth/lib/src/models/enums.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:clerk_auth/clerk_auth.dart';
import 'package:json_annotation/json_annotation.dart';

part 'display_config.g.dart';
Expand Down Expand Up @@ -32,7 +33,7 @@ class DisplayConfig {
this.googleOneTapClientId = '',
this.helpUrl = '',
this.homeUrl = '',
this.instanceEnvironmentType = '',
this.instanceEnvironmentType = InstanceType.unknown,
this.logoImageUrl = '',
this.logoLinkUrl = '',
this.logoUrl = '',
Expand Down Expand Up @@ -119,7 +120,7 @@ class DisplayConfig {
final String? homeUrl;

/// instance environment type
final String? instanceEnvironmentType;
final InstanceType instanceEnvironmentType;

/// logo image url
final String? logoImageUrl;
Expand Down
Loading
Loading