227 lines
8.3 KiB
Markdown
227 lines
8.3 KiB
Markdown
# 🚀 Vibn Marketing Attribution & Identity Sync SDK
|
|
|
|
A modular, highly scalable, and decoupled SDK package to link anonymous site traffic tracking (**Umami Analytics**) with registered user profiles (**Vibn Database**), providing comprehensive **First-Touch Marketing Attribution** and acquisition logs.
|
|
|
|
Developed originally for **Missinglettr** and structured specifically to be drop-in ready for the **Vibn Platform** architecture.
|
|
|
|
---
|
|
|
|
## 📁 Package Inventory
|
|
|
|
This package contains three decoupled layers designed to be copied directly into your respective repositories:
|
|
|
|
| Path | Purpose | Language / Framework |
|
|
| :--- | :--- | :--- |
|
|
| `frontend/VibnTracker.tsx` | Client-side search params listener, sessionStorage / Cookie persistence, automated Umami injection, and session identity bridging (`identify()`). | TypeScript / Next.js React |
|
|
| `backend/models.py` | Abstract Base Django Model adding UTM and Referrer fields to any User / Client record. | Python / Django |
|
|
| `backend/mixins.py` | Django REST Framework (DRF) interceptor mixin to auto-capture attribution variables from incoming signup payloads. | Python / Django REST Framework |
|
|
| `umami-bridge/umami_service.py` | Reusable bridge to pull aggregated pageviews, session timestamps, and raw click-trails from Umami (via REST API or raw DB joins). | Python / Django |
|
|
|
|
---
|
|
|
|
## 🏛️ Architecture Overview
|
|
|
|
The system bridges anonymous traffic with database records using a secure **Identity Exchange**:
|
|
|
|
```
|
|
[Anonymous Visitor Clicks Ad / Tweet]
|
|
│
|
|
▼
|
|
[Lands on Website with UTMs & Referrer]
|
|
│ ├── Auto-logged in Umami (analytics.vibnai.com)
|
|
│ └── Cached client-side in sessionStorage & Cookie fallback
|
|
▼
|
|
[Signs Up / Logs in via Google OAuth]
|
|
│
|
|
▼
|
|
[Frontend POSTs Signup payload + UTM params to Backend]
|
|
│
|
|
▼
|
|
[Django Backend saves user record + permanently binds UTM columns]
|
|
│
|
|
▼
|
|
[Frontend calls useVibnTracker.identify(user_id)]
|
|
│
|
|
▼
|
|
[Umami merges ALL previous anonymous browsing history with this new User ID!]
|
|
```
|
|
|
|
---
|
|
|
|
## 💻 Step-by-Step Implementation Guide
|
|
|
|
### 1. Frontend Integration (Vibn Next.js Web App)
|
|
|
|
Copy `frontend/VibnTracker.tsx` into your Next.js project (e.g., inside `components/metrics/VibnTracker.tsx`):
|
|
|
|
#### A. Wrap your Root Layout:
|
|
In `app/layout.tsx` (or your entry file), wrap the tree with `VibnTrackerProvider`. This will automatically inject your Umami tracking script and listen for UTM parameters across your landing and console domains:
|
|
|
|
```tsx
|
|
import { VibnTrackerProvider } from "@/components/metrics/VibnTracker";
|
|
|
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
return (
|
|
<html lang="en">
|
|
<VibnTrackerProvider
|
|
umamiWebsiteId="your-umami-website-uuid"
|
|
umamiScriptUrl="https://analytics.vibnai.com/script.js"
|
|
>
|
|
<body>{children}</body>
|
|
</VibnTrackerProvider>
|
|
</html>
|
|
);
|
|
}
|
|
```
|
|
|
|
#### B. Capture & Send on Signup / Google OAuth exchange:
|
|
In your signup or Google OAuth exchange page (where the user completes registration), extract the cached attribution parameters using the `useVibnTracker` hook and send them in the request body to your backend:
|
|
|
|
```tsx
|
|
import { useVibnTracker } from "@/components/metrics/VibnTracker";
|
|
|
|
export default function GoogleCallbackPage() {
|
|
const { getStoredAttribution, identify, track } = useVibnTracker();
|
|
|
|
const handleOAuthSignup = async (googleToken: string) => {
|
|
// 1. Get first-touch parameters cached in browser
|
|
const attribution = getStoredAttribution();
|
|
|
|
// 2. POST to your register endpoint
|
|
const response = await fetch("/api/auth/register", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
google_token: googleToken,
|
|
...attribution // Sends utm_source, utm_medium, utm_campaign, referrer, etc.
|
|
})
|
|
});
|
|
|
|
if (response.ok) {
|
|
const user = await response.json();
|
|
|
|
// 3. BRIDGING IDENTITY: Link anonymous browser history with real user ID!
|
|
identify({
|
|
userId: user.id, // Primary key in your database
|
|
email: user.email,
|
|
name: user.name,
|
|
plan: user.plan
|
|
});
|
|
|
|
// 4. Track custom sign-up conversion in Umami
|
|
track("user_completed_signup", { plan: user.plan });
|
|
}
|
|
};
|
|
|
|
// ...
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 2. Backend Integration (Vibn Django API)
|
|
|
|
Copy `backend/models.py` and `backend/mixins.py` into your Django apps.
|
|
|
|
#### A. Inherit from the Abstract Model:
|
|
Add first-touch marketing attribution columns to your active User or APIClient model by inheriting from `VibnAbstractAttributionModel`:
|
|
|
|
```python
|
|
# your_app/models.py
|
|
from backend.models import VibnAbstractAttributionModel
|
|
|
|
class UserProfile(VibnAbstractAttributionModel):
|
|
# Your existing fields
|
|
email = models.EmailField(unique=True)
|
|
name = models.CharField(max_length=255)
|
|
|
|
class Meta:
|
|
db_table = "user_profile"
|
|
```
|
|
|
|
Then generate and apply your database migrations:
|
|
```bash
|
|
python manage.py makemigrations
|
|
python manage.py migrate
|
|
```
|
|
|
|
#### B. Intercept requests with the DRF View Mixin:
|
|
Add the `VibnAttributionCaptureMixin` to your Signup or Authentication API ViewSet. It will automatically intercept, extract, and write the UTM parameters into the saving model:
|
|
|
|
```python
|
|
# your_app/views.py
|
|
from rest_framework import viewsets
|
|
from backend.mixins import VibnAttributionCaptureMixin
|
|
from .models import UserProfile
|
|
from .serializers import UserProfileSerializer
|
|
|
|
class RegisterViewSet(VibnAttributionCaptureMixin, viewsets.ModelViewSet):
|
|
"""
|
|
User registration API view.
|
|
VibnAttributionCaptureMixin automatically grabs utm_source, utm_campaign,
|
|
and Referrer headers from requests and binds them onto the UserProfile on save.
|
|
"""
|
|
queryset = UserProfile.objects.all()
|
|
serializer_class = UserProfileSerializer
|
|
```
|
|
|
|
---
|
|
|
|
### 3. Expose Live Traffic Trails in Admin Consoles
|
|
|
|
Copy `umami-bridge/umami_service.py` into your Python services.
|
|
|
|
You can securely query stats directly from your Umami self-hosted database (read-only) inside your Admin panels, allowing you to render **actual pageviews, device breakdowns, and exact visitor session timelines** for any specific client.
|
|
|
|
#### A. Configure Umami DB Connection:
|
|
In Django's `settings.py`, register your Umami database:
|
|
|
|
```python
|
|
DATABASES = {
|
|
'default': {
|
|
# Your main application DB
|
|
},
|
|
'umami_db': {
|
|
'ENGINE': 'django.db.backends.postgresql',
|
|
'NAME': 'umami_production_db',
|
|
'USER': 'readonly_user',
|
|
'PASSWORD': 'password',
|
|
'HOST': '34.19.250.135',
|
|
'PORT': '5432',
|
|
}
|
|
}
|
|
```
|
|
|
|
#### B. Fetch Live Session Data for Admin Console:
|
|
In your Admin API view (e.g. `admin_user_detail`), call the service to fetch raw click-trails:
|
|
|
|
```python
|
|
# your_admin_app/views.py
|
|
from rest_framework.response import Response
|
|
from umami_bridge.umami_service import VibnUmamiService
|
|
|
|
def get_admin_user_profile(request, user_id):
|
|
# Initialize service
|
|
umami = VibnUmamiService()
|
|
|
|
# 1. Fetch total web sessions, total pageviews, and first interaction timestamp
|
|
funnel = umami.get_aggregated_funnel_for_user(user_id, db_connection_name="umami_db")
|
|
|
|
# 2. Fetch the actual 50 most recent page clicks, devices, and browsers used by this client!
|
|
click_trail = umami.get_user_session_click_trail(user_id, db_connection_name="umami_db")
|
|
|
|
return Response({
|
|
"user_id": user_id,
|
|
"first_touch_web_funnel": funnel,
|
|
"live_click_trail": click_trail
|
|
})
|
|
```
|
|
|
|
---
|
|
|
|
## 🛡️ Best Practices & GDPR Compliance
|
|
|
|
1. **Self-Hosted Privacy:** Because Umami is hosted on your domain (`analytics.vibnai.com`), cookie and script blockades are minimized, and no data is shared with third parties (complying strictly with GDPR, CCPA, and PECR).
|
|
2. **First-Touch Preservation:** The mixin uses `if not client.utm_source:` checks on save, ensuring first-touch parameters (the exact ad or link that *originally* brought the user in) are preserved and never overwritten by subsequent organic logins.
|
|
3. **No Database Blockades:** The `umami_service.py` uses read-only connections and limits queries to `LIMIT 50` to make sure raw analytics querying never causes performance blocks on your main application database thread.
|