banner
克喵爱吃卤面

喵落阁

光就是一切的意义!
telegram
github
qq
email
x
bilibili

Umami Blog Access Statistics Vercel+Cloudflare Workers Deployment

Cover

Part One: Vercel+Umami#

  1. Step One
    1.1 Forkumami to your own Github repository

    image

    1.2 Create a project
    image
    index.mdx

  2. Step Two

 2.1 Create a Vercel account, I will skip this part because you can authorize directly with GitHub.

2.2 After you authorize, first create a Postgres database, just click next all the way, and once created, you can copy the connection below.

image

image

  Click Copy Snippet​, and remember that when pasting, it is the part I have underlined, no double quotes are needed, as you need to set environment variables.

   2.3 After creating the database, return to the main page's Overview​, then in the upper right corner, there is a Add New​ option to add a Project​, select your Fork​ of umami​ and add it.
2.4 Set the environment variables, DATABASE_URL​, HASH_SALT​, and TRACKER_SCRIPT_NAME​, where the value of DATABASE_URL​ is the part I underlined above, and the other two environment variables can be defined as String values of your choice.
   2.5 After setting up, click Deploy​, wait about two minutes, and the automatic deployment will be completed. After deployment, you can access it directly through the link provided in the panel below.

image

   2.6 After opening, a login page will pop up, the default login password is adminumami​, after logging in, set your own password, and then add the website you want to track in the settings. At this point, you can see the statistical data in the panel when others visit your website.

Part Two: Umami+Cloudflare worker#

This part mainly allows you to display access data on your blog, as shown below:

image

  1. Register a CloudFlare​ account, then after entering, select Workers​ and Pages​, click Create​, and then click Deploy

image

image

  After deployment, click to edit the code and replace the code inside with:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event));
});

const API_BASE_URL = 'https://umami.yourdomain.com';  // Replace with your deployed umami domain
const TOKEN = 'your_token'; // The token you obtained
const WEBSITE_ID = 'your_website_id'; // The website id added in umami
const CACHE_KEY = 'umami_cache';
const CACHE_TIME = 600; // Cache time in seconds

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;
}

  However, there are several important parameters that need to be modified: API_BASE_URL​, TOKEN​, and WEBSITE_ID​. The API_BASE_URL​ and WEBSITE_ID​ are already available, and the WEBSITE_ID​ can be found in umami​ settings. Select the website you have added, click Edit​, and the website's WEBSITE_ID​ will appear:

image

   2.2 Obtain the token​ from the api​ testing website, hoppscotch. After navigating to this page, it will look like the following image:

image

   2.2.1 Select the request method as post​, and fill in the link as:

https://your umami domain or link/api/auth/login

   2.2.2 Select Body​ for the request body and set the parameter format to application/json

{
 "username":"username",
 "password":"password"
}

   2.2.3 The content in the token​ of the returned result is the required token

{
  "token": "your token", # This is the content you need to record
  "user": {
    "id": "41e2b680-648e-4b09-bcd7-3e2b10c06264",
    "username": "admin",
    "role": "admin",
    "createdAt": "2024-11-12T09:18:12.766Z",
    "isAdmin": true
  }
}

  At this point, you have all the parameter contents needed for deploying the api​, just replace them accordingly.

   2.3 After you have deployed, there will be a link. If you are using cloudflare​ to proxy your domain, you can directly associate it.

image

  Then click or copy and paste it into the browser. After the request, the following result will appear:

image

  If there is no result, it is recommended to check the umami panel you deployed to see if there is any data. If there is data, the request here will have data as well. Clear the browser cache and test with the proxy.

Part Three: Adding Blog Statistics#

  Add the data to the about​ page

tj: # Statistics
  provider: custom # custom
  url: your data interface address
  img: https://7.isyangs.cn/1/65eb2e9109826-1.png # Background
  desc: # Description in the lower left corner of the card

  Configuration complete~

  Thanks to starsharbor for the guidance from the blog, original text


Author's Original Text#

Author: Couture
Link: https://www.coutures.top/posts/27233.html
Source: Couture
Copyright belongs to the author. For commercial reproduction, please contact the author for authorization; for non-commercial reproduction, please indicate the source.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.