무엇을 도와드릴까요?

문의 내용을 간단히 알려 주세요. 이메일로 답변드릴게요.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
홈으로

방문자 식별과 맥락 전달

ReactiveChat('identify')로 로그인 사용자를 알리고 서버의 HMAC-SHA256으로 userHash에 서명하며 시크릿을 교체하고 제품·장바구니 같은 구조화된 페이지 맥락을 전달하는 방법.

웹사이트가 방문자가 누구인지 안다면 채팅에도 알립니다. 그러면 팀은 상담원 화면에서 “방문자 4f2a” 대신 이름을 보며 고객 데이터와 고객 포털 같은 기능을 사용할 수 있습니다.

원칙: 브라우저의 정보는 증명이 되지 않습니다. 페이지가 identify로 주장하는 내용은 누구나 콘솔에서 위조할 수 있습니다. 브라우저에 전달되지 않는 시크릿으로 운영자의 서버가 계산한 서명이 있어야 확인된 사용자입니다.

브라우저 호출

ReactiveChat('identify', {
  userId:   '4711',
  email:    'kim@example.com',
  name:     'Kim Berger',
  userHash: '9c1f…',
  exp:      1792503600
});

다른 필드는 폐기합니다. identify는 위젯 로드 전에 호출해도 큐에 들어가며 조기 로드를 유발하지 않습니다. 연결 시 값을 함께 전달하고 이미 연결되어 있으면 즉시 전달합니다.

시크릿

계정의 프로젝트 → 본인 확인에서 프로젝트 시크릿을 생성합니다(프로젝트 수정 권한 필요). 64자리 16진수이며 전체 값은 정확히 한 번만 표시하고 이후에는 가립니다. 서버 환경에 넣고 브라우저 스크립트, 앱이나 저장소에 넣어서는 안 됩니다.

계산 시 중요 사항: HMAC 키는 디코딩한 바이트가 아닌 표시된 그대로의 64자 문자열 자체입니다.

서명 계산

userHash = hex( HMAC_SHA256( secret, userId + "." + exp ) )

소문자 16진수 64자입니다. 확인된 이메일 주소가 있는 경우:

userHash = hex( HMAC_SHA256( secret, userId + "." + exp + "." + email ) )

두 번째 형식에서만 이메일 주소가 확인된 것으로 간주되며 exp가 필요합니다.

PHP:

<?php
$geheim   = getenv('RC_IDENT_SECRET');      // 64 hex characters from the account
$userId   = (string) $kunde->id;
$exp      = time() + 3600;                  // at most 24 h
$userHash = hash_hmac('sha256', $userId . '.' . $exp, $geheim);
?>
<script nonce="<?= $cspNonce ?>">
  ReactiveChat('identify', {
    userId: <?= json_encode($userId) ?>,
    userHash: <?= json_encode($userHash) ?>,
    exp: <?= (int) $exp ?>
  });
</script>

Node.js:

const crypto = require('crypto');

function rcIdentitaet(kunde) {
  const userId = String(kunde.id);
  const exp = Math.floor(Date.now() / 1000) + 3600;
  const userHash = crypto.createHmac('sha256', process.env.RC_IDENT_SECRET)
    .update(userId + '.' + exp)
    .digest('hex');
  return { userId, userHash, exp };
}

Python:

import hmac, hashlib, os, time

def rc_identitaet(kunde_id: str) -> dict:
    exp = int(time.time()) + 3600
    msg = f"{kunde_id}.{exp}".encode()
    key = os.environ["RC_IDENT_SECRET"].encode()   # the hex string as text
    return {"userId": kunde_id, "exp": exp,
            "userHash": hmac.new(key, msg, hashlib.sha256).hexdigest()}

이메일 주소 포함(PHP):

$userHash = hash_hmac('sha256', $userId . '.' . $exp . '.' . $email, $geheim);

주소는 identify에 전달하는 그대로 서명해야 합니다.

인라인 스크립트 없이 사용(엄격한 CSP)

Content Security Policy가 인라인 스크립트를 허용하지 않으면 값을 데이터로 출력하고 자체 스크립트 파일에서 identify를 호출합니다.

<meta name="rc-ident" content='{"userId":"4711","userHash":"9c1f…","exp":1792503600}'>
// /js/chat-ident.js
var m = document.querySelector('meta[name="rc-ident"]');
if (m) { ReactiveChat('identify', JSON.parse(m.content)); }

단일 페이지 앱에서는 로그인 후 fetch로 서버에서 세 값을 가져옵니다.

서버의 검사 항목

유효한 해시와 exp가 모두 있는 사용자는 확인되고 만료되지 않은 사용자입니다. 이때만 고객 데이터와 고객 포털을 사용할 수 있습니다.

exp 없는 이전 형식: userHash = HMAC_SHA256(secret, userId)도 확인된 것으로 받지만 만료되지 않은 신원으로는 간주하지 않습니다. 대화 기록과 상담원 화면 표시에는 충분하지만 고객 데이터에는 부족합니다. 기존 연동을 exp 포함 형식으로 전환합니다.

검증 실패 시

채팅은 계속되지만 익명으로 작동합니다. 위젯은 auth_failed 오류와 detail.reason의 이유를 받습니다.

개발자 도구의 네트워크 탭에서 WebSocket 연결의 error 프레임에 이유가 있습니다. init_ok.identity에 verified와 reason이 표시됩니다.

“확인된 방문자만 허용” 설정은 없습니다. 확인되지 않은 방문자는 항상 익명으로 채팅합니다.

시크릿 교체

사용자 전환과 로그아웃

맥락 전달

신원 외에도 페이지에서 현재 표시된 제품이나 장바구니 내용처럼 지금 일어나는 일을 어시스턴트와 팀에 알릴 수 있습니다. track을 사용합니다.

ReactiveChat('track', 'warenkorb', {
  page_type: 'cart',
  cart_value: 129.80,
  cart_items: 3,
  currency: 'EUR'
});

다음 필드만 수집하고 나머지는 폐기합니다.

위젯은 주소, 제목, 유입 페이지와 캠페인 매개변수를 페이지가 변경될 때마다 자동 기록합니다. 맥락은 동의가 있을 때만 전송합니다(개인정보 보호 연동). 이 필드에 개인정보를 넣지 않습니다. 개인정보에는 identify를 사용합니다.

모바일 앱

앱에서는 WebView 로드 후 JavaScript로 신원을 전달하며 주소로 전달하지 않습니다. 여기서도 해시는 앱이 아닌 서버에서 계산합니다. 모바일 앱을 참조합니다.

다음: 고객 데이터 엔드포인트 · SPA와 페이지 변경

최종 업데이트: