Node.js 查询 Google Analytics 4 数据:GA Lite API 接入实战

最近在做一个小型站点看板,需求不复杂:每天定时拉一次 GA4 数据,看看过去 28 天的页面浏览、来源国家、搜索表现,再把结果塞进自己的后台和日报里。

如果直接接 Google Analytics Data API,需要处理 Google Cloud 项目、OAuth、Service Account、属性权限这些配置。对于只想在服务端读统计数据的场景,我更愿意用一层轻一点的 API,把鉴权、项目映射和常用报表接口收拢起来。

这篇记录一下如何用 Node.js 通过 GA Lite API 查询 Google Analytics 4 数据。API Key 可以登录 GA Lite 官网后,在账号设置里创建。Key 只放在服务端环境变量里,不建议塞到前端代码或浏览器里。

接入前准备

GA Lite 的公开 API 是只读接口,基础地址是:

txt 复制代码
https://galite.io/api/v1

请求时通过 Bearer Token 鉴权:

txt 复制代码
Authorization: Bearer sk_live_xxxxxxxxxxxxx

先准备两个环境变量:

bash 复制代码
export GALITE_API_KEY="sk_live_xxxxxxxxxxxxx"
export GALITE_PROJECT_KEY="your_project_key"

如果还不知道 projectKey,可以先调用项目列表接口拿到:

http 复制代码
GET /projects/list

时间范围支持 todayyesterday7days28days90days180days365days,也可以用自定义区间。日常报表我一般先用 28days,比 7 天稳定,也不会像 90 天那样把近期波动抹平。

封装一个 Node.js 请求方法

下面示例基于 Node.js 18+,直接使用内置 fetch。如果你的运行环境比较老,可以换成 undicinode-fetch

js 复制代码
const BASE_URL = "https://galite.io/api/v1";

function requireEnv(name) {
  const value = process.env[name];
  if (!value) {
    throw new Error(`Missing environment variable: ${name}`);
  }
  return value;
}

const API_KEY = requireEnv("GALITE_API_KEY");

async function galiteGet(path, query = {}) {
  const url = new URL(`${BASE_URL}${path}`);

  for (const [key, value] of Object.entries(query)) {
    if (value !== undefined && value !== null) {
      url.searchParams.set(key, String(value));
    }
  }

  const res = await fetch(url, {
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      Accept: "application/json",
    },
  });

  if (!res.ok) {
    const text = await res.text();
    throw new Error(`GA Lite API ${res.status}: ${text}`);
  }

  return res.json();
}

这个函数做两件事:统一拼查询参数,以及把错误响应原样抛出来。接第三方接口时我比较建议保留服务端返回的错误文本,排查权限、项目 Key、参数拼错会快很多。

第一步:列出可访问项目

第一次接入时先不要急着查数据,先确认当前 API Key 能看到哪些项目。

js 复制代码
async function listProjects() {
  const projects = await galiteGet("/projects/list");
  console.dir(projects, { depth: null });
}

listProjects().catch(console.error);

项目接口会返回你在 GA Lite 里可访问的站点和已连接的数据源。这里拿到的 projectKey 后面会频繁用到。注意它是 GA Lite 的项目标识,不是 GA4 的 property id。

第二步:查询 GA4 汇总数据

最常用的是 summary 接口,比如查过去 28 天的站点统计:

js 复制代码
async function getSiteSummary(projectKey, period = "28days") {
  return galiteGet(`/metrics/${projectKey}/summary`, { period });
}

const projectKey = process.env.GALITE_PROJECT_KEY;

getSiteSummary(projectKey).then((data) => {
  console.dir(data, { depth: null });
});

这个接口适合放在概览页、日报邮件、运营看板里。因为返回的是 JSON,后端可以继续做缓存、格式化或者入库,不需要让业务系统直接理解 Google Analytics 的完整报表结构。

第三步:按时间拉趋势

如果要画折线图,比如页面浏览量趋势,可以用 timeseries 接口。下面以 GA4 常见的 screenPageViews 为例:

js 复制代码
async function getPageViewTrend(projectKey, period = "28days") {
  return galiteGet(`/metrics/${projectKey}/timeseries`, {
    period,
    metric: "screenPageViews",
  });
}

const trend = await getPageViewTrend(projectKey);
console.dir(trend, { depth: null });

拿到趋势数据后,前端可以直接交给 ECharts、Chart.js 或自己的图表组件。我的习惯是在服务端把 period、metric 和项目 Key 都收敛成白名单参数,避免前端随意拼接口。

第四步:按维度拆分

除了总量和趋势,实际分析里更常问的是"流量从哪里来"。可以用 dimension 接口按国家维度查询:

js 复制代码
async function getCountryBreakdown(projectKey, period = "28days") {
  return galiteGet(`/metrics/${projectKey}/dimension`, {
    period,
    dimension: "country",
  });
}

const countries = await getCountryBreakdown(projectKey);
console.dir(countries, { depth: null });

这个接口也适合扩展到页面、来源、设备等维度。正式落地时建议先选出业务真正会看的 3 到 5 个维度,不要一上来把所有数据都拉回来。统计数据不是越多越好,能稳定回答问题才重要。

第五步:查询实时数据

如果站点刚发版、刚投放或者刚上线活动页,可以读实时接口:

js 复制代码
async function getRealtime(projectKey) {
  return galiteGet(`/metrics/${projectKey}/realtime`);
}

const realtime = await getRealtime(projectKey);
console.dir(realtime, { depth: null });

实时接口适合做"现在有没有人访问"的轻量检查。它不适合替代正式报表,也不建议高频轮询。需要做大屏的话,可以在自己的服务端加一层短缓存。

顺手把搜索数据也接进来

如果项目里同时连接了 Google Search Console 或 Bing Webmaster,GA Lite 也提供搜索数据接口。比如查 28 天搜索表现汇总:

js 复制代码
async function getSearchSummary(projectKey, period = "28days", sp = "all") {
  return galiteGet(`/metrics/${projectKey}/search/summary`, {
    period,
    sp,
  });
}

const search = await getSearchSummary(projectKey, "28days", "all");
console.dir(search, { depth: null });

sp 可以传 allgscbing。如果你只关心 Google Search Console,就传 gsc。如果想看关键词维度,可以改成:

js 复制代码
async function getSearchQueries(projectKey, period = "28days") {
  return galiteGet(`/metrics/${projectKey}/search/dimension`, {
    period,
    dimension: "query",
    sp: "gsc",
  });
}

这块对 SEO 很有用。流量数据告诉你用户来了多少,搜索数据能告诉你用户是通过哪些词来的,两边放在一起看,才更容易判断内容是不是跑偏。

需要原生 GA4 结构时,用 raw proxy

大多数场景用前面的 curated endpoints 就够了。如果你已经有一套按 GA4 runReport 设计的请求体,也可以用 raw provider proxy。

js 复制代码
async function galitePost(path, body) {
  const res = await fetch(`${BASE_URL}${path}`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      "Content-Type": "application/json",
      Accept: "application/json",
    },
    body: JSON.stringify(body),
  });

  if (!res.ok) {
    const text = await res.text();
    throw new Error(`GA Lite API ${res.status}: ${text}`);
  }

  return res.json();
}

async function runGa4Report(projectKey, propertyId) {
  return galitePost("/raw/ga4/proxy", {
    project_key: projectKey,
    path: `properties/${propertyId}:runReport`,
    body: {
      dateRanges: [{ startDate: "28daysAgo", endDate: "today" }],
      dimensions: [{ name: "country" }],
      metrics: [{ name: "screenPageViews" }],
    },
  });
}

这里的 propertyId 仍然是 GA4 的属性 ID。我的建议是:只有在你确实需要原生 GA4 返回结构,或者要迁移已有 GA4 请求体时才用 raw proxy;普通业务报表优先用 summary、timeseries、dimension 这些更稳定的接口。

放到 Express 里做一个后端接口

最后给一个更贴近业务项目的例子。前端只访问你的后端,后端再去请求 GA Lite:

js 复制代码
import express from "express";

const app = express();
const projectKey = requireEnv("GALITE_PROJECT_KEY");

app.get("/api/analytics/overview", async (req, res, next) => {
  try {
    const period = req.query.period || "28days";

    const [summary, trend, countries, search] = await Promise.all([
      getSiteSummary(projectKey, period),
      getPageViewTrend(projectKey, period),
      getCountryBreakdown(projectKey, period),
      getSearchSummary(projectKey, period, "all"),
    ]);

    res.json({
      period,
      summary,
      trend,
      countries,
      search,
    });
  } catch (error) {
    next(error);
  }
});

app.listen(3000, () => {
  console.log("Analytics API listening on http://localhost:3000");
});

这个结构有几个好处:

  • API Key 不会暴露给浏览器;
  • 业务系统只依赖自己的 /api/analytics/overview
  • 后续要加缓存、限流、日志和告警都比较自然;
  • GA4、GSC、Bing 的数据可以在服务端统一整理。

接入时我会注意的几个细节

第一,API Key 只放服务端。即使 GA Lite 的接口是只读的,也不应该把 Key 打进前端包里。

第二,定时任务不要无脑刷新。文档里提到 force=1 更适合手动刷新流程,常规看板可以用自己的缓存策略。

第三,projectKeyperiodmetricdimension 都建议做白名单。统计接口经常会被多个页面复用,参数一放开,后面排查数据口径会很麻烦。

第四,先做一个最小闭环:项目列表、汇总、趋势、国家维度、搜索汇总。跑通之后再考虑 funnel、raw proxy 或更细的维度拆分。

小结

用 Node.js 接 GA Lite 查询 Google Analytics 4 数据,核心流程其实很短:创建 API Key,拿到项目 Key,用 Bearer Token 调 REST API,然后把返回的 JSON 接进自己的服务端。

如果你的目标是做站点看板、自动日报、SEO 内容监控或者多站点运营后台,这种方式比从零处理 Google Analytics OAuth 要轻不少。关键是把 Key 放好,把接口封装在后端,并且尽早统一统计口径。后面不管是接图表、发日报,还是给内部工具用,都会顺很多。

相关推荐
寒水馨2 小时前
Linux下载、安装 Bun v1.3.14(附安装包bun-linux-x64.zip)
linux·javascript·typescript·node.js·bun·运行时·包管理器
兮动人3 小时前
Linux 安装 Claude Code 实战:Node.js、npm、GLM 配置一次跑通
linux·npm·node.js·cc·claude code
csdn2015_4 小时前
怎么更换node.js版本
node.js
在水一缸5 小时前
深入浅出:Node.js 下一代 ORM 架构设计与实战解析
数据库·微服务·云原生·node.js·orm·架构设计
CodexDave5 小时前
没有Codex,也能使用Agent Skills完成仓库体检
node.js·agent skills·仓库体检·工程评测
海上彼尚2 天前
Nodejs也能写Agent - 22.LangGraph篇 - 上下文工程
前端·javascript·人工智能·langchain·node.js
码农学院2 天前
Node.js MongoDB构建户外用品GEO优化内容管理平台
数据库·mongodb·node.js
会周易的程序员3 天前
js-shm: 高性能 Node.js 共享内存模块
开发语言·javascript·c++·node.js·共享内存·shm
5G微创业3 天前
Python / Node.js 调用短视频去水印 API 完整示例(含 SDK)
python·node.js·音视频·api·sdk·短视频