ใช้ Google Analytics 4

บทแนะนำนี้จะสาธิตวิธีติดตามการใช้งานส่วนขยายโดยใช้ Google Analytics คุณดูตัวอย่าง Google Analytics 4 ที่ใช้งานได้ใน Github ซึ่ง google-analytics.js มีโค้ดทั้งหมดที่เกี่ยวข้องกับ Google Analytics

ข้อกำหนด

บทแนะนำนี้ถือว่าคุณคุ้นเคยกับการเขียนส่วนขยาย Chrome อยู่แล้ว หากต้องการข้อมูลเกี่ยวกับวิธีเขียนส่วนขยาย โปรดอ่านบทแนะนำการเริ่มต้นใช้งาน

นอกจากนี้ คุณยังต้องตั้งค่าบัญชี Google Analytics 4 เพื่อติดตามส่วนขยายด้วย โปรดทราบว่าเมื่อตั้งค่าบัญชี คุณจะใช้ค่าใดก็ได้ในช่อง URL ของเว็บไซต์ เนื่องจากส่วนขยายจะไม่มี URL ของตัวเอง

การใช้ Measurement Protocol ของ Google Analytics

ตั้งแต่ไฟล์ Manifest V3 เป็นต้นมา ส่วนขยาย Chrome จะไม่ได้รับอนุญาตให้เรียกใช้โค้ดที่โฮสต์จากระยะไกล ซึ่งหมายความว่าคุณต้องใช้ Measurement Protocol ของ Google Analytics เพื่อติดตามเหตุการณ์ส่วนขยาย Measurement Protocol ช่วยให้คุณส่งเหตุการณ์ไปยังเซิร์ฟเวอร์ Google Analytics ได้โดยตรงผ่านคําขอ HTTP ข้อดีของแนวทางนี้คือช่วยให้คุณส่งเหตุการณ์การวิเคราะห์จากทุกที่ในส่วนขยาย รวมถึง Service Worker ได้

ตั้งค่าข้อมูลเข้าสู่ระบบ API

ขั้นตอนแรกคือการขอรับ api_secret และ measurement_id โปรดดูเอกสารประกอบของ Measurement Protocol เพื่อดูวิธีรับข้อมูลเหล่านี้สําหรับบัญชี Analytics

สร้างclient_id

ขั้นตอนที่ 2 คือการสร้างตัวระบุที่ไม่ซ้ำกันสำหรับอุปกรณ์/ผู้ใช้ที่เฉพาะเจาะจง ซึ่งก็คือ client_id รหัสควรจะยังคงเหมือนเดิมตราบใดที่ส่วนขยายยังคงติดตั้งอยู่ในเบราว์เซอร์ของผู้ใช้ โดยอาจเป็นสตริงใดก็ได้ แต่ควรไม่ซ้ำกับไคลเอ็นต์ จัดเก็บ client_id ไว้ใน chrome.storage.local เพื่อให้แน่ใจว่าค่าจะยังคงเหมือนเดิมตราบใดที่ยังติดตั้งส่วนขยายอยู่

การใช้ chrome.storage.local ต้องมีสิทธิ์ storage ในไฟล์ Manifest

manifest.json:

{
  
  "permissions": ["storage"],
  
}

จากนั้นคุณจะใช้ chrome.storage.local เพื่อจัดเก็บ client_id ได้โดยทำดังนี้

function getRandomId() {
  const digits = '123456789'.split('');
  let result = '';

  for (let i = 0; i < 10; i++) {
    result += digits[Math.floor(Math.random() * 9)];
  }

  return result;
}

async function getOrCreateClientId() {
  const result = await chrome.storage.local.get('clientId');
  let clientId = result.clientId;
  if (!clientId) {
    // Generate a unique client ID, the actual value is not relevant. We use
    // the <number>.<number> format since this is typical for GA client IDs.
    const unixTimestampSeconds = Math.floor(new Date().getTime() / 1000);
    clientId = `${this.getRandomId()}.${unixTimestampSeconds}`;
    await chrome.storage.local.set({clientId});
  }
  return clientId;
}

ส่งเหตุการณ์ Analytics

เมื่อมีข้อมูลเข้าสู่ระบบ API และ client_id คุณจะส่งเหตุการณ์ไปยัง Google Analytics ผ่านคำขอ fetch ได้

const GA_ENDPOINT = 'https://www.google-analytics.com/mp/collect';
const MEASUREMENT_ID = `G-...`;
const API_SECRET = `...`;

fetch(
  `${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,
  {
    method: 'POST',
    body: JSON.stringify({
      client_id: await getOrCreateClientId(),
      events: [
        {
          name: 'button_clicked',
          params: {
            id: 'my-button',
          },
        },
      ],
    }),
  }
);

การดำเนินการนี้จะส่งbutton_clickedเหตุการณ์ซึ่งจะปรากฏในรายงานเหตุการณ์ Google Analytics หากต้องการดูเหตุการณ์ในรายงานแบบเรียลไทม์ของ Google Analytics คุณต้องระบุพารามิเตอร์เพิ่มเติม 2 รายการ ได้แก่ session_id และ engagement_time_msec

ใช้พารามิเตอร์ที่แนะนำ session_id และ engagement_time_msec

ทั้ง session_id และ engagement_time_msec เป็นพารามิเตอร์ที่แนะนําเมื่อใช้ Measurement Protocol ของ Google Analytics เนื่องจากจําเป็นสําหรับกิจกรรมของผู้ใช้ที่จะแสดงในรายงานมาตรฐาน เช่น แบบเรียลไทม์

session_id อธิบายระยะเวลาที่ผู้ใช้โต้ตอบกับส่วนขยายอย่างต่อเนื่อง โดยค่าเริ่มต้น เซสชันหนึ่งจะสิ้นสุดลงหลังจากที่ไม่มีกิจกรรมจากผู้ใช้เป็นเวลา 30 นาที และไม่มีการจํากัดระยะเวลาของเซสชัน

ในส่วนขยาย Chrome จะไม่มีแนวคิดที่ชัดเจนเกี่ยวกับเซสชันของผู้ใช้ ซึ่งแตกต่างจากเว็บไซต์ปกติ ดังนั้นคุณต้องกำหนดความหมายของเซสชันผู้ใช้ในส่วนขยาย เช่น การโต้ตอบของผู้ใช้ใหม่ทุกครั้งอาจเป็นเซสชันใหม่ ในกรณีดังกล่าว คุณสามารถสร้างรหัสเซสชันใหม่กับทุกเหตุการณ์ได้ (เช่น ใช้การประทับเวลา)

ตัวอย่างต่อไปนี้แสดงแนวทางที่จะหมดเวลาเซสชันใหม่หลังจากไม่มีการรายงานเหตุการณ์เป็นเวลา 30 นาที (คุณปรับแต่งเวลานี้ให้เหมาะกับพฤติกรรมของผู้ใช้ส่วนขยายได้) ตัวอย่างนี้ใช้ chrome.storage.session เพื่อจัดเก็บเซสชันที่ใช้งานอยู่ขณะที่เบราว์เซอร์ทำงาน เราจะจัดเก็บเวลาล่าสุดที่เหตุการณ์ทริกเกอร์พร้อมกับเซสชัน วิธีตรวจสอบว่าเซสชันที่ใช้งานอยู่หมดอายุแล้วหรือไม่

const SESSION_EXPIRATION_IN_MIN = 30;

async function getOrCreateSessionId() {
  // Store session in memory storage
  let {sessionData} = await chrome.storage.session.get('sessionData');
  // Check if session exists and is still valid
  const currentTimeInMs = Date.now();
  if (sessionData && sessionData.timestamp) {
    // Calculate how long ago the session was last updated
    const durationInMin = (currentTimeInMs - sessionData.timestamp) / 60000;
    // Check if last update lays past the session expiration threshold
    if (durationInMin > SESSION_EXPIRATION_IN_MIN) {
      // Delete old session id to start a new session
      sessionData = null;
    } else {
      // Update timestamp to keep session alive
      sessionData.timestamp = currentTimeInMs;
      await chrome.storage.session.set({sessionData});
    }
  }
  if (!sessionData) {
    // Create and store a new session
    sessionData = {
      session_id: currentTimeInMs.toString(),
      timestamp: currentTimeInMs.toString(),
    };
    await chrome.storage.session.set({sessionData});
  }
  return sessionData.session_id;
}

ตัวอย่างต่อไปนี้จะเพิ่ม session_id และ engagement_time_msec ลงในคำขอเหตุการณ์การคลิกปุ่มก่อนหน้า สําหรับ engagement_time_msec คุณระบุค่าเริ่มต้นเป็น 100 ms ได้

const GA_ENDPOINT = "https://www.google-analytics.com/mp/collect";
const MEASUREMENT_ID = `G-...`;
const API_SECRET = `...`;
const DEFAULT_ENGAGEMENT_TIME_IN_MSEC = 100;

fetch(
`${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,
  {
    method: "POST",
    body: JSON.stringify({
      client_id: await getOrCreateClientId(),
      events: [
        {
          name: "button_clicked",
          params: {
            session_id: await this.getOrCreateSessionId(),
            engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC,
            id: "my-button",
          },
        },
      ],
    }),
  }
);

เหตุการณ์จะแสดงในรายงานแบบเรียลไทม์ของ Google Analytics ดังนี้

เหตุการณ์แบบเรียลไทม์ใน Google Analytics

การติดตามการดูหน้าเว็บในป๊อปอัป แผงด้านข้าง และหน้าส่วนขยาย

Measurement Protocol ของ Google Analytics รองรับpage_viewเหตุการณ์พิเศษสําหรับการติดตามการดูหน้าเว็บ ใช้พารามิเตอร์นี้เพื่อติดตามผู้ใช้ที่เข้าชมหน้าป๊อปอัป แผงด้านข้าง หรือหน้าส่วนขยายในแท็บใหม่ นอกจากนี้ เหตุการณ์ page_view ยังต้องใช้พารามิเตอร์ page_title และ page_location ด้วย ตัวอย่างต่อไปนี้จะทริกเกอร์เหตุการณ์การดูหน้าเว็บที่เหตุการณ์ load ของเอกสารสำหรับป๊อปอัปของส่วนขยาย

popup.js:

window.addEventListener("load", async () => {
  fetch(`${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,
  {
    method: "POST",
    body: JSON.stringify({
      client_id: await getOrCreateClientId(),
      events: [
        {
          name: "page_view",
          params: {
            session_id: await getOrCreateSessionId(),
            engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC,
            page_title: document.title,
            page_location: document.location.href
          },
        },
      ],
    }),
  });
});

คุณต้องนำเข้าสคริปต์ popup.js ในไฟล์ HTML ของป๊อปอัป และควรเรียกใช้ก่อนที่จะมีการเรียกใช้สคริปต์อื่นๆ

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Analytics Demo Popup</title>
    <script src="./popup.js" type="module"></script>
  </head>
  <body>
    <h1>Analytics Demo</h1>
  </body>
</html>

มุมมองป๊อปอัปจะแสดงเหมือนการดูหน้าเว็บอื่นๆ ในรายงานแบบเรียลไทม์ของ Google Analytics ดังนี้

เหตุการณ์การดูหน้าเว็บตามที่แสดงในแดชบอร์ดแบบเรียลไทม์ของ Google Analytics

การติดตามเหตุการณ์วิเคราะห์ใน Service Worker

การใช้ Measurement Protocol ของ Google Analytics ช่วยให้ติดตามเหตุการณ์ Analytics ใน Service Worker ของส่วนขยายได้ ตัวอย่างเช่น การฟังเหตุการณ์ unhandledrejection event ใน Service Worker จะช่วยให้คุณบันทึกข้อยกเว้นที่ไม่ได้จัดการใน Service Worker ไปยัง Google Analytics ได้ ซึ่งจะช่วยในการแก้ไขข้อบกพร่องที่ผู้ใช้อาจรายงานได้เป็นอย่างมาก

service-worker.js:

addEventListener("unhandledrejection", async (event) => {
  `${GA_ENDPOINT}?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`,
  {
    method: "POST",
    body: JSON.stringify({
      client_id: getOrCreateClientId(),
      events: [
        {
          // Note: 'error' is a reserved event name and cannot be used
          // see https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=gtag#reserved_names
          name: "extension_error",
          params: {
            session_id: await this.getOrCreateSessionId(),
            engagement_time_msec: DEFAULT_ENGAGEMENT_TIME_IN_MSEC,
            message: error.message,
            stack: error.stack,
          },
        },
      ],
    }),
  }
});

ตอนนี้คุณจะเห็นเหตุการณ์ข้อผิดพลาดในรายงาน Google Analytics แล้ว

เหตุการณ์ข้อผิดพลาดตามที่แสดงในแดชบอร์ดเหตุการณ์ Google Analytics

การแก้ไขข้อบกพร่อง

Google Analytics มีฟีเจอร์ที่มีประโยชน์ 2 อย่างสําหรับการแก้ไขข้อบกพร่องของเหตุการณ์ Analytics ในส่วนขยาย

  1. ปลายทางการแก้ไขข้อบกพร่องพิเศษ https://www.google-analytics.com**/debug**/mp/collect ที่จะรายงานข้อผิดพลาดในคำจำกัดความเหตุการณ์
  2. รายงานแบบเรียลไทม์ของ Google Analytics ซึ่งจะแสดงเหตุการณ์เมื่อเข้ามา