사실 Connected Content는 그 자체로 하나의 글로 작성해도 될 정도로 방대한 사용사례와 내용을 가지고 있고, Connected Content로 받아온 데이터를 실제 메시지에 뿌려줄 때 사용하는 Mark-up Language인 Liquid의 경우에도 그 자체로 하나의 글 주제가 될 수 있을 정도로 방대한 내용을 자랑합니다.

향후 Bridging Braze 시리즈를 통하여 Connected Content와 Liquid에 대해서는 별도 글을 통해서 다뤄보도록 하고, 이번 글을 통해서는 Connected Content와 Liquid를 사용해서 버려진 장바구니를 만드는 방법 자체에 대해서만 더 깊게 다뤄보도록 하겠습니다.

들어가기 앞서 (1) : Connected Content는 무엇이고 왜 필요한가?

[이커머스 서비스의 Custom Attribute 예시]

Braze에는 Custom User Attribute라고 하는 데이터 타입이 있습니다. Custom User Attribute는 사용자 1명에게 귀속되는 데이터입니다. 예를 들어 패션 리테일 서비스라고 한다면 여태 구매한 브랜드 리스트, 카드 등록했는지, 장바구니에 담긴 상품들의 ID, 멤버십 등급, 팔로우한 브랜드 리스트 등이 Custom User Attribute라고 볼 수 있습니다.

그러나 여기서 발생하는 문제는 항상 Braze 서버에 저장된 Custom User Attribute 값이 고객사 서버 내부에 있는 데이터와 100% 매칭하도록 하려면 많은 클라이언트 혹은 서버쪽 개발이 필요하다는 것입니다. 또한 Custom User Attribute는 한 번 바꿀 때마다 데이터 포인트를 소진시킵니다. 또한 여타 모든 SaaS가 그렇듯이 Custom User Attribute는 1차원 Array 값밖에 지원하지 않기 때문에, Nested Array와 같은 복잡한 데이터에 대해서는 저장이 불가합니다.

Connected Content는 메시지를 보내는 순간에 고객사가 세팅해놓은 API를 쳐서 그 API에서 Response를 받아와서 메시지의 개인화에 활용할 수 있도록 도와주는 기능입니다. API에서 데이터를 가져오기 때문에 이 경우에는 데이터 포인트를 소진시키지 않고, 억지로 Braze의 Custom User Attribute에 데이터를 넣거나 빼지 않아도, 광고주 서버와 DB에서 가장 최신의 데이터를 가져올 수 있다는 점에서 좋습니다.

이번에는 Connected Content 기능을 적극적으로 사용해보도록 하겠습니다.

혹시라도 Braze의 Connnected Content 기능이 더 궁금하신 분은 이 링크를 참고해주세요.

들어가기 앞서 (2) : 메시징 채널로서의 이메일의 중요성

모바일 앱 시장이 커지면서 모바일 푸시의 중요성이 이메일보다 단기적으로 많이 부각되었지만, 이메일은 여전히 매우 중요한 고객과의 소통 수단입니다.

이메일의 중요성은 아이러니하게도 모바일 앱 시장이 커지면서 더욱 커졌습니다. Return Path에 따르면 이미 전체 이메일의 55% 이상은 모바일 디바이스에서 열리고 있습니다. (놀랍게도 PC가 아닙니다! 😳)

뿐만 아니라 이메일은 이미지, 그리고 HTML5의 각종 기능(롤링 배너 등)을 사용하여 더욱 풍부한 시각적 효과를 제공합니다. 메시징 채널의 목적이 단순 홍보가 아니라 고객과 브랜드간의 장기적인 소통 관계를 만든다는 시각에서 이러한 시각적 효과는 브랜드에 대한 고객의 인지를 강화시키는 것에 매우 중요합니다.

그렇기에 이번에는 이메일을 메인 메시징 채널로 사용해보겠습니다.

STEP 1 : 테스트를 위한 Mock API 만들기

Connected Content를 사용할 때 가장 먼저 해야할 일은 Mock API (Mock API)를 만들고 그 API에 JSON 형태의 샘플 Response를 넣어서 이를 빠르게 테스트해보는 것입니다.

오늘 추천드릴 Mock API 제작 서비스는 바로 Mocky인데요. JSON 형태의 Response만 정의한다면 빠르게 가짜 API를 만들어볼 수 있습니다.

빠르게 Mock API를 만들어보기 위하여 JSON 형태의 샘플을 아래에 붙여넣습니다. 이 JSON을 복사 붙여넣기 해서 Body에 붙여넣습니다.


{
 "user_id":123,
 "products":[
    {
       "product_id":"37330037",
       "product_name":"아디다스 트레이닝복세트 여성 삼선 트랙탑+트랙팬츠",
       "product_image":"http://image.gsshop.com/image/37/33/37330037_L1.jpg",
       "product_url":"http://www.gsshop.com/prd/prd.gs?prdid=37330037&lsectid=1378829&rank=10&lseq=403259",
       "product_price":84000,
       "added_at":"2020-03-01T15:43:28+0000"
    },
    {
       "product_id":"56009414",
       "product_name":"20년 최신상 리복 남성 에어메쉬 트랙수트 2종",
       "product_image":"http://image.gsshop.com/image/56/00/56009414_L1.jpg",
       "product_url":"http://www.gsshop.com/prd/prd.gs?prdid=56009414&lsectid=1378829&rank=7&lseq=403259",
       "product_price":99000,
       "added_at":"2020-02-25T15:43:28+0000"
    }
 ]
}

그 이후에 ‘Generate my HTTP Response’ 버튼을 누르면 가짜 API가 완성됩니다.

지금부터는 각자가 만드신 API로 실습을 하셔도 좋고, 아니면 아래에 이미 만들어진 API를 사용하셔도 좋습니다.

-- CODE language-markup --http://www.mocky.io/v2/5e66296c3100002293239d0b

Tip : 진짜 API를 설계하는 법

Mocky는 Connected Content API를 기획하고 실제로 이메일에서 어떻게 데이터가 보이는지 확인할 때 유용하게 사용할 수 있습니다. 그러나 실제로는 내부의 개발자들에게 부탁하여 진짜 API를 만들어야 합니다.

이 때에는 API에서 User ID를 받아서 해당 User ID에 속하는 값들을 내려주도록 설계하는 것이 좋습니다. 예를 들어서 버려진 장바구니 캠페인 API의 경우에는 User ID를 파라미터로 받아서 해당 User ID의 장바구니에 실제로 들어있는 제품들의 정보를 내려주는 식으로 설계되어야 합니다.

Braze의 Liquid문에서는 Default Attributes의 하나로 User ID를 지원하고 있습니다. (e.g. {{${user_id}}}) 자세한 것은 Braze의 Personalization Tags와 관련된 문서를 참조해주세요. (관련 링크)

STEP 3 : 이메일의 Body를 이루는 HTML 소스코드에 Liquid문으로 데이터 동적으로 채워넣기

이제 Braze로 들어가서 이메일 캠페인을 위한 HTML 소스코드에 Liquid문으로 데이터를 동적으로 채워넣어볼까요?

여러분의 빠른 실습을 위하여 아래와 같이 원본과 완성본의 HTML 파일을 준비하였습니다.

위의 링크를 통해서 파일을 여신 후 우클릭을 하여 크롬 기준으로 ‘페이지 소스 보기’ 버튼을 눌러서 전체 소스를 볼 수 있습니다.

(Tip : 한편, 본 가이드에서는 HTML 소스를 수정할 때 Atom을 사용합니다. 혹은 Sublime이나 평소에 쓰시는 편한 Text Editor을 사용할 수도 있습니다.)

이제 하나하나 차근차근 짚어보겠습니다.


STEP 3.1. Connected Content용 API 호출하여 Response를 변수로 저장하기

가장 먼저 해야할 것은 Liquid 문을 사용하여 API를 호출하고 호출하였을 때 내려온 결과값을 특정한 Liquid의 변수에 저장하는 것입니다.

-- CODE language-liquid --{% connected_content http://www.mocky.io/v2/5e66296c3100002293239d0b :save result %}


위에 보이는 소스를 HTML 파일의 가장 위에 추가하도록 합시다.

위의 구조를 보면 우선 `connected_content` 옆에 API를 날릴 Endpoint URI를 집어넣습니다. 그리고 `:save`를 넣고 한 칸 띄워서 Response를 받을 변수의 이름을 지정합니다. 이 경우에는 `result`가 Response로 날아온 JSON이 저장될 변수명이 됩니다.

이제 `result`를 하나의 JavaScript의 Object 형태의 변수로 앞으로 나오는 모든 Liquid문 안에서 사용할 수 있습니다.

STEP 3.2. HTML 소스에서 반복되는 구간을 찾고 For 문으로 치환하기

이제 실제로 Connected Content를 통해서 받아온 데이터를 동적으로 HTML 소스코드 상에 반영해보겠습니다.

아시다시피 장바구니에 하나의 물건을 담진 않습니다. 그렇기 때문에 우리는 우선 반복되는 상품 박스 구간을 찾아야 합니다. 반복되는 상품 박스 구간을 찾기 위해서는 크롬의 ‘검사(Inspector)’ 기능을 활용하도록 하겠습니다.


위의 예시에서처럼 상품 박스 구간이 있을 것으로 예상되는 곳에서 검사를 시행해서, 마우스로 돌아다니면서 상품 2개가 반복되는 코드의 구간을 찾아냈습니다. 그 부분은 HTML 코드의 중간에 있는 <tr> Element이며, <tbody> 아래에 있는 3, 4번째 부분이 상품 박스에 속합니다.

CSS Selector로는 아래와 같습니다. CSS Selector : “body > div > table > tbody > tr > td > table:nth-child(4) > tbody > tr > td > table > tbody > tr:nth-child(3)”

실제로 개발자가 개발해준 코드라면 반복되는 구간에 사전에 합의된 id 혹은 class가 붙어있어서 더 금방 찾을 수 있는데, 이 예시의 경우에는 인터넷에서 다운로드받은 템플릿을 활용하였기에 조금 더 찾는 과정이 복잡하였습니다. (Tip : 개발자/퍼블리셔에게 반복되는 상품 박스의 경우 별도의 class로 표기해달라고 말하면 좋습니다.)

-- CODE language-liquid --{% for product_item in result.products %}          <tr style="border-collapse:collapse;">            …이제 이 안에서는 product_item을 사용할 수 있음…          </tr>{% endfor %}

이제 반복되는 코드 구간을 위와 같이 Liquid문으로 구성된 for 문 안에 넣습니다. 실제 HTML 코드에서는 반복되는 코드 구간이 2개가 있으므로 (상품이 2개가 나와 있으므로), 후자를 지워주고, 전자를 for 문 안에 넣어주면 됩니다.

위의 Liquid 문법을 설명하면 `result`는 앞서 설명했듯이 API의 JSON 형태의 Response를 저장한 변수이며, 이 변수의 속성으로 Array 형태의 `products`가 들어가있습니다. `products`의 Array에 담겨있는 하나하나의 아이템들을 `product_item`에 지정하는 것입니다.


STEP 3.3. `product_item`의 데이터를 실제 상품 박스안에 동적으로 채워넣기

이제 `result.products`가 for문을 돌면서 주는 `product_item`의 데이터를 실제 상품 박스안에 동적으로 채워넣어보겠습니다.

이미 위에서 개별 상품의 Taxonomy를 아래와 같이 설계하였는데요. HTML 소스코드 상의 정적인(static) 값들을 각각의 상품 속성을 나타내는 Liquid 문으로 대체해주면 됩니다.


{
           "product_id" : "37330037",
           "product_name" : "아디다스 트레이닝복세트 여성 삼선 트랙탑+트랙팬츠",
           "product_image" : "http://image.gsshop.com/image/37/33/37330037_L1.jpg",
           "product_url" : "http://www.gsshop.com/prd/prd.gs?prdid=37330037&lsectid=1378829&rank=10&lseq=403259",
           "product_price" : 84000,
           "added_at" : "2020-03-01T15:43:28+0000"
}

우리가 이 예시에서 대체해야 할 내용은 크게 3가지입니다.

  • 상품 이미지 링크
  • 상품 이름
  • 상품 가격

각각의 속성에 대해서 아래와 같이 대체하였습니다. (코드 내 빨간색 부분 참조) 이 작업은 코드 에디터에서 진행하였기에 스크린샷을 보여드릴 수 없는 점 양해부탁드립니다.

이미지 주소 : `img` element의 `src` attribute의 내용을 `{{ product_item.product_image }}`로 대체

상품 이름 : `h3` element의 내용을 `{{ product_item.product_name }}`로 대체

상품 가격 : `h3` element의 내용을 `{{ product_item.product_price | money_without_trailing_zeros }}`으로 대체

(참고 : Shopify에서는 Money Filters 기능을 통하여 돈과 같은 숫자를 더 쉽게 정제할 수 있도록 도와주고 있습니다. 위에서 사용한 `money_without_trailing_zeros`에 대해서 더 알아보고 싶다면 이 링크를 참조해주세요. 한국과 같이 천 단위로 , 를 붙이는 경우에는 number_with_delimiter를 사용할 수 있습니다.)

실제 정적 내용을 Liquid문으로 대체하는 것이 다 끝났습니다!

이제 실제로 이메일을 보내기 전 Braze 시스템은 Liquid 문법에 의하여 for 문을 돌면서 각각의 `product_item`마다 속한 이미지 주소, 상품 이름, 상품 가격을 대체해주게 됩니다.

STEP 4 : ‘며칠 전’에 담은 상품인지 시간 계산하여 넣어주기

위의 내용에서 한 가지 빠진 것이 있는데요. 상품 상세 정보에는 언제 상품이 장바구니에 담겼는지를 알려주는 데이터가 `added_at`으로 넣어져있는데요. 이 정보를 메일을 보내는 순간의 시간과 대조해서 ‘며칠 전'을 계산해보도록 하겠습니다.

이 며칠 전을 계산하려면 우선 주어진 시간 값을 Unix time (Epoch time)으로 변환시켜야 하는데요. 참고로 Unix time은 1970년 1월 1일 00:00:00 UTC 기준으로 얼마나 많은 ‘초’가 지났는지를 계산해서 현재의 시간을 표현하는 방법인데요. (관련 링크)

Braze에서는 시간을 표현할 때 ISO 8601을 따르고 있습니다. 따라서 위의 Mock API에서도 ISO 8601 기준으로 시간을 넣어줬었는데요. 내부 API를 제작할 시에도 ISO 8601을 따라주시면 되겠습니다.

-- CODE language-liquid -- {% for product_item in result.products %}    {% assign date_now_second = "now" | date: '%s' %}    {% assign date_cart_second = product_item.added_at | date: '%s' %}    {% assign time_diff_date = date_now_second | minus: date_cart_second | divided_by: 86400 %}    … 중간 내용 생략 … {% endfor %}

date_now_second라는 변수에 지금 시간을 'now'를 통해서 넣어주고, 이 값을 | date: '%s' 필터를 사용하여 Unix time으로 변환시킵니다. 같은 식으로 product_item.added_at을 변환시켜서 date_cart_second에 넣어줍니다. 그 후 | minus 필터를 사용하여 ‘초’의 차이를 구해주고, 이 차이를 60 * 60 * 24인 86400으로 나눠주게 되면 우리가 구하고자 하는 ‘며칠’이 나오게 됩니다.


이제 완성된 `time_diff_date` 변수를 HTML 코드 내에서 Liquid문을 통해서 사용할 수 있습니다.

STEP 5 : 이메일 제목 넣어주기

마지막으로 이메일에 제목이 빠질 수 없죠. Braze에서는 어떠한 input에서라도 Connected Content를 사용할 수 있습니다.

result 객체 안에 있는 products는 Array 형식을 띄고 있기 때문에 .size라는 Liquid의 문법을 사용하여서 “총 X개의 아이템들이 고객님을 기다리고 있어요! 😉”라는 문장의 X를 채워보도록 합시다. 간단합니다. 뒤에 .size를 붙여주기만 하면 됩니다. 자세한 문법은 이 링크를 참조해주세요.

현재 Mock API에는 2개의 상품 정보가 담겨있으므로 정상적으로 작동한다면 “2”라는 숫자가 나와야 합니다.

아래의 코드를 Sending Info > Subject 안에 넣고 우측 하단의 ‘Preview and Test’ 버튼을 누를 경우 이메일 제목이 우리가 의도한대로 “2”라는 숫자와 함께 나오는 것을 확인할 수 있습니다.

-- CODE language-liquid --
{% connected_content http://www.mocky.io/v2/5e66296c3100002293239d0b :save result %}총 {{ result.products.size }}개의 아이템이 고객님을 기다리고 있어요! 😉

완성된 Preview!

이제 만든 Braze 대시보드의 이메일 Preview 기능을 사용하여 위에서 수정한 HTML 코드가 실제로 어떻게 보이는지 확인해볼까요?


Body 부분에 최종본 HTML 코드를 넣고 우측 하단의 ‘Preview and Test’ 버튼을 눌러봅니다. 짜잔! 2개의 아이템이 상세정보와 함께 잘 나오는 것을 확인할 수 있습니다.

Tip : Content Block 활용하기

Braze에서는 자주 사용하는 HTML 및 TEXT 데이터를 하나의 블록으로 만들어서 저장하는 기능을 제공합니다. 위에서 만들어놓은 혹은 자주 사용하는 Connected Content를 하나의 블록으로 저장하고 쉽게 불러와서 사용할 수 있습니다. (관련 링크)

Coming Up Next : 최적화 및 예외처리하기

많은 시행착오 끝에 여기까지 온 분들, 정말 고생 많으셨습니다. 👏👏

그러나 아직 남아있는 할 일이 있습니다. 현실에서는 수 많은 예외 상황들이 존재하기 때문입니다.

다음 편에서는 아래의 2개의 추가 설정을 어떻게 Braze의 Liquid문으로 구현할 수 있는지를 다뤄보겠습니다.

  1. 최적화 : 장바구니에 담은지 14일이 넘어가는 아이템은 걸러내기 (왜냐하면 14일이 넘은 상품을 살 가능성은 희박하고, 괜히 사용자를 귀찮게 할 수 있으므로)
  2. 예외처리 : 만약 장바구니에 단 하나의 아이템도 담겨있지 않을 경우에는 메일 보내지 않기 (빈 이메일이 나가면 안되므로)

많은 기대해주세요! 😉

안녕하세요. 지난 편(링크)에서는 어떻게 Braze의 Canvas 기능을 사용하여 버려진 장바구니 캠페인을 만드는지 확인했었는데요. 이번 편에는 Braze의 Connected Content 기능을 사용하여 버려진 장바구니 담기 캠페인을 보다 더 세밀하게 만드는 법에 대해서 알아보도록 하겠습니다.

실시간 데이터 분석을 통한 마케팅 자동화로 사용자 재방문을 유도하세요.
정교한 타겟 설정을 통해 사용자 인게이지먼트를 높일 수 있습니다.
Braze 데모 신청하기
Published in
Share article