계열 서비스 어디에나 얹을 수 있는 플로팅 채팅 위젯입니다. 호스트 페이지는 스크립트를 넣고 로그인 상태만 알려주면 되고, 나머지는 위젯이 처리합니다.
1단계
</body> 앞에 넣습니다. 스텁이 먼저 정의되므로 로더 로드를 기다릴 필요가 없습니다.
<!-- 로더가 붙기 전 호출을 큐에 쌓아두는 스텁 --> <script> window.GaonTalk = window.GaonTalk || function () { (window.GaonTalk.q = window.GaonTalk.q || []).push(arguments); }; </script> <script async src="https://gaontalk.gaonprime.com/loader.js" data-app-id="내-app-id"></script>
2단계
위젯은 로그인 유저에게만 보입니다. identify 를 부르기 전에는 버튼조차 뜨지 않습니다.
// 로그인 직후 GaonTalk('identify', { getToken: () => fetch('/api/gaontalk-token', { credentials: 'same-origin' }) .then(r => r.json()).then(d => d.token), }); // 로그아웃 직후 GaonTalk('shutdown');
token 대신 getToken 을 권합니다.
로더가 필요한 순간에만 부르므로, 버튼만 보고 대화를 안 여는 유저에게는 토큰 요청이 아예 나가지 않습니다.
세션이 만료돼도 로더가 알아서 다시 부릅니다.
이 페이지에 실제 위젯이 붙어 있습니다. 아래 버튼이 위 코드와 똑같은 호출을 합니다.
로그인을 누르면 우측 하단에 버튼이 나타납니다.
| 호출 | 설명 |
|---|---|
| GaonTalk('identify', {…}) | getToken(권장) 또는 token. 이걸 부른 뒤에야 버튼이 나타납니다. |
| GaonTalk('shutdown') | 버튼·iframe·메모리 상태를 즉시 제거합니다. 로그아웃 시 호출하세요. |
| GaonTalk('open') | 패널을 엽니다. |
| GaonTalk('close') | 패널을 닫습니다. |
| GaonTalk('on', 이벤트, cb) | 아래 이벤트를 구독합니다. |
| 이벤트 | 언제 |
|---|---|
| ready | 위젯이 부팅을 마쳤습니다. |
| open / close | 패널이 열리거나 닫혔습니다. |
| identify-required | 세션이 만료됐습니다. getToken 을 넘겼다면 로더가 알아서 처리하므로 오지 않습니다. |
| dead | 토큰을 세 번 받지 못했습니다. 위젯이 연결 종료 화면으로 넘어갑니다. |
| error | 토큰 발급 실패 등. { code } 가 함께 옵니다. |
토큰은 호스트 백엔드가 만듭니다. app 별 secret 은 서버에만 두고 브라우저로 내려보내지 않습니다.
alg HS256
secret app 별 secret (서버 보관)
exp 5분
claims { sub: 유저ID, app_id: 내-app-id, jti: 매번 새 값 }
jti 는 필수이며 매번 새로 발급해야 합니다.
같은 토큰으로 두 번 세션을 만들 수 없습니다. 없으면 401 로 거부됩니다.
발급한 토큰을 HTML 에 그대로 찍지 마세요. 응답을 저장하는 캐시가 있으면
다른 사람이 남의 토큰을 받게 됩니다. 위 예시처럼 런타임에 받아오거나,
불가피하면 그 페이지에 Cache-Control: private, no-store 를 거세요.