서버 측 태그 지정 소개에서 태그 관리자의 서버 측 태그 지정에 대해 간략히 살펴보고, 클라이언트의 정의와 역할을 알아봤습니다. 클라이언트는 사용자 기기에서 이벤트 데이터를 수신하고 컨테이너의 나머지 부분에서 사용할 수 있도록 조정합니다. 이 도움말에서는 서버 측 태그에서 해당 데이터를 처리하는 방법을 설명합니다.
서버 컨테이너에서 태그는 클라이언트로부터 들어오는 이벤트 데이터를 수신하고 변환한 후 수집과 분석을 위해 다시 전송합니다. 태그는 개발자가 원하는 곳 어디에나 데이터를 전송할 수 있습니다. 대상이 HTTP 요청을 수락하는 한, 태그는 서버 컨테이너의 데이터도 수락할 수 있습니다.
서버 컨테이너에는 다음과 같이 맞춤 구성 없이 사용할 수 있는 기본 제공 태그 3개가 있습니다.
- Google 애널리틱스 4
- HTTP 요청
Google 애널리틱스 이외의 위치에 데이터를 전송하려고 하거나, HTTP 요청 태그에서 제공하는 것보다 더 많은 기능이 필요한 경우에는 다른 태그를 사용해야 합니다. 커뮤니티 템플릿 갤러리에서 추가 태그를 찾거나 태그를 직접 작성할 수 있습니다. 이 튜토리얼에서는 서버 컨테이너를 위한 자체 태그 작성의 기본 사항을 설명합니다.
목표
- 이벤트 데이터를 읽고, HTTP 요청을 전송하고, 브라우저에서 쿠키를 설정하는 데 사용할 API를 알아봅니다.
- 태그의 구성 옵션을 설계하기 위한 권장사항을 알아봅니다.
- 사용자 지정 데이터와 자동 수집 데이터 간의 차이점과 구분이 중요한 이유를 알아봅니다.
- 서버 컨테이너에서 태그의 역할을 알아봅니다. 태그 구현 시 필수 사항과 금지 사항을 이해합니다.
- 커뮤니티 템플릿 갤러리에 태그 템플릿을 제출하는 것을 고려해야 하는 경우를 알아봅니다.
기본 요건
Baz Analytics 태그
이 튜토리얼에서는 Baz Analytics라는 서비스로 측정 데이터를 보내는 태그를 만듭니다.
Baz Analytics는 https://example.com/baz_analytics
에 대한 HTTP GET 요청을 통해 데이터를 수집하는
간단한 가상 분석 서비스입니다. 여기에는 다음과 같은 매개변수가
있습니다.
매개변수 | 예 | 설명 |
---|---|---|
id | BA-1234 | Baz Analytics 계정의 ID입니다. |
en | click | 이벤트 이름입니다. |
l | https://www.google.com/search?q=sgtm
|
이벤트가 발생한 페이지의 URL입니다. |
u | 2384294892 | 작업을 수행하는 사용자의 ID입니다. 여러 작업을 단일 사용자와 다시 연결하는 데 사용됩니다. |
태그 구성
가장 먼저 해야 할 일은 태그 템플릿을 만드는 것입니다. 컨테이너의 템플릿 섹션으로 이동하고 태그 템플릿 섹션에서 새로 만들기를 클릭합니다. 태그에 이름과 설명을 추가합니다.
그런 다음 템플릿 편집기의 필드 섹션으로 이동하여 태그에 다양한 구성 옵션을 추가합니다. 그러면 어떤 옵션이 필요한지 궁금할 것입니다. 태그를 만드는 방법에는 다음과 같이 세 가지가 있습니다.
- 전부 구성: 모든 매개변수에 구성 필드를 추가합니다. 사용자가 모든 항목을 명시적으로 설정해야 합니다.
- 구성 없음: 태그 구성 옵션이 없습니다. 모든 데이터를 이벤트에서 직접 가져옵니다.
- 일부 구성: 일부 매개변수에 대한 필드만 있습니다.
모든 매개변수에 대한 필드가 있으면 매우 유연하며 사용자가 태그 구성을
완전히 제어할 수 있습니다. 하지만 실제로는 많은 작업이
중복됩니다. 특히 페이지 URL이 포함된 Baz Analytics l
매개변수와 같은 요소는 명확하고 보편적입니다.
태그가 구성될 때마다 변경되지 않는 동일한 데이터를 입력하는 것이
컴퓨터에 가장 적합합니다.
이벤트에서 데이터를 가져오기만 하는 태그를 사용하는 것이 정답일 수 있습니다. 이 태그가 실질적으로 수행하는 작업은 없기 때문에 이 태그는 사용자가 구성할 수 있는 가장 간단한 태그이지만, 가장 제한적이면서 취약한 옵션이기도 합니다. 필요한 경우라도 사용자는 태그의 동작을 변경할 수 없습니다.
예를 들어 웹사이트 및 Google 애널리틱스에서는 이벤트를 purchase
라고 하지만,
Baz Analytics에서는 이를 buy
라고 할 수 있습니다. 또는 들어오는 이벤트 데이터의
구조에 대한 태그의 가정이 실제로는 맞지 않을 수
있습니다. 두 경우 모두 사용자가 특정 동작을 할 수 없습니다.
많은 경우에서 그렇듯, 답은 두 극단 사이에 있습니다. 일부 데이터는 항상 이벤트에서 가져오는 것이 좋으며, 기타 데이터는 사용자가 구성해야 합니다. 이벤트에서 가져올 데이터와 사용자가 구성할 데이터는 어떻게 결정할 수 있을까요? 이 질문에 답하려면 컨테이너에 들어오는 데이터를 자세히 살펴봐야 합니다.
데이터는 어디에서 유입되나요?
Google 애널리틱스 4 태그에서 서버 컨테이너로 들어오는 데이터는 사용자 지정 데이터와 자동 수집 데이터라는 두 가지 카테고리로 나눌 수 있습니다.
사용자 지정 데이터는 사용자가 gtag.js event
명령어에 입력하는 모든
데이터입니다. 예를 들어 명령어는 다음과 같습니다.
gtag('event', 'search', {
search_term: 'beets',
});
그러면 서버 컨테이너의 매개변수는 다음과 같습니다.
{
event_name: 'search',
search_term: 'beets',
}
이는 간단하지만 태그의 관점에서는 사용하기가 매우
어렵습니다. 이 데이터는 사용자가 입력한 것이므로 무엇이든 될 수 있습니다.
위와 같이 사용자는
추천 이벤트 및 매개변수만 전송할 테지만,
그럴 필요는 없습니다. event_name
매개변수의 위치(값이 아님)를
제외하고, 사용자 데이터의 형식이나
구조에 대한 보장은 없습니다.
다행히 컨테이너에서는 사용자가 입력한 데이터만 수신하지는 않습니다. 브라우저의 Google 애널리틱스 4 태그에서 자동 수집되는 많은 데이터도 가져옵니다. 여기에는 다음이 포함됩니다.
ip_override
language
page_location
page_referrer
page_title
screen_resolution
user_agent
또한 서버 요청이 웹브라우저에서 온 경우 getCookieValue
API를 통해 브라우저 쿠키
데이터를 사용할 수도 있습니다.
쿠키 데이터는 위에 언급된 자동 수집 데이터를 구성합니다. 대개 자동 수집 데이터는 보편적이고 의미론적으로 분명한 데이터로 구성됩니다. 브라우저의 GA4 태그에서 요청이 들어오면 이 데이터가 항상 제공되며 데이터 형식은 늘 동일합니다. 이러한 매개변수에 대한 자세한 내용은 이벤트 참조를 참고하세요.
이러한 분류법은 사용자가 구성해야 할 데이터와 태그에 지정해야 하는 데이터를 결정할 때 유용한 도구가 됩니다. 자동 수집 데이터는 이벤트에서 바로 읽을 수 있습니다. 그 외의 경우는 사용자가 구성해야 합니다.
이 점을 고려하여 Baz Analytics 태그의 매개변수를 다시 살펴보세요.
- 측정 ID,
id
: 자동 수집되지 않으므로 태그 구성 시 사용자가 입력해야 하는 값의 명확한 예시입니다. - 이벤트 이름,
en
: 위에서 언급했듯이 이벤트 이름은 항상event_name
매개변수에서 직접 가져올 수 있습니다. 그러나 이러한 값은 사용자 정의 값이므로, 필요한 경우 이름을 재정의할 수 있는 기능을 제공하는 것이 좋습니다. - 페이지,
l
: 이 값은 모든 이벤트에서 Google 애널리틱스 GA4 브라우저 태그가 자동 수집하는page_location
매개변수에서 가져올 수 있습니다. 따라서 직접 값을 입력하라고 사용자에게 요구해서는 안 됩니다. - 사용자 ID,
u
: Baz Analytics 서버 태그에서u
매개변수는 페이지의 태그로 사용자 지정되지도, 자동으로 수집되지도 않습니다. 그 대신 사용자가 웹사이트를 여러 번 방문했을 때 식별될 수 있도록 브라우저 쿠키에 저장됩니다. 아래 구현에서 볼 수 있듯이, 이는setCookie
API를 사용하여 쿠키를 설정하는 Baz Analytics 서버 태그입니다. 즉, Baz Analytics 태그만 키가 저장되는 위치와 방법을 알고 있습니다.l
과 마찬가지로u
매개변수는 자동으로 수집됩니다.
태그 구성을 완료하면 다음과 같이 표시됩니다.
태그 구현
태그 구성이 완료되었으므로, 이제 샌드박스 처리된 자바스크립트에서 동작을 구현하는 단계로 넘어갈 준비가 되었습니다.
태그는 다음 4가지 작업을 수행해야 합니다.
- 태그 구성에서 이벤트 이름을 가져옵니다.
- 이벤트의
page_location
속성에서 페이지 URL을 가져옵니다. - 사용자 ID를 계산합니다. 태그는
_bauid
라는 쿠키에서 사용자 ID를 찾습니다. 이 쿠키가 없으면 태그는 새 값을 계산하고, 추후 요청에 대비해 저장합니다. - URL을 구성하고 Baz Analytics 수집 서버에 요청합니다.
태그가 컨테이너에 전체적으로 어떻게 적용되는지 생각해 보는 것도 좋습니다. 컨테이너 구성요소는 각기 다른 역할을 수행하므로, 다음과 같이 태그가 수행하지 않거나 수행해서는 안 되는 역할도 있습니다
- 이벤트를 실행할지 여부를 판단하기 위해 이벤트를 검사하면 안 됩니다. 이는 트리거가 하는 역할입니다.
runContainer
API로 컨테이너를 실행해서는 안 됩니다. 이는 클라이언트의 역할입니다.- 중요한 예외인 쿠키를 제외하고는 요청 또는 응답과 직접 상호작용을 시도해서는 안 됩니다. 이 또한 클라이언트의 역할입니다.
이러한 작업을 수행하는 태그 템플릿을 작성하면 태그 사용자에게 혼동을 줄 수 있습니다. 예를 들어 들어오는 요청에 응답을 전송하는 태그는 클라이언트가 동일한 작업을 하지 못하도록 합니다. 그러면 컨테이너 작동 방식에 대한 사용자의 예상을 벗어나게 됩니다.
다음은 이 모든 사항을 염두에 두고 샌드박스 처리된 JS에서 태그를 주석 처리한 것입니다.
const encodeUriComponent = require('encodeUriComponent');
const generateRandom = require('generateRandom');
const getCookieValues = require('getCookieValues');
const getEventData = require('getEventData');
const logToConsole = require('logToConsole');
const makeString = require('makeString');
const sendHttpGet = require('sendHttpGet');
const setCookie = require('setCookie');
const USER_ID_COOKIE = '_bauid';
const MAX_USER_ID = 1000000000;
// The event name is taken from either the tag's configuration or from the
// event. Configuration data comes into the sandboxed code as a predefined
// variable called 'data'.
const eventName = data.eventName || getEventData('event_name');
// page_location is automatically collected by the Google Analytics 4 tag.
// Therefore, it's safe to take it directly from event data rather than require
// the user to specify it. Use the getEventData API to retrieve a single data
// point from the event. There's also a getAllEventData API that returns the
// entire event.
const pageLocation = getEventData('page_location');
const userId = getUserId();
const url = 'https://www.example.com/baz_analytics?' +
'id=' + encodeUriComponent(data.measurementId) +
'en=' + encodeUriComponent(eventName) +
(pageLocation ? 'l=' + encodeUriComponent(pageLocation) : '') +
'u=' + userId;
// The sendHttpGet API takes a URL and returns a promise that resolves with the
// result once the request completes. You must call data.gtmOnSuccess() or
// data.gtmOnFailure() so that the container knows when the tag has finished
// executing.
sendHttpGet(url).then((result) => {
if (result.statusCode >= 200 && result.statusCode < 300) {
data.gtmOnSuccess();
} else {
data.gtmOnFailure();
}
});
// The user ID is taken from a cookie, if present. If it's not present, a new ID
// is randomly generated and stored for later use.
//
// Generally speaking, tags should not interact directly with the request or
// response. This prevents different tags from conflicting with each other.
// Cookies, however, are an exception. Tags are the only container entities that
// know which cookies they need to read or write. Therefore, it's okay for tags
// to interact with them directly.
function getUserId() {
const userId = getCookieValues(USER_ID_COOKIE)[0] || generateRandom(0, MAX_USER_ID);
// The setCookie API adds a value to the 'cookie' header on the response.
setCookie(USER_ID_COOKIE, makeString(userId), {
'max-age': 3600 * 24 * 365 * 2,
domain: 'auto',
path: '/',
httpOnly: true,
secure: true,
});
return userId;
}
이렇게 태그가 구현되었습니다. 태그를 사용하려면 먼저 API 권한을 올바르게 설정해야 합니다. 템플릿 편집기의 권한 탭으로 이동하여 다음 권한을 지정합니다.
- 쿠키 값 읽기:
_bauid
- 이벤트 데이터 읽기:
event_name
및page_location
- HTTP 요청 보내기:
https://www.example.com/*
- 쿠키 설정:
_bauid
또한 태그 테스트를 작성해야 합니다. 템플릿 테스트에 관한 자세한 내용은 템플릿 개발자 가이드의 테스트 섹션을 참고하세요.
마지막으로 잊지 말고 코드 실행 버튼을 사용하여 태그를 한 번 이상 실행해 보세요. 이렇게 하면 많은 간단한 실수로 인해 서버에 문제가 발생하는 것을 방지할 수 있습니다.
커뮤니티 템플릿 갤러리에 태그 제출
새로운 태그의 생성, 테스트, 배포를 모두 완료했으므로 혼자만을 위해 간직하고 있을 이유가 없습니다. 새 태그가 다른 사용자에게 도움이 될 것 같은 경우 커뮤니티 템플릿 갤러리에 이를 제출해 보세요.
결론
이번 튜토리얼에서는 서버 컨테이너용 태그 작성의 기본사항을 알아봤습니다. 배운 내용은 다음과 같습니다.
- 이벤트 데이터를 읽고, HTTP 요청을 보내고, 브라우저에서 쿠키를 설정하는 데 사용하는 API
- 태그의 구성 옵션 설계 관련 권장사항
- 사용자 지정 데이터와 자동 수집 데이터 간의 차이점과 이 구분이 중요한 이유
- 컨테이너에서 태그의 역할(해야 할 역할과 해서는 안 되는 역할)
- 커뮤니티 템플릿 갤러리에 태그 템플릿을 제출하는 시기 및 방법