중첩 커스텀 속성
이 페이지에서는 중첩 커스텀 속성에 대해 설명하며, 이를 통해 속성 집합을 다른 속성의 속성정보로 정의할 수 있습니다. 즉, 커스텀 속성 오브젝트를 정의할 때 해당 오브젝트에 대한 추가 속성 집합을 정의할 수 있습니다.
중첩 속성 소개
중첩 속성을 사용하면 단일 커스텀 속성 오브젝트의 데이터를 활용하여 더 풍부한 Segment를 구축하고 메시지를 개인화할 수 있습니다.
다음 예시에서 커스텀 속성 favorite_book에는 중첩 속성 title, author, publishing_date가 포함되어 있습니다. 이 오브젝트를 사용하여 저자별로 사용자를 타겟팅하거나, 출판일로 필터링하거나, 책 제목을 메시지에 직접 삽입할 수 있습니다:
1
2
3
4
5
"favorite_book": {
"title": "The Hobbit",
"author": "J.R.R. Tolkien",
"publishing_date": "1937"
}
지원되는 데이터 유형
다음 데이터 유형이 지원됩니다:
| 데이터 유형 | 설명 |
|---|---|
| 숫자 | 숫자 값으로, 예를 들어 1 또는 5.5입니다. |
| 문자열 | 텍스트 값으로, 예를 들어 "Hello" 또는 "The Hobbit"입니다. |
| 부울 | true 또는 false로 평가되는 값입니다. |
| 배열 | 값의 목록으로, 예를 들어 ["red", "blue", "green"]입니다. |
| 시간 |
날짜 및 시간 비교에 사용되는 타임스탬프 값입니다. 중첩된 시간 커스텀 속성을 필터링할 때 다음 중 선택할 수 있습니다:
|
| 오브젝트 | 키-값 쌍으로 구성된 구조화된 값으로, 예를 들어 {"author": "Tolkien"}입니다. |
| 오브젝트 배열 |
오브젝트의 목록으로, 예를 들어 [{"title": "The Hobbit"}, {"title": "Dune"}]입니다.
자세한 내용은
오브젝트 배열 을 참조하세요.
|
고려 사항
- 중첩 커스텀 속성은 Braze SDK 또는 API를 통해 전송되는 커스텀 속성을 위한 것입니다.
- 오브젝트의 최대 크기는 100 KB입니다. 업데이트로 인해 오브젝트가 100 KB를 초과하면 Braze는 해당 업데이트를 삭제하고 속성은 변경되지 않습니다.
- 키 이름과 문자열 값의 크기 제한은 255자입니다.
- 키 이름에는 공백을 포함할 수 없습니다.
- 마침표(
.)와 달러 기호($)는 고객 프로필에 중첩 커스텀 속성을 전송하려는 경우 API 페이로드에서 지원되지 않는 문자입니다. - 모든 Braze 파트너가 중첩 커스텀 속성을 지원하는 것은 아닙니다. 특정 파트너 통합이 이 기능을 지원하는지 확인하려면 파트너 설명서를 참조하세요.
- 중첩 커스텀 속성은 Connected Audience API 호출 시 필터로 사용할 수 없습니다.
- 기본적으로 중첩 커스텀 속성 Segment 필터에는 오브젝트 유형 커스텀 속성, 오브젝트 배열 속성, 배열 유형 커스텀 속성이 포함됩니다. 속성을 선택하면 속성정보 스키마 선택기에 중첩 배열 필드에 대한 배열 경로(
[]표기법 사용)가 포함됩니다. 해당 필터에서 최상위 배열 커스텀 속성을 숨기려면 Braze 지원팀에 문의하세요. - 대시보드에서 커스텀 사용자로 미리보기를 사용하여 메시지를 미리 볼 때, 모의 데이터는 문자열 또는 문자열 배열로만 입력할 수 있으며 중첩 오브젝트는 지원되지 않습니다. 중첩 커스텀 속성을 참조하는 메시지를 미리 보려면 프로필에 해당 중첩 속성이 이미 있는 기존 사용자를 선택하세요. 중첩 커스텀 이벤트 속성정보의 경우, 렌더링을 확인하려면 테스트 사용자를 대상으로 하는 실시간 Campaign을 실행해야 합니다.
API 예시
다음은 “Most Played Song” 오브젝트를 사용한 /users/track 예시입니다. 노래의 속성정보를 캡처하기 위해 most_played_song을 오브젝트로 나열하고 오브젝트 속성정보 세트를 함께 포함하는 API 요청을 보냅니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"attributes": [
{
"external_id": "user_id",
"most_played_song": {
"song_name": "Solea",
"artist_name": "Miles Davis",
"album_name": "Sketches of Spain",
"genre": "Jazz",
"play_analytics": {
"count": 1000,
"top_10_listeners": true
}
}
}
]
}
기존 오브젝트를 업데이트하려면 요청에 _merge_objects 파라미터를 포함하여 users/track으로 POST를 보냅니다. 이렇게 하면 업데이트 내용이 기존 오브젝트 데이터와 딥 병합됩니다. 딥 병합은 첫 번째 레벨만 병합하는 것이 아니라 오브젝트의 모든 레벨이 다른 오브젝트에 병합되도록 합니다. 이 예시에서는 Braze에 이미 most_played_song 오브젝트가 있으며, 이제 most_played_song 오브젝트에 새 필드 year_released를 추가합니다.
1
2
3
4
5
6
7
8
9
10
11
{
"attributes": [
{
"external_id": "user_id",
"_merge_objects": true,
"most_played_song": {
"year_released": 1960
}
}
]
}
이 요청이 수신되면 커스텀 속성 오브젝트는 다음과 같이 표시됩니다:
1
2
3
4
5
6
7
8
9
10
11
{"most_played_song": {
"song_name": "Solea",
"artist_name" : "Miles Davis",
"album_name": "Sketches of Spain",
"year_released": 1960,
"genre": "Jazz",
"play_analytics": {
"count": 1000,
"top_10_listeners": true
}
}}

_merge_objects를 true로 설정해야 합니다. 그렇지 않으면 오브젝트가 덮어쓰기됩니다. _merge_objects는 기본적으로 false입니다.
커스텀 속성 오브젝트를 삭제하려면 커스텀 속성 오브젝트를 null로 설정하여 users/track으로 POST를 보냅니다.
1
2
3
4
5
6
7
8
{
"attributes": [
{
"external_id": "user_id",
"most_played_song": null
}
]
}

SDK 예제
다음 샘플은 각 SDK에서 동일한 중첩 커스텀 속성 오브젝트(most_played_song)를 생성, 병합 업데이트 및 삭제하는 방법을 보여줍니다.
생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
val json = JSONObject()
.put("song_name", "Solea")
.put("artist_name", "Miles Davis")
.put("album_name", "Sketches of Spain")
.put("genre", "Jazz")
.put(
"play_analytics",
JSONObject()
.put("count", 1000)
.put("top_10_listeners", true)
)
braze.getCurrentUser { user ->
user.setCustomUserAttribute("most_played_song", json)
}
업데이트
1
2
3
4
5
6
val json = JSONObject()
.put("year_released", 1960)
braze.getCurrentUser { user ->
user.setCustomUserAttribute("most_played_song", json, true)
}
삭제
1
2
3
braze.getCurrentUser { user ->
user.unsetCustomUserAttribute("most_played_song")
}
생성
1
2
3
4
5
6
7
8
9
10
11
12
let json: [String: Any?] = [
"song_name": "Solea",
"artist_name": "Miles Davis",
"album_name": "Sketches of Spain",
"genre": "Jazz",
"play_analytics": [
"count": 1000,
"top_10_listeners": true,
],
]
braze.user.setCustomAttribute(key: "most_played_song", dictionary: json)
업데이트
1
2
3
4
5
let json: [String: Any?] = [
"year_released": 1960
]
braze.user.setCustomAttribute(key: "most_played_song", dictionary: json, merge: true)
삭제
1
braze.user.unsetCustomAttribute(key: "most_played_song")
생성
1
2
3
4
5
6
7
8
9
10
11
12
import * as braze from "@braze/web-sdk";
const json = {
"song_name": "Solea",
"artist_name": "Miles Davis",
"album_name": "Sketches of Spain",
"genre": "Jazz",
"play_analytics": {
"count": 1000,
"top_10_listeners": true
}
};
braze.getUser().setCustomUserAttribute("most_played_song", json);
업데이트
1
2
3
4
5
6
import * as braze from "@braze/web-sdk";
const json = {
"year_released": 1960
};
braze.getUser().setCustomUserAttribute("most_played_song", json, true);
삭제
1
2
import * as braze from "@braze/web-sdk";
braze.getUser().setCustomUserAttribute("most_played_song", null);
생성
1
2
3
4
5
6
7
8
9
10
11
12
Dictionary<string, object> attributes = new Dictionary<string, object>();
attributes.Add("song_name", "Solea");
attributes.Add("artist_name", "Miles Davis");
attributes.Add("album_name", "Sketches of Spain");
attributes.Add("genre", "Jazz");
Dictionary<string, object> playAnalytics = new Dictionary<string, object>();
playAnalytics.Add("count", 1000);
playAnalytics.Add("top_10_listeners", true);
attributes.Add("play_analytics", playAnalytics);
AppboyBinding.SetCustomUserAttribute("most_played_song", attributes);
업데이트
1
2
3
4
Dictionary<string, object> attributes = new Dictionary<string, object>();
attributes.Add("year_released", 1960);
AppboyBinding.SetCustomUserAttribute("most_played_song", attributes, true);
삭제
1
AppboyBinding.UnsetCustomUserAttribute("most_played_song");
오브젝트 속성정보로 날짜 캡처하기
오브젝트 속성정보로 날짜를 캡처하려면 $time 키를 사용해야 합니다. 다음 예시에서는 “Important Dates” 오브젝트를 사용하여 birthday와 wedding_anniversary라는 오브젝트 속성정보 세트를 캡처합니다. 이러한 날짜의 값은 $time 키를 포함하는 오브젝트이며, null 값이 될 수 없습니다.

처음에 오브젝트 속성정보로 날짜를 캡처하지 않은 경우, 모든 사용자에 대해 $time 키를 사용하여 이 데이터를 다시 전송하는 것을 권장합니다. 그렇지 않으면 $time 속성을 사용할 때 불완전한 Segments가 생성될 수 있습니다. 단, 중첩 커스텀 속성의 $time 값이 올바른 형식이 아닌 경우 해당 중첩 커스텀 속성 전체가 업데이트되지 않습니다.
1
2
3
4
5
6
7
8
9
10
11
{
"attributes": [
{
"external_id": "time_with_nca_test",
"important_dates": {
"birthday": {"$time" : "1980-01-01"},
"wedding_anniversary": {"$time" : "2020-05-28"}
}
}
]
}

중첩 커스텀 속성의 경우, 연도가 0 미만이거나 3000을 초과하면 Braze는 해당 값을 사용자에게 저장하지 않습니다.
Liquid 템플릿
다음 Liquid 템플릿 예시는 앞선 API 요청에서 저장된 커스텀 속성 오브젝트 속성정보를 참조하고 이를 메시징에 사용하는 방법을 보여줍니다.
custom_attribute 개인화 태그와 점 표기법을 사용하여 오브젝트의 속성정보에 접근합니다. 오브젝트 이름(오브젝트 배열을 참조하는 경우 배열 내 위치 포함)을 지정한 다음, 점(마침표)과 속성정보 이름을 차례로 입력합니다.
{{custom_attribute.${most_played_song}[0].artist_name}} — “Miles Davis”
{{custom_attribute.${most_played_song}[0].song_name}} — “Solea”
{{custom_attribute.${most_played_song}[0].play_analytics.count}} — “1000”
메시지에서 중첩 커스텀 속성 Liquid를 사용하려면:
- Campaign 또는 Canvas로 이동한 다음, 개인화를 추가할 메시지 단계를 엽니다.
- 메시지 작성기에서 값을 표시할 위치에 Liquid 스니펫을 삽입합니다.
- 미리보기 및 테스트를 사용하여 프로필에 중첩 커스텀 속성이 이미 있는 기존 사용자로 값이 예상대로 렌더링되는지 확인합니다.
개인화
개인화 추가를 사용하여 중첩 커스텀 속성을 메시지에 삽입할 수 있습니다.
개인화 추가를 열려면:
- Campaign 또는 Canvas로 이동한 다음, 개인화를 추가할 메시지 단계를 엽니다.
- 메시지 작성기에서 개인화를 선택하여 개인화 추가 사이드바를 열고, 개인화 옵션을 선택합니다.
중첩 커스텀 속성 개인화를 구성하려면:
- 개인화 유형에서 중첩 커스텀 속성을 선택합니다.
- 최상위 속성에서 삽입할 중첩 커스텀 속성 경로를 선택합니다.
예를 들어,
preferences.neighborhood_office를 선택합니다. - 선택 사항: 기본값에 해당 속성에 대한 자체 값이 없는 사용자를 위한 대체 값을 입력합니다.
- 생성된 Liquid 스니펫을 검토하여 예상 경로와 일치하는지 확인합니다.
- 삽입을 선택합니다.
이 예시에서 Braze는 preferences.neighborhood_office의 중첩 값을 메시지에 삽입합니다. 기본값은 속성에 대한 자체 값이 없는 사용자를 위해 메시지에 포함되는 대체 값입니다.

중첩 커스텀 속성을 삽입하는 옵션이 보이지 않는 경우 스키마가 생성되었는지 확인하세요.
스키마 생성 및 재생성
세분화 및 개인화에서 중첩 커스텀 속성을 사용하려면 해당 속성에 대한 스키마를 생성해야 합니다. 스키마가 생성된 후에는 필요에 따라 재생성할 수 있습니다. 스키마에 대한 자세한 내용은 중첩 오브젝트 탐색기를 사용하여 스키마 생성을 참조하세요.
스키마 생성
중첩 커스텀 속성을 생성하고 Braze에 데이터를 전송한 후 스키마를 생성할 수 있습니다:
- Data Settings > Custom Attributes로 이동합니다.
- 중첩 커스텀 속성을 검색합니다.
- 속성의 Attribute Name 열에서 Generate Schema를 선택합니다.
스키마가 생성되면 아이콘이 플러스 아이콘으로 변경되며, 이를 선택하여 스키마를 확인하고 관리할 수 있습니다.
스키마 재생성
중첩 커스텀 속성의 스키마를 재생성하려면:
- Data Settings > Custom Attributes로 이동합니다.
- 중첩 커스텀 속성을 검색합니다.
- 속성의 Attribute Name 열에서 Manage schema를 선택하여 스키마를 관리합니다.
- Modal이 나타납니다. Regenerate Schema를 선택합니다.
스키마 작업이 이미 진행 중인 경우(상태가 Generating인 동안에는 옵션을 사용할 수 없음) 다른 재생성을 시작할 수 없습니다. 회사당 한 번에 하나의 스키마 생성 작업만 실행할 수 있습니다. 스키마 재생성은 새 오브젝트만 감지하며 현재 스키마에 존재하는 오브젝트를 삭제하지 않습니다.

기존 오브젝트가 있는 오브젝트 배열의 스키마를 초기화하려면 새 커스텀 속성을 생성해야 합니다. 스키마 재생성은 기존 오브젝트를 삭제하지 않습니다.
스키마를 재생성한 후 데이터가 예상대로 표시되지 않으면 해당 속성이 충분히 자주 수집되지 않을 수 있습니다. 사용자 데이터는 해당 중첩 속성에 대해 Braze에 이전에 전송된 데이터를 기반으로 샘플링됩니다. 속성이 충분히 수집되지 않으면 스키마에 반영되지 않습니다.
중첩 커스텀 속성 변경 트리거
중첩 커스텀 속성 오브젝트가 변경될 때 트리거할 수 있습니다. 이 옵션은 오브젝트 배열의 변경에는 사용할 수 없습니다. 경로 탐색기를 볼 수 있는 옵션이 보이지 않는 경우, 스키마가 생성되었는지 확인하세요.
예를 들어, 실행 기반 Campaign에서 커스텀 속성 값 변경에 대한 새 트리거 동작을 추가하여 근처 사무실 선호도를 변경한 사용자를 타겟팅할 수 있습니다.
실행 기반 Campaign에서 이 트리거를 구성하려면:
- Campaign을 생성하거나 편집한 다음, 전달 유형을 실행 기반 전달로 설정합니다.
- 트리거 설정에서 커스텀 속성 값 변경을 선택합니다.
- 모니터링할 중첩 커스텀 속성 경로를 선택합니다.
예를 들어,
preferences.neighborhood_office를 선택합니다. - 임의의 새 값 등 원하는 트리거 조건을 선택합니다.
- Campaign 메시지와 오디언스 구성을 완료한 다음 Campaign을 시작합니다.
문제 해결
중첩 커스텀 속성 값이 일관되게 적용되지 않는 경우
중첩 커스텀 속성 값이 고객 프로필에 일관되게 추가되지 않는 경우, 대부분 데이터 유형 불일치와 관련된 문제입니다.
이 문제를 진단하고 해결하려면 다음을 수행하세요:
- 사용자 예시 비교: 중첩 커스텀 속성이 설정되어야 하는 사용자 중 성공한 사례와 실패한 사례를 각각 하나씩 확인합니다.
- 데이터 구조 검토: 두 프로필의 커스텀 속성 값을 확인하고 비교합니다:
- 속성정보가 오브젝트 아래에 저장되어 있나요?
- 속성정보가 속성정보 배열로 저장되어 있나요?
- 세분화 필터 확인: 저장된 데이터 구조를 세분화 필터에서 중첩 커스텀 속성이 참조되는 방식과 비교합니다.
- 데이터 유형 확인: 커스텀 속성의 데이터 유형을 확인하려면 다음을 수행합니다:
- 데이터 설정 > 커스텀 속성으로 이동합니다.
- 확인하려는 중첩 속성이 포함된 최상위 커스텀 속성을 검색합니다.
- 해당 행에 스키마 생성이 표시되면 선택하여 먼저 스키마를 생성합니다.
- 스키마가 생성된 후, 해당 속성의 속성 이름 열에서 플러스 아이콘을 선택합니다.
- 스키마 편집 Modal에서 중첩 속성과 데이터 유형 열의 해당 값을 검토합니다.
데이터 유형이 고객 프로필 전체에서 의도한 형식과 일치하지 않는 경우, 영향을 받는 고객 프로필에서 잘못된 형식의 값을 제거하고 적절한 API 요청 또는 SDK 메서드를 사용하여 올바른 형식으로 속성을 다시 전송하세요.
오브젝트 배열에서의 세분화 동작
여러 개의 중첩 커스텀 속성 필터를 AND 로직으로 사용하여 오브젝트 배열을 기준으로 세분화할 때, 각 필터는 배열의 모든 항목에 대해 독립적으로 평가됩니다. 배열 내 어떤 항목이든 각 개별 필터를 충족하면 해당 사용자는 Segment에 포함됩니다. 필터가 동일한 항목과 일치할 필요는 없습니다.
예를 들어, 사용자가 다음과 같은 배열을 가지고 있다고 가정합니다:
1
2
3
4
5
6
{
"orders": [
{"product": "Shoes", "price": 80},
{"product": "Hat", "price": 25}
]
}
다음과 같은 AND 필터가 적용된 Segment가 있습니다:
orders[].price가 50보다 큼orders[].price가 30보다 작음
이 사용자는 첫 번째 필터가 “Shoes” 항목(80 > 50)과 일치하고, 두 번째 필터가 “Hat” 항목(25 < 30)과 일치하기 때문에 조건을 충족합니다. 단일 항목이 두 조건을 모두 만족하지 않더라도 사용자는 여전히 Segment에 포함됩니다.
배열 내 동일한 항목에서 모든 조건이 일치해야 하는 경우, 동일한 경로에서 다중 기준 세분화를 사용하거나, 항목 간 교차 매칭을 방지하도록 데이터를 재구성하세요.
데이터 포인트
전송되는 모든 키는 데이터 포인트를 소비합니다. 예를 들어, 고객 프로필에서 초기화된 이 오브젝트는 7개의 데이터 포인트로 계산됩니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"attributes": [
{
"external_id": "user_id",
"most_played_song": {
"song_name": "Solea",
"artist_name": "Miles Davis",
"album_name": "Sketches of Spain",
"year_released": 1960,
"genre": "Jazz",
"play_analytics": {
"count": 1000,
"top_10_listeners": true
}
}
}
]
}

커스텀 속성 오브젝트를 null로 업데이트하는 것도 데이터 포인트를 소비합니다.