文章摘要
Stars Harbor Deepseek

又到了主题共建教程系列~今天的教程是如何在关于页接入自建umami数据

本文教程仅适用于通过vercel自建的umami追踪,通过服务器自托管的仅提供部分第三方教程,敬请谅解

搭建数据源

vercel部署umami

  1. fork一份官方的仓库

  2. 登录vercel控制台(若此前尚未注册vercel,请自行借助搜索引擎搜索教程,此处不做赘述)
  3. 在控制台首页顶栏中找到「Storage」,点击进入
    solitude-about_umami-1.webp
  4. 点击「Create Database」新建数据库,选择「Postgres」
    solitude-about_umami-2.webp
  5. 设置名称并确认
    solitude-about_umami-3.webp
  6. 进入数据库控制台,此时页面上会显示一个用于连接数据库的字符串,点击Show Secret按钮后复制双引号中的内容(无需包含双引号)
    solitude-about_umami-4.webp
  7. 新建项目,选择刚刚fork的umami仓库
  8. 设置必要环境变量(数据库)DATABASE_URL,数据库值设置为第5步完成后复制的长字符串
  9. (可选)非必要环境变量TRACKER_SCRIPT_NAME,可设置umami跟踪器名称,以避免默认名称被广告拦截器拦截导致追踪失败。该处可任意填写自己喜欢的值
  10. 等待部署完成即可
  11. (可选)绑定自定义域名,此处不做赘述
  12. 访问umami地址,初次登录时默认用户名为 admin ,默认密码为 umami,可在登录后自行修改

Cloudflare-Workers搭建数据接口

以下教程来自「梦爱吃鱼」,特此鸣谢!原文地址:

  1. 前往 Hoppscotch 获取token
    solitude-about_umami-5.webp
  2. 成功后返回token信息
    solitude-about_umami-6.webp
  3. 前往Cloudflare,创建一个Workers,设置好名称,确认部署并等待
  4. 部署完成,点击右上角编辑代码,修改worker.js的内容(注意,部分内容需修改为你的数据!!!)
    addEventListener('fetch', event => {
      event.respondWith(handleRequest(event));
    });
    
    const API_BASE_URL = '你的umami地址';
    const TOKEN = '第2步中你获取到的token';
    const WEBSITE_ID = '你的博客在umami中的website ID';
    const CACHE_KEY = 'umami_cache'; // 缓存
    const CACHE_TIME = 600; // 缓存时间,单位秒
    
    async function fetchUmamiData(startAt, endAt) {
      const url = `${API_BASE_URL}/api/websites/${WEBSITE_ID}/stats?startAt=${startAt}&endAt=${endAt}`;
      const response = await fetch(url, {
        headers: {
          'Authorization': `Bearer ${TOKEN}`,
          'Content-Type': 'application/json'
        }
      });
    
      if (!response.ok) {
        console.error(`Error fetching data: ${response.statusText}`);
        return null;
      }
    
      return response.json();
    }
    
    async function handleRequest(event) {
      const cache = await caches.open(CACHE_KEY);
      const cachedResponse = await cache.match(event.request);
    
      if (cachedResponse) {
        return cachedResponse;
      }
    
      const now = Date.now();
      const todayStart = new Date(now).setHours(0, 0, 0, 0);
      const yesterdayStart = new Date(now - 86400000).setHours(0, 0, 0, 0);
      const lastMonthStart = new Date(now).setMonth(new Date(now).getMonth() - 1);
      const lastYearStart = new Date(now).setFullYear(new Date(now).getFullYear() - 1);
    
      const [todayData, yesterdayData, lastMonthData, lastYearData] = await Promise.all([
        fetchUmamiData(todayStart, now),
        fetchUmamiData(yesterdayStart, todayStart),
        fetchUmamiData(lastMonthStart, now),
        fetchUmamiData(lastYearStart, now)
      ]);
    
      const 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
      };
    
      const jsonResponse = new Response(JSON.stringify(responseData), {
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
          'Access-Control-Allow-Headers': 'Content-Type, Authorization'
        }
      });
    
      event.waitUntil(cache.put(event.request, jsonResponse.clone()));
    
      return jsonResponse;
    }
  5. 完成编辑后,保存并部署
  6. (可选)绑定自定义域名。在workers中点击设置,在域和路由项下添加自定义域名(受cloudflare限制,域名必须已托管至cloudflare才可绑定)

将数据引入about页面

修改./source/_data/about.yml文件中的统计部分

tj: # 统计
  provider: custom # 51la/custom
  url: 你的数据接口地址
  img: https://7.isyangs.cn/1/65eb2e9109826-1.png # 背景
  desc: # 卡片左下角描述

配置完成~

写在最后

下次一定还拖更