Matomo Heartbeat !exclusive! [UPDATED]

destroy() this.stopHeartbeat(); if (this.idleCheckId) clearInterval(this.idleCheckId); this.log('Heartbeat destroyed');

public function getEngagementReport($dateRange = 'last30') $apiUrl = $this->matomoUrl . '/index.php'; $params = [ 'module' => 'API', 'method' => 'CustomEvents.getCustomEvent', 'idSite' => $this->siteId, 'period' => 'range', 'date' => $dateRange, 'format' => 'json', 'filter_limit' => -1 ]; if ($this->tokenAuth) $params['token_auth'] = $this->tokenAuth; $url = $apiUrl . '?' . http_build_query($params); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); return json_decode($response, true); matomo heartbeat

$input = json_decode(file_get_contents('php://input'), true); $result = $handler->processHeartbeat($input); destroy() this

sendFinalHeartbeat() if (this.isActive && this.lastHeartbeatTime) const engagedTime = Math.floor((Date.now() - this.lastHeartbeatTime) / 1000); if (engagedTime >= this.options.minVisitLength) const finalData = action_name: 'Final Heartbeat', e_c: 'Engagement', e_a: 'end', e_n: 'Session End', e_v: engagedTime, total_engaged: this.totalEngagedTime + engagedTime ; if (window._paq) window._paq.push(['trackEvent', finalData.e_c, finalData.e_a, finalData.e_n, finalData.e_v]); // Use synchronous ping for final heartbeat this.sendBeacon(finalData); $ch = curl_init()

$data = json_decode(file_get_contents('php://input'), true); $result = $tracker->recordHeartbeat( session_id(), $data['visitor_id'] ?? '', $data['page_url'] ?? '', $data['engaged_time'] ?? 0 );