Skip to content

Add wzrk_dl deep link attribution to InApp click events#519

Open
darshanclevertap wants to merge 6 commits intodevelopfrom
claude/inapp-deep-link-attribution-lk90P
Open

Add wzrk_dl deep link attribution to InApp click events#519
darshanclevertap wants to merge 6 commits intodevelopfrom
claude/inapp-deep-link-attribution-lk90P

Conversation

@darshanclevertap
Copy link
Contributor

@darshanclevertap darshanclevertap commented Feb 13, 2026

Summary

This PR implements deep link attribution for InApp clicks by adding the wzrk_dl property to InApp notification click events. This complements the existing wzrk_c2a (call-to-action) tracking to provide complete click attribution with actual navigation destinations.

Key Changes

  • Added CLTAP_PROP_WZRK_DL constant in CTConstants.h to define the new wzrk_dl event property
  • Enhanced CTEventBuilder to include wzrk_dl in InApp notification state events when present in query parameters
  • Updated button click handler in CTInAppDisplayViewController.handleButtonClickFromIndex: to extract deep links from button actions and pass them to the event builder
  • Modified action handler in CTInAppDisplayManager.handleNotificationAction: to ensure deep links are captured and included in event tracking
  • Added comprehensive documentation explaining the feature, template behavior matrix, and implementation details
  • Created unit test suite (CTInAppDeepLinkAttributionTests.m) with 10+ test cases covering:
    • Event builder with/without deep links
    • Button actions with various URL formats
    • Multi-CTA scenarios with different deep links per button
    • Personalized deep links with query parameters
    • Backward compatibility with legacy formats

Implementation Details

  • Deep links are extracted from CTNotificationButton.action.actionURL.absoluteString for CTA buttons
  • The wzrk_dl property is only added to events when a deep link URL exists (no empty strings)
  • Multi-CTA templates automatically track the specific clicked button's deep link
  • Personalized deep links with user-specific parameters are preserved in their entirety
  • Fully backward compatible - existing wzrk_c2a behavior unchanged
  • Supports all template types: basic templates, image-only, HTML, and advanced InApp Builder

Event Property Reference

wzrk_dl (Deep Link):

  • Type: String
  • When Present: Only when InApp click leads to URL navigation
  • Format: Full URL with scheme, path, and query parameters
  • Examples: https://shop.example.com/sale, myapp://product/123

wzrk_c2a (Call-to-Action):

  • Existing property capturing button text
  • Behavior unchanged
  • Empty for non-CTA templates (image-only, etc.)

https://claude.ai/code/session_01VM4LdS9H8hQnLzUugNkvvx

Summary by CodeRabbit

Release Notes

  • New Features

    • Added deep link attribution support for in-app notifications, enabling tracking and propagation of deep links across notification actions and template types.
  • Tests

    • Added comprehensive test coverage validating deep link attribution functionality and backward compatibility.
  • Documentation

    • Added documentation detailing deep link attribution feature and implementation guidelines.

This plan outlines the approach to add wzrk_dl property to InApp click events:
- Support for CTA button deep links
- Template-level deep links for non-CTA templates
- Multi-CTA tracking
- Personalized deep link capture
- Backward compatibility with existing wzrk_c2a

The implementation is organized into 6 sprints covering:
1. Core infrastructure and constants
2. CTA button support
3. Template-level support
4. Advanced templates (HTML, Custom, Builder)
5. Comprehensive testing
6. Documentation

https://claude.ai/code/session_01VM4LdS9H8hQnLzUugNkvvx
Changes:
- Removed Phase 9.2 (Integration Tests section)
- Removed Phase 10.3 (Changelog Entry section)
- Updated Files to Modify list (removed integration test file and changelog)
- Updated Sprint 5 & 6 implementation order
- Updated Pre-Release Checklist
- Updated Definition of Done
- Moved plan to .claude/plans/ directory

The plan now focuses on unit tests and code documentation only.

https://claude.ai/code/session_01VM4LdS9H8hQnLzUugNkvvx
This commit implements wzrk_dl (deep link) attribution for InApp clicks,
complementing the existing wzrk_c2a (call-to-action) tracking.

Changes:
1. Added CLTAP_PROP_WZRK_DL constant in CTConstants.h
2. Updated CTEventBuilder to document wzrk_dl support in params
3. Modified handleButtonClickFromIndex to extract button deep links
4. Modified triggerInAppAction to capture template-level deep links
5. Modified handleImageTapGesture for image-only template deep links
6. Created comprehensive unit test suite (CTInAppDeepLinkAttributionTests.m)

Features:
- CTA button clicks capture button-specific deep links
- Multi-CTA templates track clicked button's specific deep link
- Image-only templates capture template-level deep links
- Non-CTA navigable templates include destination URLs
- Personalized deep links are preserved with all parameters
- Empty wzrk_dl is not added when no deep link exists
- Backward compatible with existing wzrk_c2a behavior

Test Coverage:
- Event builder with/without wzrk_dl
- Button actions with deep links
- Multi-CTA scenarios
- Personalized deep links
- Backward compatibility

https://claude.ai/code/session_01VM4LdS9H8hQnLzUugNkvvx
Enhanced handleNotificationAction to automatically extract deep links
from action URLs for attribution tracking. This ensures comprehensive
wzrk_dl support across all template types that weren't directly covered
by button click handlers.

Changes:
- Modified handleNotificationAction in CTInAppDisplayManager to extract
  wzrk_dl from action.actionURL when not already present in extras
- Preserves existing wzrk_dl in extras (no override)
- Creates mutable copy of extras to add deep link

Template Coverage:
- HTML templates (JavaScript-triggered navigation)
- Custom templates with URL actions
- Advanced InApp Builder templates
- Any template type calling handleNotificationAction with URL actions

Benefits:
- Automatic wzrk_dl extraction for all action-based navigation
- No need to manually add wzrk_dl in calling code
- Consistent deep link attribution across all template types
- Fallback for any missed edge cases

https://claude.ai/code/session_01VM4LdS9H8hQnLzUugNkvvx
…nt 6)

Created detailed feature documentation covering all aspects of the
wzrk_dl deep link attribution feature.

Documentation Contents:
- Feature overview and summary
- Event property reference (wzrk_dl and wzrk_c2a)
- Template behavior matrix with expected values
- Implementation details for all template types
- Code examples and usage patterns
- Backward compatibility information
- Testing and troubleshooting guides
- File modifications reference

Key Sections:
1. Overview - Feature purpose and template support
2. Event Properties - wzrk_dl and wzrk_c2a specifications
3. Template Behavior Matrix - Expected values per template type
4. Implementation Details - CTA buttons, multi-CTA, image-only, HTML, etc.
5. Code Examples - Reading events, creating campaigns
6. Backward Compatibility - Legacy format support
7. When wzrk_dl is NOT Included - Edge cases and exclusions
8. Testing - Unit tests and manual testing procedures
9. Troubleshooting - Common issues and solutions
10. Implementation Files - Modified and new files reference

This documentation provides developers with complete information to
understand and use the deep link attribution feature effectively.

https://claude.ai/code/session_01VM4LdS9H8hQnLzUugNkvvx
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 13, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (1)
  • ^(task|feat|feature|fix)/

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The changes implement InApp deep link attribution by adding a new wzrk_dl property constant, propagating deep links from button action URLs through event building and display layers, and validating the implementation with comprehensive tests and documentation.

Changes

Cohort / File(s) Summary
Implementation Planning
.claude/plans/IMPLEMENTATION_PLAN.md
Comprehensive plan detailing InApp deep link attribution implementation phases, file changes, test strategy, rollback plan, and validation criteria.
Constants and Core Infrastructure
CleverTapSDK/CTConstants.h, CleverTapSDK/CTEventBuilder.m
Added CLTAP_PROP_WZRK_DL constant macro. Added initializeWithValidationConfig: method to CTEventBuilder for initialization support.
InApp Display Layer
CleverTapSDK/CTInAppDisplayViewController.m, CleverTapSDK/InApps/CTInAppDisplayManager.m
Updated multiple methods to extract deep links from button action URLs and propagate them through extras dictionaries. CTInAppDisplayViewController extracts deep links in button click and gesture handlers; CTInAppDisplayManager augments extras with wzrk_dl when recording in-app notification state events.
Testing
CleverTapSDKTests/InApps/CTInAppDeepLinkAttributionTests.m
New test suite with 10 test methods covering deep-link presence/absence in events, button deep-link handling, personalized deep links, and backward compatibility with existing wzrk_c2a property.
Documentation
docs/InApp-Deep-Link-Attribution.md
New documentation file covering wzrk_dl property usage, template coverage matrix, code examples, backward compatibility, testing guidance, and affected implementation files.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant InAppDisplayViewController as InAppDisplayViewController
    participant InAppDisplayManager as InAppDisplayManager
    participant EventBuilder as CTEventBuilder
    participant Delegate as Delegate Handler

    User->>InAppDisplayViewController: Tap button/image
    activate InAppDisplayViewController
    InAppDisplayViewController->>InAppDisplayViewController: Extract deep link from actionURL
    InAppDisplayViewController->>InAppDisplayViewController: Build extras dict with wzrk_dl
    InAppDisplayViewController->>InAppDisplayManager: handleNotificationAction(action, extras)
    deactivate InAppDisplayViewController
    
    activate InAppDisplayManager
    InAppDisplayManager->>InAppDisplayManager: Augment extras with wzrk_dl from actionURL
    InAppDisplayManager->>EventBuilder: buildInAppNotificationStateEvent(extras)
    deactivate InAppDisplayManager
    
    activate EventBuilder
    EventBuilder->>EventBuilder: Include wzrk_dl in event properties
    EventBuilder->>InAppDisplayManager: Return event with wzrk_dl
    deactivate EventBuilder
    
    activate InAppDisplayManager
    InAppDisplayManager->>Delegate: Call delegate with augmented extras
    deactivate InAppDisplayManager
    
    activate Delegate
    Delegate->>Delegate: Process event with deep link attribution
    deactivate Delegate
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • Sonal-Kachare
  • akashvercetti
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add wzrk_dl deep link attribution to InApp click events' directly and specifically summarizes the main change—adding a new deep link attribution property to InApp click events.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into develop

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/inapp-deep-link-attribution-lk90P

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@francispereira
Copy link

francispereira commented Feb 13, 2026

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@darshanclevertap
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@CleverTapSDKTests/InApps/CTInAppDeepLinkAttributionTests.m`:
- Around line 138-151: The test fails because CTNotificationButton's init is
unavailable and its text/action properties are readonly; update the test to
construct the button via the public initializer CTNotificationButton
initWithJSON: by building a JSON/dictionary that includes the "text" value and
an "action" object (with the URL string) so the deserializer populates the
readonly properties (or alternatively, if direct construction is intended,
change the CTNotificationButton header to provide a public writable initializer
and mark text and action as readwrite or add a designated initializer that
accepts text and CTNotificationAction); for this PR implement the test-side fix
using initWithJSON: and create a JSON payload representing the button and its
action so assertions can check button.action.actionURL as before.

In `@docs/InApp-Deep-Link-Attribution.md`:
- Around line 306-307: Update the placeholder header values: replace the
"Feature Added: v[Version TBD]" entry with "v7.5.0" and change the "Minimum iOS:
iOS 10.0" entry to "iOS 9.0" so the document matches the current SDK version and
the minimum iOS deployment target declared in CleverTap-iOS-SDK.podspec; update
the lines where "Feature Added" and "Minimum iOS" are defined in
InApp-Deep-Link-Attribution.md accordingly.
🧹 Nitpick comments (4)
docs/InApp-Deep-Link-Attribution.md (1)

32-36: Add language specifier to fenced code block.

The markdownlint hint flags this code block as missing a language specifier (MD040).

Proposed fix
-```
+```text
 wzrk_dl: "https://myapp.com/products/sale"
.claude/plans/IMPLEMENTATION_PLAN.md (1)

1-656: Implementation plan is thorough and well-structured.

This planning document under .claude/plans/ provides good traceability for the feature implementation. Consider whether this should remain in the repository long-term or be moved to project management tooling post-merge.

CleverTapSDKTests/InApps/CTInAppDeepLinkAttributionTests.m (2)

101-134: Test documents a gap: empty string wzrk_dl passes through to the event.

The test correctly documents that the event builder doesn't filter empty strings. Since the calling code in CTInAppDisplayViewController and CTInAppDisplayManager guards with deepLink.length > 0, this won't happen in practice. However, if a future code path bypasses the length check, an empty wzrk_dl would leak into event data.

Consider whether the event builder itself should strip empty wzrk_dl values as a defense-in-depth measure, or if this is acceptable as-is.


185-208: Multi-CTA test validates object identity but doesn't test the full event flow.

This test verifies that two CTNotificationButton instances maintain separate deep links — which is essentially testing NSURL/property assignment. A more valuable test would simulate calling handleButtonClickFromIndex: with different indices and verify the resulting extras dictionary contains the correct per-button deep link. That said, this still provides basic regression coverage for the data model.

Updated button creation in tests to use initWithJSON: instead of
unavailable init and readonly property setters.

Changes:
- testNotificationButtonWithDeepLink: Use JSON with text and actions
- testNotificationButtonWithHTTPDeepLink: Use JSON structure
- testNotificationButtonWithoutDeepLink: Use JSON with close action
- testMultipleCTAButtonsWithDifferentDeepLinks: Use JSON for both buttons

JSON Structure:
@{
    @"text": @"Button Text",
    @"actions": @{
        @"ios": @"url_string",
        @"type": @"url" // or "close"
    }
}

This follows the SDK's button deserialization pattern where
CTNotificationButton has readonly text/action properties that
must be set via initWithJSON: (init is unavailable).

Fixes PR review comment about readonly properties.

https://claude.ai/code/session_01VM4LdS9H8hQnLzUugNkvvx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments