Skip to content

Commit 740656c

Browse files
feat(audience-sdk)!: drop Identify/Alias string-identityType overloads
The Audience backend accepts only the closed IdentityType enum. The string-identityType overloads on Identify and Alias were vestigial: anything outside the enum gets rejected at validation, and studios with a proprietary system already have IdentityType.Custom as the escape hatch. Removes the overloads to match the TS SDK shape and reduce footguns. BREAKING CHANGE: callers of Identify(string, string, ...) or Alias(string, string, string, string) must migrate to the IdentityType overload. Direct mapping: "steam" -> IdentityType.Steam, "passport" -> IdentityType.Passport, etc., per IdentityTypeExtensions.ToLowercaseString. - ImmutableAudience.cs: consolidates each pair into the IdentityType overload, calling .ToLowercaseString() inline at the MessageBuilder call site. Drops the two string overloads and their wrappers. - ImmutableAudienceTests.cs: migrates four test calls from string to enum form (Identify and Alias). dotnet test: 274 passed, 0 failed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 62c2273 commit 740656c

3 files changed

Lines changed: 28 additions & 41 deletions

File tree

examples/audience/Assets/SampleApp/Scripts/AudienceSample.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ private void OnIdentify() => RunAndLog("identify()", () =>
189189
{
190190
var f = CaptureIdentifyForm();
191191
var traits = ParseTraits(f.RawTraits);
192-
ImmutableAudience.Identify(f.Id, f.Type, traits);
192+
ImmutableAudience.Identify(f.Id, ParseIdentityType(f.Type), traits);
193193
// SDK drops via Log.Warn when id is empty or consent < Full. Mirror
194194
// only when accepted — otherwise the panel would show stale state.
195195
var accepted = !string.IsNullOrEmpty(f.Id)
@@ -212,7 +212,7 @@ private void OnIdentifyTraits() => RunAndLog("identify(traits)", () =>
212212
if (string.IsNullOrEmpty(userId)) throw new InvalidOperationException("no active identity — call Identify first");
213213
var traits = ParseTraits(CaptureTraitsUpdate());
214214
if (traits == null || traits.Count == 0) throw new InvalidOperationException("traits required");
215-
ImmutableAudience.Identify(userId, _mirrorIdentityType ?? IdentityType.Custom.ToLowercaseString(), traits);
215+
ImmutableAudience.Identify(userId, ParseIdentityType(_mirrorIdentityType), traits);
216216
_mirrorTraits = traits;
217217
OnSdkStateChanged();
218218
return Json.Serialize(traits, 2);
@@ -221,7 +221,7 @@ private void OnIdentifyTraits() => RunAndLog("identify(traits)", () =>
221221
private void OnAlias() => RunAndLog("alias()", () =>
222222
{
223223
var f = CaptureAliasForm();
224-
ImmutableAudience.Alias(f.FromId, f.FromType, f.ToId, f.ToType);
224+
ImmutableAudience.Alias(f.FromId, ParseIdentityType(f.FromType), f.ToId, ParseIdentityType(f.ToType));
225225
// SDK drops via Log.Warn when fromId/toId is empty or consent < Full.
226226
// The IsAliasReady gate keeps empty endpoints unreachable from the
227227
// UI; this post-call check is defense-in-depth.
@@ -371,5 +371,20 @@ private void ResetIdentityMirror()
371371

372372
private static Dictionary<string, object>? ParseTraits(string? raw) =>
373373
string.IsNullOrWhiteSpace(raw) ? null : JsonReader.DeserializeObject(raw!);
374+
375+
// Parses a wire-format identity string (e.g. "steam") back into the
376+
// IdentityType enum the SDK now requires. Falls back to Custom for
377+
// unknown or empty values.
378+
private static IdentityType ParseIdentityType(string? value) => (value ?? "").ToLowerInvariant() switch
379+
{
380+
"passport" => IdentityType.Passport,
381+
"steam" => IdentityType.Steam,
382+
"epic" => IdentityType.Epic,
383+
"google" => IdentityType.Google,
384+
"apple" => IdentityType.Apple,
385+
"discord" => IdentityType.Discord,
386+
"email" => IdentityType.Email,
387+
_ => IdentityType.Custom,
388+
};
374389
}
375390
}

src/Packages/Audience/Runtime/ImmutableAudience.cs

Lines changed: 6 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -308,20 +308,7 @@ public static void Track(string eventName, Dictionary<string, object>? propertie
308308
/// <param name="userId">The player's identifier within the chosen provider.</param>
309309
/// <param name="identityType">The identity provider that issued <paramref name="userId"/>.</param>
310310
/// <param name="traits">Optional player attributes (email, name, etc.).</param>
311-
public static void Identify(string userId, IdentityType identityType, Dictionary<string, object>? traits = null) =>
312-
Identify(userId, identityType.ToLowercaseString(), traits);
313-
314-
/// <summary>
315-
/// Attaches a known user ID to subsequent events. String overload
316-
/// for providers outside the <see cref="IdentityType"/> enum.
317-
/// </summary>
318-
/// <param name="userId">The player's identifier within the chosen provider.</param>
319-
/// <param name="identityType">
320-
/// The identity provider name. Required. Data-deletion requests
321-
/// match events by this namespace.
322-
/// </param>
323-
/// <param name="traits">Optional player attributes (email, name, etc.).</param>
324-
public static void Identify(string userId, string identityType, Dictionary<string, object>? traits = null)
311+
public static void Identify(string userId, IdentityType identityType, Dictionary<string, object>? traits = null)
325312
{
326313
if (!_initialized) return;
327314

@@ -352,8 +339,8 @@ public static void Identify(string userId, string identityType, Dictionary<strin
352339
}
353340

354341
var anonymousId = Identity.GetOrCreate(config.PersistentDataPath!, level);
355-
var msg = MessageBuilder.Identify(anonymousId, userId, identityType, config.PackageVersion,
356-
SnapshotCallerDict(traits));
342+
var msg = MessageBuilder.Identify(anonymousId, userId, identityType.ToLowercaseString(),
343+
config.PackageVersion, SnapshotCallerDict(traits));
357344
EnqueueIdentity(msg);
358345
}
359346

@@ -364,23 +351,7 @@ public static void Identify(string userId, string identityType, Dictionary<strin
364351
/// <param name="fromType">Identity provider for <paramref name="fromId"/>.</param>
365352
/// <param name="toId">The new identifier.</param>
366353
/// <param name="toType">Identity provider for <paramref name="toId"/>.</param>
367-
public static void Alias(string fromId, IdentityType fromType, string toId, IdentityType toType) =>
368-
Alias(fromId, fromType.ToLowercaseString(), toId, toType.ToLowercaseString());
369-
370-
/// <summary>
371-
/// Links two user IDs for the same player. String overload for
372-
/// providers outside the <see cref="IdentityType"/> enum.
373-
/// </summary>
374-
/// <param name="fromId">The previously-known identifier.</param>
375-
/// <param name="fromType">
376-
/// Identity provider for <paramref name="fromId"/>. Required.
377-
/// Data-deletion requests match events by this namespace.
378-
/// </param>
379-
/// <param name="toId">The new identifier.</param>
380-
/// <param name="toType">
381-
/// Identity provider for <paramref name="toId"/>. Required.
382-
/// </param>
383-
public static void Alias(string fromId, string fromType, string toId, string toType)
354+
public static void Alias(string fromId, IdentityType fromType, string toId, IdentityType toType)
384355
{
385356
if (!_initialized) return;
386357

@@ -399,7 +370,8 @@ public static void Alias(string fromId, string fromType, string toId, string toT
399370
var config = _config;
400371
if (config == null) return;
401372

402-
var msg = MessageBuilder.Alias(fromId, fromType, toId, toType, config.PackageVersion);
373+
var msg = MessageBuilder.Alias(fromId, fromType.ToLowercaseString(), toId, toType.ToLowercaseString(),
374+
config.PackageVersion);
403375
EnqueueIdentity(msg);
404376
}
405377

src/Packages/Audience/Tests/Runtime/ImmutableAudienceTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ public void Identify_FullConsent_WritesIdentifyEvent()
618618
{
619619
ImmutableAudience.Init(MakeConfig(ConsentLevel.Full));
620620

621-
ImmutableAudience.Identify("76561198012345", "steam");
621+
ImmutableAudience.Identify("76561198012345", IdentityType.Steam);
622622
ImmutableAudience.Shutdown();
623623

624624
var queueDir = AudiencePaths.QueueDir(_testDir);
@@ -633,7 +633,7 @@ public void Identify_AnonymousConsent_IsIgnored()
633633
{
634634
ImmutableAudience.Init(MakeConfig(ConsentLevel.Anonymous));
635635

636-
ImmutableAudience.Identify("user1", "steam");
636+
ImmutableAudience.Identify("user1", IdentityType.Steam);
637637
ImmutableAudience.Shutdown();
638638

639639
var queueDir = AudiencePaths.QueueDir(_testDir);
@@ -648,7 +648,7 @@ public void Alias_FullConsent_WritesAliasEvent()
648648
{
649649
ImmutableAudience.Init(MakeConfig(ConsentLevel.Full));
650650

651-
ImmutableAudience.Alias("steam123", "steam", "user_456", "passport");
651+
ImmutableAudience.Alias("steam123", IdentityType.Steam, "user_456", IdentityType.Passport);
652652
ImmutableAudience.Shutdown();
653653

654654
var queueDir = AudiencePaths.QueueDir(_testDir);
@@ -971,7 +971,7 @@ public void SetConsent_DowngradeToAnonymous_StressTest_NoUserIdLeak()
971971
for (int iter = 0; iter < iterations; iter++)
972972
{
973973
ImmutableAudience.Init(MakeConfig(ConsentLevel.Full));
974-
ImmutableAudience.Identify(testUserId, "steam");
974+
ImmutableAudience.Identify(testUserId, IdentityType.Steam);
975975

976976
// Clear Init events so only race events can leak.
977977
ImmutableAudience.FlushQueueToDiskForTesting();

0 commit comments

Comments
 (0)