Files

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.