نمونهٔ OpenPanel موجود (stats.*) با یک پروژهٔ دوم برای این سایت استفاده میشود؛ VITE_OPENPANEL_URL/VITE_OPENPANEL_CLIENT_ID در زمان بیلد تزریق میشوند و در نبودشان همهچیز بیاثر است. API عمومی track() تغییر نکرده و مسیر Umami هم برای عقبنشینی دستنخورده مانده.
66 lines
2.9 KiB
TypeScript
66 lines
2.9 KiB
TypeScript
// لایهٔ نازک تحلیل رفتار — OpenPanel.
|
|
//
|
|
// نمونهٔ OpenPanel از قبل روی این سرور بالا است (stats.bennu-api-bahrestan.ir) و
|
|
// پروژهٔ ERP هم از همان استفاده میکند؛ بهجای اجرای یک ابزار تحلیل دوم (Umami)،
|
|
// همین یک نمونه با یک «پروژهٔ» دوم برای این سایت به کار میرود.
|
|
//
|
|
// اگر VITE_OPENPANEL_URL و VITE_OPENPANEL_CLIENT_ID در زمان بیلد تنظیم نشده باشند،
|
|
// همهٔ فراخوانیها بیاثر و ارزاناند (مثل حالت فعلی Umami).
|
|
//
|
|
// مسیر Umami دستنخورده مانده تا اگر اسکریپت قدیمی جایی فعال بود از کار نیفتد.
|
|
|
|
declare global {
|
|
interface Window {
|
|
op?: (...args: unknown[]) => void
|
|
umami?: { track: (event?: string, data?: Record<string, unknown>) => void }
|
|
}
|
|
}
|
|
|
|
const OP_URL = (import.meta.env?.VITE_OPENPANEL_URL as string | undefined)?.trim()
|
|
const OP_CLIENT_ID = (import.meta.env?.VITE_OPENPANEL_CLIENT_ID as string | undefined)?.trim()
|
|
const OP_SCRIPT_URL = (import.meta.env?.VITE_OPENPANEL_SCRIPT_URL as string | undefined)?.trim()
|
|
|
|
// شیم صف OpenPanel — تا رسیدن op1.js، فراخوانیها در صف میمانند و بعد تخلیه میشوند.
|
|
function loadOpenPanelScript(src: string): void {
|
|
if (document.querySelector('script[data-openpanel]')) return
|
|
const shim = document.createElement('script')
|
|
shim.textContent =
|
|
'window.op=window.op||function(){var n=[];return new Proxy(function(){arguments.length&&n.push([].slice.call(arguments))},{get:function(t,r){return"q"===r?n:function(){n.push([r].concat([].slice.call(arguments)))}},has:function(t,r){return"q"===r}}) }();'
|
|
document.head.appendChild(shim)
|
|
const script = document.createElement('script')
|
|
script.src = src
|
|
script.async = true
|
|
script.defer = true
|
|
script.dataset.openpanel = '1'
|
|
document.head.appendChild(script)
|
|
}
|
|
|
|
/** یکبار در شروع اپ صدا زده میشود؛ بدون تنظیمات، هیچ کاری نمیکند. */
|
|
export function initAnalytics(): void {
|
|
if (!OP_URL || !OP_CLIENT_ID) return
|
|
try {
|
|
if (OP_SCRIPT_URL) loadOpenPanelScript(OP_SCRIPT_URL)
|
|
window.op?.('init', {
|
|
apiUrl: OP_URL,
|
|
clientId: OP_CLIENT_ID,
|
|
trackScreenViews: true, // بازدید صفحه → کدام صفحات دیده میشوند
|
|
})
|
|
} catch {
|
|
// تحلیل رفتار هرگز نباید مسیر اصلی را بشکند
|
|
}
|
|
}
|
|
|
|
/** رخداد سفارشی — در داشبورد OpenPanel نمایش داده میشود. */
|
|
export function track(event: string, data?: Record<string, unknown>) {
|
|
try {
|
|
window.op?.('track', event, data ?? {})
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
try {
|
|
window.umami?.track(event, data)
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|