- 添加Umami token自动获取和更新机制 - 实现token有效性检测和自动管理 - 新增update_token.php用于手动更新token - 延长缓存时间至7天减少API调用 - 优化系统稳定性和维护性
205 lines
6.7 KiB
PHP
205 lines
6.7 KiB
PHP
<?php
|
||
header('Content-Type: application/json');
|
||
header("Access-Control-Allow-Origin: *");
|
||
|
||
// 配置 Umami API 的凭据
|
||
$apiBaseUrl = 'https://um.com';
|
||
$username = 'your-username'; // Umami登录用户名
|
||
$password = 'your-password'; // Umami登录密码
|
||
$token = '你的tocken';
|
||
$websiteId = '你的网站id';
|
||
$cacheFile = 'umami_cache.json';
|
||
$tokenFile = 'umami_token.json'; // token缓存文件
|
||
$cacheTime = 604800; // 缓存时间为7天(604800秒)
|
||
|
||
// 获取当前时间戳(毫秒级)
|
||
$currentTimestamp = time() * 1000;
|
||
|
||
// Umami API 的起始时间戳(毫秒级)
|
||
$startTimestampToday = strtotime("today") * 1000;
|
||
$startTimestampYesterday = strtotime("yesterday") * 1000;
|
||
$startTimestampLastMonth = strtotime("-1 month") * 1000;
|
||
$startTimestampLastYear = strtotime("-1 year") * 1000;
|
||
|
||
/**
|
||
* 获取新的Umami token
|
||
* @param string $apiBaseUrl API基础URL
|
||
* @param string $username 用户名
|
||
* @param string $password 密码
|
||
* @return string|null 返回token或null
|
||
*/
|
||
function getNewUmamiToken($apiBaseUrl, $username, $password) {
|
||
$loginUrl = "$apiBaseUrl/api/auth/login";
|
||
$loginData = json_encode([
|
||
'username' => $username,
|
||
'password' => $password
|
||
]);
|
||
|
||
$options = [
|
||
'http' => [
|
||
'method' => 'POST',
|
||
'header' => [
|
||
"Content-Type: application/json",
|
||
"Content-Length: " . strlen($loginData)
|
||
],
|
||
'content' => $loginData
|
||
]
|
||
];
|
||
|
||
$context = stream_context_create($options);
|
||
$response = @file_get_contents($loginUrl, false, $context);
|
||
|
||
if ($response === FALSE) {
|
||
error_log("Failed to get new token from Umami API");
|
||
return null;
|
||
}
|
||
|
||
$responseData = json_decode($response, true);
|
||
return $responseData['token'] ?? null;
|
||
}
|
||
|
||
/**
|
||
* 获取有效的token(自动更新机制)
|
||
* @param string $apiBaseUrl API基础URL
|
||
* @param string $username 用户名
|
||
* @param string $password 密码
|
||
* @param string $tokenFile token缓存文件路径
|
||
* @param string $currentToken 当前token
|
||
* @return string 有效的token
|
||
*/
|
||
function getValidToken($apiBaseUrl, $username, $password, $tokenFile, $currentToken) {
|
||
// 检查token缓存文件
|
||
if (file_exists($tokenFile)) {
|
||
$tokenData = json_decode(file_get_contents($tokenFile), true);
|
||
if ($tokenData && isset($tokenData['token']) && isset($tokenData['timestamp'])) {
|
||
// token缓存7天有效
|
||
if (time() - $tokenData['timestamp'] < 604800) {
|
||
return $tokenData['token'];
|
||
}
|
||
}
|
||
}
|
||
|
||
// 尝试获取新token
|
||
$newToken = getNewUmamiToken($apiBaseUrl, $username, $password);
|
||
if ($newToken) {
|
||
// 保存新token到缓存文件
|
||
$tokenData = [
|
||
'token' => $newToken,
|
||
'timestamp' => time()
|
||
];
|
||
file_put_contents($tokenFile, json_encode($tokenData));
|
||
return $newToken;
|
||
}
|
||
|
||
// 如果获取新token失败,返回当前token
|
||
return $currentToken;
|
||
}
|
||
|
||
/**
|
||
* 检测token是否有效
|
||
* @param string $apiBaseUrl API基础URL
|
||
* @param string $websiteId 网站ID
|
||
* @param string $token 要检测的token
|
||
* @return bool token是否有效
|
||
*/
|
||
function isTokenValid($apiBaseUrl, $websiteId, $token) {
|
||
$testUrl = "$apiBaseUrl/api/websites/$websiteId/stats?startAt=" . (time() * 1000 - 86400000) . "&endAt=" . (time() * 1000);
|
||
$options = [
|
||
'http' => [
|
||
'method' => 'GET',
|
||
'header' => [
|
||
"Authorization: Bearer $token",
|
||
"Content-Type: application/json"
|
||
]
|
||
]
|
||
];
|
||
$context = stream_context_create($options);
|
||
$response = @file_get_contents($testUrl, false, $context);
|
||
|
||
// 检查HTTP响应状态码
|
||
if (isset($http_response_header)) {
|
||
foreach ($http_response_header as $header) {
|
||
if (strpos($header, 'HTTP/') === 0) {
|
||
$statusCode = (int) substr($header, 9, 3);
|
||
return $statusCode === 200;
|
||
}
|
||
}
|
||
}
|
||
|
||
return $response !== FALSE;
|
||
}
|
||
|
||
// 定义 Umami API 请求函数
|
||
function fetchUmamiData($apiBaseUrl, $websiteId, $startAt, $endAt, $token) {
|
||
$url = "$apiBaseUrl/api/websites/$websiteId/stats?" . http_build_query([
|
||
'startAt' => $startAt,
|
||
'endAt' => $endAt
|
||
]);
|
||
$options = [
|
||
'http' => [
|
||
'method' => 'GET',
|
||
'header' => [
|
||
"Authorization: Bearer $token",
|
||
"Content-Type: application/json"
|
||
]
|
||
]
|
||
];
|
||
$context = stream_context_create($options);
|
||
$response = @file_get_contents($url, false, $context);
|
||
|
||
if ($response === FALSE) {
|
||
$error = error_get_last();
|
||
echo "Error fetching data: " . $error['message'] . "\n";
|
||
echo "URL: " . $url . "\n";
|
||
return null;
|
||
}
|
||
|
||
return json_decode($response, true);
|
||
}
|
||
|
||
// 获取有效的token(自动检查和更新)
|
||
$validToken = getValidToken($apiBaseUrl, $username, $password, $tokenFile, $token);
|
||
|
||
// 检查缓存文件是否存在且未过期
|
||
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheTime)) {
|
||
// 读取缓存文件
|
||
$cachedData = file_get_contents($cacheFile);
|
||
echo $cachedData;
|
||
} else {
|
||
// 如果token无效,尝试重新获取
|
||
if (!isTokenValid($apiBaseUrl, $websiteId, $validToken)) {
|
||
$validToken = getNewUmamiToken($apiBaseUrl, $username, $password);
|
||
if ($validToken) {
|
||
// 更新token缓存
|
||
$tokenData = [
|
||
'token' => $validToken,
|
||
'timestamp' => time()
|
||
];
|
||
file_put_contents($tokenFile, json_encode($tokenData));
|
||
}
|
||
}
|
||
|
||
// 获取统计数据
|
||
$todayData = fetchUmamiData($apiBaseUrl, $websiteId, $startTimestampToday, $currentTimestamp, $validToken);
|
||
$yesterdayData = fetchUmamiData($apiBaseUrl, $websiteId, $startTimestampYesterday, $startTimestampToday, $validToken);
|
||
$lastMonthData = fetchUmamiData($apiBaseUrl, $websiteId, $startTimestampLastMonth, $currentTimestamp, $validToken);
|
||
$lastYearData = fetchUmamiData($apiBaseUrl, $websiteId, $startTimestampLastYear, $currentTimestamp, $validToken);
|
||
|
||
// 组装返回的 JSON 数据
|
||
$responseData = [
|
||
"today_uv" => $todayData['visitors']['value'] ?? null,
|
||
"today_pv" => $todayData['pageviews']['value'] ?? null,
|
||
"yesterday_uv" => $yesterdayData['visitors']['value'] ?? null,
|
||
"yesterday_pv" => $yesterdayData['pageviews']['value'] ?? null,
|
||
"last_month_pv" => $lastMonthData['pageviews']['value'] ?? null,
|
||
"last_year_pv" => $lastYearData['pageviews']['value'] ?? null
|
||
];
|
||
|
||
// 将数据写入缓存文件
|
||
file_put_contents($cacheFile, json_encode($responseData));
|
||
|
||
// 输出 JSON 数据
|
||
echo json_encode($responseData);
|
||
}
|
||
?>
|