我需要 Google Data API 的 Oauth2 令牌以及 React 应用程序的客户端 ID 和客户端密钥

问题描述 投票:0回答:1

我想通过谷歌数据API从谷歌分析获取数据。请求如下。

export async function fetchAnalyticsData() {
  //   getAccessToken();

  const GA4_PROPERTY_ID = "";
  const url = `https://analyticsdata.googleapis.com/v1beta/properties/${GA4_PROPERTY_ID}:runReport`;

  const requestOptions = {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      // Add your authorization token here if required
      Authorization: "Bearer YOUR_ACCESS_TOKEN",
    },
    body: JSON.stringify({
      dateRanges: [{ startDate: "2023-09-01", endDate: "2023-09-15" }],
      dimensions: [{ name: "country" }],
      metrics: [{ name: "activeUsers" }],
    }),
  };

  try {
    const response = await fetch(url, requestOptions);
    const data = await response.json();
    console.log(data); // Do whatever you need with the data
  } catch (error) {
    console.error("Error fetching data:", error);
  }
}

此请求返回 401。“请求的身份验证凭据无效。需要 OAuth 2 访问令牌、登录 cookie 或其他有效的身份验证凭据”。

因此,我创建了 Oauth2 客户端 ID 和客户端密钥:

(https://i.stack.imgur.com/iDSSU.png)

如果可能的话,如何使用客户端 ID 和密钥获取请求的令牌。我不希望用户登录。 -

javascript oauth-2.0 google-analytics-api google-api-js-client
1个回答
0
投票

这是我访问实时 API 的示例,您必须更改它才能使用标准报告

配置.js

const appConfig = {
  'CLIENT_ID' :  'READACTEd',
  'API_KEY' : 'REDACTED',
  'PROPERTY_ID':'250796939'
}

实时.js

<!DOCTYPE html>
<html>
<head>
    <title>Gmail API Quickstart</title>
    <meta charset="utf-8" />
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
        google.charts.load('current', {
            'packages':['geochart'],
        });
        function drawRegionsMap(mapData) {
            var data = google.visualization.arrayToDataTable(mapData);

            var options = {};

            var chart = new google.visualization.GeoChart(document.getElementById('regions_div'));

            chart.draw(data, options);
        }
    </script>
</head>
<body>
<p>google analytics data API realtime Quickstart</p>

<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize_button" onclick="handleAuthClick()">Authorize</button>
<button id="signout_button" onclick="handleSignoutClick()">Sign Out</button>

<pre id="content" style="white-space: pre-wrap;"></pre>
<script src="config.js"></script>
<script type="text/javascript">

    /* exported gapiLoaded */
    /* exported gisLoaded */
    /* exported handleAuthClick */
    /* exported handleSignoutClick */

    // TODO(developer): Set to client ID and API key from the Developer Console
    const CLIENT_ID = appConfig.CLIENT_ID
    const API_KEY = appConfig.API_KEY

    // Discovery doc URL for APIs used by the quickstart
    const DISCOVERY_DOC = 'https://analyticsdata.googleapis.com/$discovery/rest?version=v1beta';

    // Authorization scopes required by the API; multiple scopes can be
    // included, separated by spaces.
    const SCOPES = 'https://www.googleapis.com/auth/analytics.readonly';

    const PROPERTY_ID = appConfig.PROPERTY_ID

    let tokenClient;
    let gapiInited = false;
    let gisInited = false;

    document.getElementById('authorize_button').style.visibility = 'hidden';
    document.getElementById('signout_button').style.visibility = 'hidden';

    /**
     * Callback after api.js is loaded.
     */
    function gapiLoaded() {
        gapi.load('client', initializeGapiClient);
    }

    /**
     * Callback after the API client is loaded. Loads the
     * discovery doc to initialize the API.
     */
    async function initializeGapiClient() {
        await gapi.client.init({
            apiKey: API_KEY,
            discoveryDocs: [DISCOVERY_DOC],
        });
        gapiInited = true;
        maybeEnableButtons();
    }

    /**
     * Callback after Google Identity Services are loaded.
     */
    function gisLoaded() {
        tokenClient = google.accounts.oauth2.initTokenClient({
            client_id: CLIENT_ID,
            scope: SCOPES,
            callback: '', // defined later
        });
        gisInited = true;
        maybeEnableButtons();
    }

    /**
     * Enables user interaction after all libraries are loaded.
     */
    function maybeEnableButtons() {
        if (gapiInited && gisInited) {
            document.getElementById('authorize_button').style.visibility = 'visible';
            if (localStorage.getItem('accessToken')) {
                handleAuthClick()
            }
        }

    }

    /**
     *  Sign in the user upon button click.
     */
    function handleAuthClick() {
        tokenClient.callback = async (resp) => {
            if (resp.error !== undefined) {
                throw (resp);
            }
            document.getElementById('signout_button').style.visibility = 'visible';
            document.getElementById('authorize_button').innerText = 'Refresh';
            const token = gapi.client.getToken();
            localStorage.setItem('accessToken', token.access_token);
            await getRealTime();
        };

        if (localStorage.getItem('accessToken')) {
            // get saved access token.
            access_token = localStorage.getItem('accessToken')
            // set it in the client
            gapi.client.setToken({ access_token: access_token });
            const token = gapi.client.getToken();
            //document.getElementById('content').innerText = "Reading from local storage: " + token.access_token
            getRealTime();
            document.getElementById('signout_button').style.visibility = 'visible';
            document.getElementById('authorize_button').innerText = 'Refresh';

        } else if (gapi.client.getToken() === null) {
            // Prompt the user to select a Google Account and ask for consent to share their data
            // when establishing a new session.
            tokenClient.requestAccessToken({prompt: 'consent'});
        } else {
            // Skip display of account chooser and consent dialog for an existing session.
            tokenClient.requestAccessToken({prompt: ''});
            const token = gapi.client.getToken();
            // save the access token to localstorage to prevent loss during a refresh
            localStorage.setItem('accessToken', token.access_token);
        }
    }

    /**
     *  Sign out the user upon button click.
     */
    function handleSignoutClick() {
        const token = gapi.client.getToken();
        if (token !== null) {
            // Clear the access token from the client and the local storage.
            gapi.client.setToken('');
            localStorage.removeItem('accessToken');
            document.getElementById('content').innerText = '';
            document.getElementById('authorize_button').innerText = 'Authorize';
            document.getElementById('signout_button').style.visibility = 'hidden';
        }
    }

    /**
     * Realtime reports show events and usage data for the periods of time ranging
     * from the present moment to 30 minutes ago (up to 60 minutes for Google Analytics
     * 360 properties) and can be used for applications such as live counters of visitors
     * on your website.
     */
    async function getRealTime() {
        let response;
        try {
            response = await gapi.client.analyticsdata.properties.runRealtimeReport({
                'property': 'properties/' + PROPERTY_ID,
                dimensions: [{ name: 'country', },],
                metrics: [{ name: 'activeUsers', },],
            });
        } catch (err) {
            document.getElementById('content').innerText = err.message;
            return;
        }
        const data = response.result;

        if (!data) {
            document.getElementById('content').innerText = 'Error requesting profile.';
            return;
        }

        const jsonString = JSON.stringify(data);

        const rows = data.rows
        if (!rows) {
            document.getElementById('content').innerText = 'No data ' + jsonString;
            return;
        }

        const formattedData = [];

        // Add the header row
        formattedData.push(['city', 'activeUsers']);

        // Process each data item
        for (const row of rows) {
            const city = row.dimensionValues[0].value;
            const activeUsers = parseInt(row.metricValues[0].value);

            // Add the formatted data row
            formattedData.push([city, activeUsers]);
        }


        drawRegionsMap(formattedData)
        //document.getElementById('content').innerText = jsonString
    }
</script>
<script async defer src="https://apis.google.com/js/api.js" onload="gapiLoaded()"></script>
<script async defer src="https://accounts.google.com/gsi/client" onload="gisLoaded()"></script>
<div id="regions_div" style="width: 900px; height: 500px;"></div>
</body>
</html>

这应该足以让您开始,直到我有时间为标准报告创建另一个示例

© www.soinside.com 2019 - 2024. All rights reserved.