sentalong 0.1.0 copy "sentalong: ^0.1.0" to clipboard
sentalong: ^0.1.0 copied to clipboard

Thin Flutter client for the Sentalong tracking API. Deep-link click capture, identify, and qualification stages — no analytics, no fingerprinting, no device identifiers.

sentalong #

Thin Flutter client for the Sentalong tracking API. It does exactly four things — configure, handle a deep link, identify a signed-up user, and report qualification stages — and nothing else.

  • No PII generated. The SDK only sends what your app passes in.
  • No analytics, no fingerprinting, no device identifiers. This is a policy requirement (App Store / Play policy safety), not a style choice.
  • Fail-safe. No method ever throws: bad URLs, offline devices, and server hiccups degrade to null (or false for qualify).

Install #

# pubspec.yaml
dependencies:
  sentalong: ^0.1.0
flutter pub get

The package's only runtime dependencies are shared_preferences (to persist the click id) and http (transport).

Quickstart #

1. Configure once at startup #

import 'package:sentalong/sentalong.dart';

void main() {
  Sentalong.configure(
    'https://sentalong.com', // your Sentalong origin
    'prg_abc123',            // your program id
    // urlParam: 'via',      // change if your links use a different param
  );
  runApp(const MyApp());
}

The SDK deliberately does not depend on a deep-link package — pass it whatever URL your existing wiring receives. With app_links (or the older uni_links), the wiring looks like this:

// pubspec.yaml (your app, not this SDK):
//   app_links: ^6.0.0

import 'package:app_links/app_links.dart';
import 'package:sentalong/sentalong.dart';

final _appLinks = AppLinks();

Future<void> initDeepLinks() async {
  // Cold start: the link that launched the app, if any.
  final Uri? initial = await _appLinks.getInitialLink();
  if (initial != null) {
    await Sentalong.handleUri(initial);
  }

  // Warm/foreground links while the app is running.
  _appLinks.uriLinkStream.listen((Uri uri) {
    Sentalong.handleUri(uri);
  });
}

handleUrl / handleUri accepts universal links (https://…), Android App Links, and custom schemes (myapp://…) alike. When the link carries your attribution param (default via), the SDK reports the click and persists the returned click id for the number of days your program's attribution window allows. It also forwards sub_id (or sub1) and the six supported ad-click ids (gclid, fbclid, ttclid, twclid, li_fat_id, msclkid) when present.

Links with via=test are treated as smoke tests: the SDK logs Sentalong: test click received and sends/stores nothing — the same behavior as the t.js web snippet.

3. Identify at signup #

Call identify right after the user completes signup. If a click was captured (and hasn't expired), the server links the new user to the partner who referred them:

Future<void> onSignupComplete(User user) async {
  final String? referralId = await Sentalong.identify(
    user.email,
    externalId: user.id, // optional: your own user id
  );
  // referralId is 'ref_…' when attribution succeeded, or null when there
  // was no stored click (organic signup) or the network was unavailable.
}

Calling identify again later is safe — the server treats repeat identifies idempotently, and the SDK keeps the click id stored after success.

4. Report qualification stages (optional) #

await Sentalong.qualify('signup');    // also: 'onboarded', 'demo'

Returns true only when the server acknowledged the stage.

Attribution limits on iOS #

Be honest with yourself about what mobile attribution can and cannot do on iOS:

  • There is no install referrer on iOS. Unlike Android's Play Install Referrer, Apple provides no API that tells an app which link led to its App Store install. If a user taps a partner link, installs your app from the App Store, and then opens it, that hop through the App Store breaks the linkhandleUrl never fires because no URL reaches the app.
  • What does work: universal links and custom-scheme links that open an already-installed app deliver the full URL, and this SDK attributes those clicks reliably. Web-to-app flows where the user signs up in the browser (where the t.js snippet captured the click) also attribute normally.
  • What this SDK will not do: it will not fingerprint devices, join IP addresses, or use any probabilistic matching to paper over the install gap. Those techniques violate Apple's App Tracking Transparency rules and are explicitly out of scope.
  • Practical advice: for iOS install campaigns, send partners' traffic to a web landing page first (where the click is captured), and let users sign up on the web or deep-link into the app afterwards. Expect some unavoidable attribution loss on cold App Store installs.

On Android, deep links into an installed app work the same way; install referrer capture is available in the Kotlin SDK (com.sentalong.sdk), not in this Flutter package.

Testing your integration #

The core client is pure Dart and injectable, so you can unit-test your own wiring without a network or a Flutter engine:

final client = SentalongClient(
  storage: InMemorySentalongStorage(),
  httpClient: myFakeHttpClient, // implements SentalongHttpClient
);
client.configure('https://sentalong.com', 'prg_test');

See test/sentalong_test.dart in this package for a complete example.

API reference #

Method Returns Notes
Sentalong.configure(baseUrl, programId, {urlParam}) void Call once before anything else.
Sentalong.handleUrl(String url) Future<String?> Click id (clk_…) or null. Never throws.
Sentalong.handleUri(Uri uri) Future<String?> Same, for a pre-parsed Uri.
Sentalong.identify(email, {externalId}) Future<String?> Referral id (ref_…) or null.
Sentalong.qualify(stage) Future<bool> 'signup', 'onboarded', or 'demo'.

Stored state lives under the shared_preferences keys sentalong.cid and sentalong.cid_expires_at (ISO-8601). An expired click id is discarded the next time it is read.

License #

MIT

0
likes
150
points
64
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Thin Flutter client for the Sentalong tracking API. Deep-link click capture, identify, and qualification stages — no analytics, no fingerprinting, no device identifiers.

Homepage
Repository (GitHub)

License

MIT (license)

Dependencies

flutter, http, shared_preferences

More

Packages that depend on sentalong