mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-11 17:46:20 +01:00
Analytics UA to V4 Conversion
This commit is contained in:
@@ -3,7 +3,6 @@ import logging
|
||||
from django.conf import settings
|
||||
from django.apps import apps
|
||||
from celery import shared_task
|
||||
from allianceauth import __version__
|
||||
from .models import AnalyticsTokens, AnalyticsIdentifier
|
||||
from .utils import (
|
||||
install_stat_addons,
|
||||
@@ -12,14 +11,14 @@ from .utils import (
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
BASE_URL = "https://www.google-analytics.com/"
|
||||
BASE_URL = "https://www.google-analytics.com"
|
||||
|
||||
DEBUG_URL = f"{BASE_URL}debug/collect"
|
||||
COLLECTION_URL = f"{BASE_URL}collect"
|
||||
DEBUG_URL = f"{BASE_URL}/debug/mp/collect"
|
||||
COLLECTION_URL = f"{BASE_URL}/mp/collect"
|
||||
|
||||
if getattr(settings, "ANALYTICS_ENABLE_DEBUG", False) and settings.DEBUG:
|
||||
# Force sending of analytics data during in a debug/test environemt
|
||||
# Usefull for developers working on this feature.
|
||||
# Force sending of analytics data during in a debug/test environment
|
||||
# Useful for developers working on this feature.
|
||||
logger.warning(
|
||||
"You have 'ANALYTICS_ENABLE_DEBUG' Enabled! "
|
||||
"This debug instance will send analytics data!")
|
||||
@@ -31,40 +30,38 @@ if settings.DEBUG is True:
|
||||
ANALYTICS_URL = DEBUG_URL
|
||||
|
||||
|
||||
def analytics_event(category: str,
|
||||
action: str,
|
||||
label: str,
|
||||
value: int = 0,
|
||||
def analytics_event(namespace: str,
|
||||
task: str,
|
||||
label: str = "",
|
||||
result: str = "",
|
||||
value: int = 1,
|
||||
event_type: str = 'Celery'):
|
||||
"""
|
||||
Send a Google Analytics Event for each token stored
|
||||
Includes check for if its enabled/disabled
|
||||
|
||||
Args:
|
||||
`category` (str): Celery Namespace
|
||||
`action` (str): Task Name
|
||||
`label` (str): Optional, Task Success/Exception
|
||||
`value` (int): Optional, If bulk, Query size, can be a binary True/False
|
||||
`namespace` (str): Celery Namespace
|
||||
`task` (str): Task Name
|
||||
`label` (str): Optional, additional task label
|
||||
`result` (str): Optional, Task Success/Exception
|
||||
`value` (int): Optional, If bulk, Query size, can be a Boolean
|
||||
`event_type` (str): Optional, Celery or Stats only, Default to Celery
|
||||
"""
|
||||
analyticstokens = AnalyticsTokens.objects.all()
|
||||
client_id = AnalyticsIdentifier.objects.get(id=1).identifier.hex
|
||||
for token in analyticstokens:
|
||||
if event_type == 'Celery':
|
||||
allowed = token.send_celery_tasks
|
||||
elif event_type == 'Stats':
|
||||
for token in AnalyticsTokens.objects.filter(type='GA-V4'):
|
||||
if event_type == 'Stats':
|
||||
allowed = token.send_stats
|
||||
else:
|
||||
allowed = False
|
||||
|
||||
if allowed is True:
|
||||
tracking_id = token.token
|
||||
send_ga_tracking_celery_event.s(
|
||||
tracking_id=tracking_id,
|
||||
client_id=client_id,
|
||||
category=category,
|
||||
action=action,
|
||||
measurement_id=token.token,
|
||||
secret=token.secret,
|
||||
namespace=namespace,
|
||||
task=task,
|
||||
label=label,
|
||||
result=result,
|
||||
value=value).apply_async(priority=9)
|
||||
|
||||
|
||||
@@ -72,136 +69,104 @@ def analytics_event(category: str,
|
||||
def analytics_daily_stats():
|
||||
"""Celery Task: Do not call directly
|
||||
|
||||
Gathers a series of daily statistics and sends analytics events containing them
|
||||
Gathers a series of daily statistics
|
||||
Sends analytics events containing them
|
||||
"""
|
||||
users = install_stat_users()
|
||||
tokens = install_stat_tokens()
|
||||
addons = install_stat_addons()
|
||||
logger.debug("Running Daily Analytics Upload")
|
||||
|
||||
analytics_event(category='allianceauth.analytics',
|
||||
action='send_install_stats',
|
||||
analytics_event(namespace='allianceauth.analytics',
|
||||
task='send_install_stats',
|
||||
label='existence',
|
||||
value=1,
|
||||
event_type='Stats')
|
||||
analytics_event(category='allianceauth.analytics',
|
||||
action='send_install_stats',
|
||||
analytics_event(namespace='allianceauth.analytics',
|
||||
task='send_install_stats',
|
||||
label='users',
|
||||
value=users,
|
||||
event_type='Stats')
|
||||
analytics_event(category='allianceauth.analytics',
|
||||
action='send_install_stats',
|
||||
analytics_event(namespace='allianceauth.analytics',
|
||||
task='send_install_stats',
|
||||
label='tokens',
|
||||
value=tokens,
|
||||
event_type='Stats')
|
||||
analytics_event(category='allianceauth.analytics',
|
||||
action='send_install_stats',
|
||||
analytics_event(namespace='allianceauth.analytics',
|
||||
task='send_install_stats',
|
||||
label='addons',
|
||||
value=addons,
|
||||
event_type='Stats')
|
||||
|
||||
for appconfig in apps.get_app_configs():
|
||||
analytics_event(category='allianceauth.analytics',
|
||||
action='send_extension_stats',
|
||||
analytics_event(namespace='allianceauth.analytics',
|
||||
task='send_extension_stats',
|
||||
label=appconfig.label,
|
||||
value=1,
|
||||
event_type='Stats')
|
||||
|
||||
|
||||
@shared_task()
|
||||
def send_ga_tracking_web_view(
|
||||
tracking_id: str,
|
||||
client_id: str,
|
||||
page: str,
|
||||
title: str,
|
||||
locale: str,
|
||||
useragent: str) -> requests.Response:
|
||||
|
||||
"""Celery Task: Do not call directly
|
||||
|
||||
Sends Page View events to GA, Called only via analytics.middleware
|
||||
|
||||
Parameters
|
||||
----------
|
||||
`tracking_id` (str): Unique Server Identifier
|
||||
`client_id` (str): GA Token
|
||||
`page` (str): Page Path
|
||||
`title` (str): Page Title
|
||||
`locale` (str): Browser Language
|
||||
`useragent` (str): Browser UserAgent
|
||||
|
||||
Returns
|
||||
-------
|
||||
requests.Reponse Object
|
||||
"""
|
||||
headers = {"User-Agent": useragent}
|
||||
|
||||
payload = {
|
||||
'v': '1',
|
||||
'tid': tracking_id,
|
||||
'cid': client_id,
|
||||
't': 'pageview',
|
||||
'dp': page,
|
||||
'dt': title,
|
||||
'ul': locale,
|
||||
'ua': useragent,
|
||||
'aip': 1,
|
||||
'an': "allianceauth",
|
||||
'av': __version__
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
ANALYTICS_URL, data=payload,
|
||||
timeout=5, headers=headers)
|
||||
logger.debug(f"Analytics Page View HTTP{response.status_code}")
|
||||
return response
|
||||
|
||||
|
||||
@shared_task()
|
||||
def send_ga_tracking_celery_event(
|
||||
tracking_id: str,
|
||||
client_id: str,
|
||||
category: str,
|
||||
action: str,
|
||||
label: str,
|
||||
value: int) -> requests.Response:
|
||||
measurement_id: str,
|
||||
secret: str,
|
||||
namespace: str,
|
||||
task: str,
|
||||
label: str = "",
|
||||
result: str = "",
|
||||
value: int = 1):
|
||||
"""Celery Task: Do not call directly
|
||||
|
||||
Sends Page View events to GA, Called only via analytics.middleware
|
||||
Sends an events to GA
|
||||
|
||||
Parameters
|
||||
----------
|
||||
`tracking_id` (str): Unique Server Identifier
|
||||
`client_id` (str): GA Token
|
||||
`category` (str): Celery Namespace
|
||||
`action` (str): Task Name
|
||||
`label` (str): Optional, Task Success/Exception
|
||||
`measurement_id` (str): GA Token
|
||||
`secret` (str): GA Authentication Secret
|
||||
`namespace` (str): Celery Namespace
|
||||
`task` (str): Task Name
|
||||
`label` (str): Optional, additional task label
|
||||
`result` (str): Optional, Task Success/Exception
|
||||
`value` (int): Optional, If bulk, Query size, can be a binary True/False
|
||||
|
||||
Returns
|
||||
-------
|
||||
requests.Reponse Object
|
||||
"""
|
||||
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"}
|
||||
parameters = {
|
||||
'measurement_id': measurement_id,
|
||||
'api_secret': secret
|
||||
}
|
||||
|
||||
payload = {
|
||||
'v': '1',
|
||||
'tid': tracking_id,
|
||||
'cid': client_id,
|
||||
't': 'event',
|
||||
'ec': category,
|
||||
'ea': action,
|
||||
'el': label,
|
||||
'ev': value,
|
||||
'aip': 1,
|
||||
'an': "allianceauth",
|
||||
'av': __version__
|
||||
'client_id': AnalyticsIdentifier.objects.get(id=1).identifier.hex,
|
||||
"user_properties": {
|
||||
"allianceauth_version": {
|
||||
"value": "allianceauth_version"
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
ANALYTICS_URL, data=payload,
|
||||
timeout=5, headers=headers)
|
||||
logger.debug(f"Analytics Celery/Stats Event HTTP{response.status_code}")
|
||||
return response
|
||||
},
|
||||
'non_personalized_ads': True,
|
||||
"events": [{
|
||||
"name": "celery_event",
|
||||
"params": {
|
||||
"namespace": namespace,
|
||||
"task": task,
|
||||
'result': result,
|
||||
'label': label,
|
||||
"value": value
|
||||
}
|
||||
}]
|
||||
}
|
||||
try:
|
||||
response = requests.post(
|
||||
ANALYTICS_URL,
|
||||
params=parameters,
|
||||
json=payload,
|
||||
timeout=10)
|
||||
response.raise_for_status()
|
||||
logger.debug(
|
||||
f"Analytics Celery/Stats Event HTTP{response.status_code}")
|
||||
return response.status_code
|
||||
except requests.exceptions.HTTPError as e:
|
||||
logger.debug(e)
|
||||
return response.status_code
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
logger.debug(e)
|
||||
return "Failed"
|
||||
|
||||
Reference in New Issue
Block a user