前言

在写完上篇《使用 Umami Api 显示统计数据》之后,越发的觉得Umami非常有意思。于是就继续看了看官方API,一番了解下来之后,发现通过 Track events 可以实现自定义的页面事件统计。灵光一闪,觉得可以用这玩意做个点赞统计。

使用

使用起来非常简单,只需要在触发事件的元素中加上:

data-umami-event="{event-name}"

例如:

<button id="Like-button" data-umami-event="Like button">点赞</button>

当然,也可以使用 Javascript

const button = document.getElementById('Like-button');

button.onclick = () => umami.track('Like button');

如此一来,Umami就会统计到一个名为 Like button 的事件信息,并为触发次数进行统计。

接口

已经有了统计的信息,下面只需要通过官方的API接口就能获取到统计的数据了。

GET /api/websites/{websiteId}/events

该接口需要5个参数,分别是:

  • startAt: 起始时间.
  • endAt: 终止时间.
  • unit: 时间单位 (year | month | hour | day).
  • timezone: 时区 (ex. Asia/Shanghai).
  • url: 连接.

请求代码如下:

var umiTime = Date.parse(new Date()); //获取当前时间戳
var pathurl = indow.location.pathname; // 获取当前URL路径
var umiUrl = "https://umami.mydomain.com/api/websites/" + <websiteId> + "/events?startAt=0&endAt=" + umiTime + "&unit=hour&url=" + pathurl +"&timezone=Asia/Shanghai"

  fetch(umiUrl,{
    method: 'GET',
    mode: 'cors',
    cache: 'default',
    headers: {
      'Authorization': 'Bearer ' + <Token>,
      'Content-Type': 'application/json'
    }
  })
  .then(res => res.json()).then(resdata => {});

请求成功后,获取到的数据如下:

[
  { "x": "Like button", "t": "2023-04-12 22:00:00", "y": 1 },
  { "x": "Like button", "t": "2023-04-12 22:00:00", "y": 5 },
  { "x": "Like button", "t": "2023-04-12 23:00:00", "y": 4 },
  { "x": "Like button", "t": "2023-04-12 23:00:00", "y": 4 },
  { "x": "Like button", "t": "2023-04-13 00:00:00", "y": 1 }
]

最后

获取到的数据其实是请求的Url页面中,该事件以时间单位统计的一个数组,如果在参数中选择unithour,那么数据将会以小时为单位来分割,每小时的数据为一个对象,以此类推。而我们需要将所有的数据求和来得到我们最终的统计结果。

function groupBy(arr, by) {
  return arr.reduce((groups, item) => {
      // 获取 item 的分组的 key
      const key = by(item);
      // 看看这个组是不是已经存在
      let group = groups.find(g => g.key === key);
      if(!group) {
          // 不存在就创建一个新组
          group = {key, items: []};
          groups.push(group);
      }
      // item 放入组中
      group.items.push(item);
      return groups;
  }, []);
}
let data = groupBy(res, item => item.x)
  .map(g => ({
      x: g.key,
      t: g.items.map(item => item.t),
      y: g.items.reduce((sum, item) => sum + item.y, 0)
  }));
console.log(data);

以上。