개발 문서

문서를 참고하여 서비스에 AI 태깅/검색 기능을 연동하고 테스트해 보세요.

taggingBox 가이드

taggingBox SDK를 활용한 개발 방법을 알아보세요.

FAQ

자주 묻는 질문과 답변을 모았습니다.

목차

설치 방법
패키지 설치
npm install tbmini-sdk
사용 방법
JavaScript/TypeScript
import { TaggingSDK } from 'tbmini-sdk';

const sdk = new TaggingSDK();
sdk.init({
  applicationKey: 'your-application-key',
  userKey: 'user-unique-id',
  locale: 'ko' // or 'en'
});

sdk.createTaggingBox({
  containerId: 'tagging-container',
  width: '25rem',
  height: '600px',
  animation: 'fadeIn',
  animationDuration: '0.5s'
});
React
import React, { useEffect } from 'react';
import { TaggingSDK } from 'tbmini-sdk';

function App() {
  useEffect(() => {
    const sdk = new TaggingSDK();
    sdk.init({
      applicationKey: 'your-application-key',
      userKey: 'user-unique-id',
      locale: 'ko' // or 'en'
    });

    sdk.createTaggingBox({
      containerId: 'tagging-container',
      width: '25rem',
      height: '600px',
      animation: 'fadeIn',
      animationDuration: '0.5s'
    });
  }, []);

  return (
    <div className="container">
      <h1>tbmini-sdk React Example</h1>
      <div id="tagging-container"></div>
    </div>
  );
}

export default App;
Vue
<template>
  <div class="container">
    <div id="tagging-container"></div>
  </div>
</template>

<script>
import { TaggingSDK } from 'tbmini-sdk';

export default {
  name: 'App',
  mounted() {
    const sdk = new TaggingSDK();
    sdk.init({
      applicationKey: 'your-application-key',
      userKey: 'user-unique-id',
      locale: 'ko' // or 'en'
    });

    sdk.createTaggingBox({
      containerId: 'tagging-container',
      width: '25rem',
      height: '600px',
      animation: 'fadeIn'
    });
  }
}
</script>
CDN
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>tbmini-sdk Example</title>
    <script src="https://unpkg.com/tbmini-sdk@latest/dist/tbmini-sdk.min.js"></script>
</head>
<body>
    <div id="tagging-container"></div>

    <script>
        window.TaggingSDK.init({
            applicationKey: 'your-application-key',
            userKey: 'user-unique-id',
            locale: 'ko'
        });

        window.TaggingSDK.createTaggingBox({
            containerId: 'tagging-container',
            width: '25rem',
            height: '600px',
            animation: 'fadeIn',
            animationDuration: '0.5s'
        });
    </script>
</body>
</html>
SDK 옵션 설정
기본 설정
TaggingBox.init({
  containerId: 'tagging-container',  // required
  apiKey: 'your-api-key',           // required
  userKey: 'user-unique-id'         // required
});
크기 및 위치 설정
TaggingBox.init({
  containerId: 'tagging-container',
  apiKey: 'your-api-key',
  userKey: 'user-unique-id',
  width: '400px',                   // default: '400px'
  height: '600px'                   // default: '600px'
});
컨테이너 스타일 설정
// Set container style after SDK initialization
TaggingBox.init({
  containerId: 'tagging-container',
  apiKey: 'your-api-key',
  userKey: 'user-unique-id'
});

// Set container style
const container = document.getElementById('tagging-container');
container.style.position = 'fixed';
container.style.top = '5rem';
container.style.right = '2rem';
container.style.zIndex = '999';
container.style.height = '100vh';
container.style.width = '25rem';
애니메이션 설정
// animation options
TaggingBox.init({
  containerId: 'tagging-container',
  apiKey: 'your-api-key',
  userKey: 'user-unique-id',
  animation: 'slideInLeft',         
  animationDuration: '0.5s'        
});
플로팅 아이콘 설정
// Use the default icon
TaggingBox.init({
  containerId: 'tagging-container',
  apiKey: 'your-api-key',
  userKey: 'user-unique-id'
});

// Use custom SVG icon
TaggingBox.init({
  containerId: 'tagging-container',
  apiKey: 'your-api-key',
  userKey: 'user-unique-id',
  iconSvg: `<svg width="60" height="60" viewBox="0 0 24 24" fill="none">
    <circle cx="12" cy="12" r="10" fill="#007bff"/>
    <path d="M12 6v6l4 2" stroke="white" stroke-width="2"/>
  </svg>`,
  iconSize: '80px',
  iconPosition: { bottom: '30px', right: '30px' }
});

// Use image URL
TaggingBox.init({
  containerId: 'tagging-container',
  apiKey: 'your-api-key',
  userKey: 'user-unique-id',
  iconSvg: `<img src="https://example.com/icon.png" alt="Custom Icon" class="tagging-icon">`,
  iconSize: '70px'
});
표시 옵션 설정
// Show the floating icon first (default)
TaggingBox.init({
  containerId: 'tagging-container',
  apiKey: 'your-api-key',
  userKey: 'user-unique-id',
  showIconFirst: true              // default: true
});

// If you are showing TaggingBox right away
TaggingBox.init({
  containerId: 'tagging-container',
  apiKey: 'your-api-key',
  userKey: 'user-unique-id',
  showIconFirst: false             // Show the box without the icon first
});
인증 플로우

tbmini SDK는 두 가지 인증 방식을 지원합니다. (Secured On / Secured Off)

Secured On (보안 인증 활성화)
방법 1: doAuth 메서드 사용(권장)

고객사 백엔드에서 /api/v1/sdk_api/v1.1/client_auth/client_access_key API를 호출하여 access_key를 발급받고, 이를 doAuth 메서드로 전달합니다.

const sdk = new TaggingSDK();
sdk.init({
  applicationKey: 'your-application-key',
  userKey: 'user-unique-id',
  doAuth: async (userKey) => {
    // 고객사 백엔드에서 Application Secret을 사용하여 access_key 발급
    const response = await fetch('https://your-backend.com/api/get-access-key', {
      method: 'POST',
      body: JSON.stringify({ user_key: userKey })
    });
    const data = await response.json();
    return data.access_key; // access_key 반환
  }
});

고객사 백엔드에서는 다음과 같이 구현합니다

// 고객사 백엔드 예시
app.post('/api/get-access-key', async (req, res) => {
  const { user_key } = req.body;
  
  // Application Secret을 사용하여 tbmini API 호출
  const response = await fetch(
    `https://developers.tbmini.im/api/v1/sdk_api/v1.1/client_auth/client_access_key?user_key=${user_key}`,
    {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.APPLICATION_API_KEY,
        'X-API-Secret': process.env.APPLICATION_API_SECRET
      }
    }
  );
  
  const data = await response.json();
  res.json({ access_key: data.access_key });
});
방법 2: authURL 사용

고객사 백엔드에서 access_key를 발급하는 엔드포인트를 제공하고, SDK에서 해당 URL을 사용합니다.

const sdk = new TaggingSDK();
sdk.init({
  applicationKey: 'your-application-key',
  userKey: 'user-unique-id',
  authURL: 'https://your-backend.com/api/get-access-key' // 고객사 백엔드 엔드포인트
});

고객사 백엔드는 user_key를 query parameter로 받아 access_key를 반환해야 합니다

// 고객사 백엔드 예시
app.post('/api/get-access-key', async (req, res) => {
  const { user_key } = req.query;
  
  // Application Secret을 사용하여 tbmini API 호출
  const response = await fetch(
    `https://developers.tbmini.im/api/v1/sdk_api/v1.1/client_auth/client_access_key?user_key=${user_key}`,
    {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.APPLICATION_API_KEY,
        'X-API-Secret': process.env.APPLICATION_API_SECRET
      }
    }
  );
  
  const data = await response.json();
  res.json({ access_key: data.access_key });
});

발급받은 access_key로 SDK는 자동으로 /api/v1/sdk_api/v1.1/client_auth?access_key=(access_key) GET API를 호출하여 최종 토큰을 획득합니다.

Secured Off (보안 인증 비활성화)

콘솔에서 "Secured off"로 설정한 경우, SDK가 직접 /api/v1/sdk_api/v1.1/client_auth POST API를 호출하여 토큰을 획득합니다.
이 경우 x-api-key 헤더에 Application Key를, user_key에 사용자 식별자를 넣어 간단하게 토큰을 획득할 수 있습니다.

const sdk = new TaggingSDK();
sdk.init({
  applicationKey: 'your-application-key',
  userKey: 'user-unique-id'
  // doAuth나 authURL 설정 불필요
});

주의: Secured Off 방식은 사용자 계정 유출의 위험이 있으므로, 프로덕션 환경에서는 Secured On 방식을 사용하는 것을 강력히 권장합니다.

SDK 초기화 옵션
init method options
옵션타입필수기본값설명
applicationKeystringYes-콘솔에서 발급받은 Application Key (공개 키, Secret 아님)
userKeystringYes-사용자를 식별하는 고유 키
localestringNo'ko'언어 설정 ('ko' 또는 'en')
authURLstringNoapiBaseUrl + '/client_auth'엔드 유저 보안 인증용 백엔드 URL (고객사 서버). Secured On일 때 사용
doAuthfunctionNo-사용자 인증 커스텀 메서드. `async (user_key: string) => Promise(string)` 형식으로 access_key를 반환해야 합니다.

* 이 옵션 설정 시 authURL이 무시됩니다.

TaggingBox 생성 옵션

createTaggingBox method options
크기 설정
옵션기본값예시설명
width'400px'width: '400px'TaggingBox width
height'600px'height: '600px'TaggingBox height
애니메이션 설정
옵션기본값예시설명
animation'slideInRight'animation: 'slideInRight'렌더링 될 때 animation 타입
(slideInLeft, slideInTop, fadeIn, zoomIn, none)
animationDuration'0.3s'animationDuration: '0.3s'애니메이션 지속 시간 (밀리초 단위)
표시 옵션
옵션기본값예시설명
showIconFirsttrueshowIconFirst: true플로팅 아이콘 표시 여부
containerIdhttps://developers.tbmini.imapiBaseUrl: 'https://developers.tbmini.im'SDK가 렌더링될 컨테이너 요소의 ID
로고 설정
옵션기본값예시설명
logoSvg-logoSvg: '<svg>...'커스텀 로고 SVG
logoWidth'60px'logoWidth: '60px'로고 이미지의 가로 크기
logoHeight'20px'logoHeight: '20px'로고 이미지의 세로 크기
플로팅 아이콘 설정
옵션기본값예시설명
iconSvg-iconSvg: '<svg>...'플로팅 아이콘 SVG
iconSize'60px'iconSize: '60px'플로팅 아이콘 크기
iconPositionbottom: '20px', right: '20px'iconPosition: { bottom: '20px', right: '20px' }플로팅 아이콘 위치 (top, left, right, bottom)

API 함수 사용

SDK 초기화 후 getAPIs() 메서드를 통해 API 함수에 접근할 수 있습니다.

const sdk = new TaggingSDK();
sdk.init({
  applicationKey: 'your-application-key',
  userKey: 'user-unique-id'
});

const apis = sdk.getAPIs();

// API 함수 사용 예시
const boxes = await apis.getClientBoxes();

API 함수 목록

Client Context API

postClientContext()

사용자 컨텍스트 정보를 생성하고 박스 정보를 가져옵니다.

Input Parametersx
Output{ boxes: Array<{box_id, name}>, ... } → 사용자 박스 정보 및 컨텍스트 데이터
API EndpointPOST /client/context
Client Boxes API

getClientBoxes()

클라이언트의 박스 목록을 조회합니다.

Input Parametersx
Output{ boxes: Array<{box_id, name}>, plan_limits: {max_boxes_per_client, current_boxes_for_client} } → 박스 목록과 플랜 제한 정보
API EndpointGET /client/boxes

patchClientBoxes({box_id, name})

박스 이름을 업데이트합니다.

Input Parametersbox_id (number): 업데이트할 박스 ID name (string): 새로운 박스 이름
Output{ box_id, name, owner_public_client_id } → 업데이트된 박스 정보
API EndpointPATCH /client/boxes/{box_id}

putClientBoxesOrder(orderedList)

박스 순서를 변경합니다.

Input ParametersorderedList (Array): 변경된 순서의 박스 ID 리스트
Output없음 (성공 시 알림 표시)
API EndpointPUT /client/boxes/order
Recommendations API

postRecommendations(params)

콘텐츠를 저장하고 태그 추천을 요청합니다.

Input Parameterstitle : 콘텐츠 제목 url : 원본 URL content : 콘텐츠 내용 input_type : 입력 타입 (DIRECT, PASTE, FILE_UPLOAD, API, UNKNOWN) box_id(string) : 저장할 박스 ID recommend_tags : 태그 추천 여부
Output{ request_id : string, recommended_tags: Array<{name : string, source : string}>, ... } → 요청 ID와 추천 태그 목록
API EndpointPOST /recommendations
Tags API

postTags({request_id, box_id, tags})

추천받은 태그를 저장합니다.

Input Parametersrequest_id(string) : postRecommendations에서 받은 request_id box_id(string) : 저장할 박스 ID tags : 저장할 태그 목록
Output{ request_id, ... } → 요청 ID와 저장 결과
API EndpointPOST /tags
Chatbot API

getChatbotMasterBoxes()

챗봇용 마스터 목록을 조회합니다.

Input Parametersx
Output{ total_count, items: Array<{title, text_content, ...}>, skip, limit}
API EndpointGET /chatbot/masters?skip=0&limit=20

postChatbotSearch({query, master_box_id, room_id})

챗봇 검색을 수행합니다.

Input Parametersquery : 사용자의 검색 질문 master_box_id(string) : 검색할 Master의 특정 Box ID (선택 사항) room_id(number) :기존 대화방 ID (없으면 새 방 생성)
Output{ room_id, query: {id, user_query, context, ai_answer, master_box_id_used, sequence_number, created_at}, deducted_credits, message, context }
API EndpointPOST /chatbot/search

getChatbotBoxContents({master_box_id})

특정 마스터 박스의 콘텐츠 목록을 조회합니다.

Input Parametersmaster_box_id(string) : 조회할 마스터 박스 ID
Output{ total_count, items: Array<{title, text_content, master_box_id, is_chatbot_enabled, master_content_id, master_id, tags, created_at, updated_at, request_id}>, skip, limit }
API EndpointGET /chatbot/boxes/{master_box_id}/contents?skip=0&limit=100

getChatbotRooms()

챗봇 대화방 목록을 조회합니다.

Input Parametersx
OutputArray<{room_id, title, initial_master_box_id, created_at, updated_at, query_count}>
API EndpointGET /chatbot/rooms

getChatbotRoomsDetail(room_id)

특정 챗봇 대화방의 상세 정보(채팅 히스토리)를 조회합니다.

Input Parametersroom_id(number) :조회할 대화방 ID
Output{ room_id, title, requesting_client_public_id, content_owner_master_id, initial_master_box_id, created_at, updated_at, total_queries, queries: Array<{id, user_query, context, ai_answer, master_box_id_used, sequence_number, created_at}> }
API EndpointGET /chatbot/rooms/{room_id}

postRagSearch({query, box_id, room_id})

지정된 Client Box 내의 콘텐츠를 대상으로 RAG 검색을 수행하고, 결과를 Room에 기록합니다.

Input Parametersquery : RAG 검색 질문 box_id(string) : 검색 컨텍스트로 사용할 Client Box의 ID (선택 사항) room_id(number) :기존 검색 기록방 ID (없으면 새로 생성)
Output{ room_id: number, query: string, answer: string, box_id_used: string, sequence_number: number, created_at: string, deducted_credits: number, context: Array<string> } → RAG 검색 결과와 메타데이터
API EndpointPOST /rag/search

postRagSearchAllBoxes({query, room_id})

Client의 모든 접근 가능한 Box 내 콘텐츠를 대상으로 RAG 검색을 수행하고, 결과를 Room에 기록합니다.

Input Parametersquery : RAG 검색 질문 room_id(number) :기존 검색 기록방 ID (없으면 새로 생성)
Output{ room_id: number, query: string, answer: string, box_id_used: string, sequence_number: number, created_at: string, deducted_credits: number, context: Array<string> } → RAG 검색 결과와 메타데이터
API EndpointPOST /rag/search-all-boxes

getRagRooms({limit, skip})

Client의 모든 RAG 검색 기록방 목록을 조회합니다.

Input Parameterslimit : 조회 개수 (max 50, min 1), 기본값 20 skip : n개 이후 검색 (pagination), 기본값 0
OutputArray<{room_id: number, title: string, initial_box_id: string, created_at: string, updated_at: string, query_count: number}> → RAG 검색 기록방 목록
API EndpointGET /rag/rooms?limit={limit}&skip={skip}

getRagRoomsDetail({room_id, skip, limit})

특정 RAG 검색 기록방의 모든 질의응답을 조회합니다.

Input Parametersroom_id(number) :조회할 검색 기록방의 ID skip : 건너뛸 메시지 수, 기본값 0 limit : 가져올 메시지 수, 기본값 100
Output{ room_id: number, title: string, initial_box_id: string, created_at: string, updated_at: string, total_queries: number, queries: Array<{sequence_number: number, user_query: string, context: Array<string>, ai_answer: string, box_id_used: number, created_at: string}> } → RAG 검색 기록방 상세 정보
API EndpointGET /rag/rooms/{room_id}?skip={skip}&limit={limit}
Contents API

getClientContents({box_id, limit, offset})

콘텐츠 목록을 조회합니다 (Box 필터링 가능).

Input Parametersbox_id(string) : 필터링할 Box ID (선택 사항) limit : 페이지당 항목 수 (min 1, max 100), 기본값 20 offset : 건너뛸 항목 수, 기본값 0
Output{ total_count: number, limit: number, offset: number, items: Array<{request_id: string, box_id: string, owner_public_client_id: string, title: string, content: string, url: string, created_dt: string, updated_dt: string, associated_tags: Array<{tag_id: number, tag_nm: string, scope: string}>}> } → 콘텐츠 목록과 메타데이터
API EndpointGET /client/contents?box_id={box_id}&limit={limit}&offset={offset}

getContents(request_id)

콘텐츠 상세 정보를 조회합니다.

Input Parametersrequest_id (string): 조회할 콘텐츠의 request_id (짧은 Hex)
Output{ request_id: string, box_id: string, owner_public_client_id: string, title: string, content: string, url: string, created_dt: string, updated_dt: string, associated_tags: Array<{tag_id: number, tag_nm: string, scope: string}> } → 콘텐츠 상세 정보
API EndpointGET /contents/{request_id}

deleteContents(request_id)

주어진 request_id에 해당하는 콘텐츠를 삭제합니다.

Input Parametersrequest_id (string): 삭제할 콘텐츠의 request_id (짧은 Hex)
Output없음 (성공 시 204 응답)
API EndpointDELETE /contents/{request_id}

patchContents({request_id, title, content, url})

특정 콘텐츠의 제목, 내용, URL 등을 수정합니다.

Input Parametersrequest_id(string) : 수정할 콘텐츠의 request_id title : 변경할 콘텐츠 제목 (선택 사항) content : 변경할 콘텐츠 내용 (선택 사항) url : 변경할 원본 URL (선택 사항)
Output{ request_id: string, box_id: string, owner_public_client_id: string, title: string, content: string, url: string, created_dt: string, updated_dt: string, associated_tags: Array<{tag_id: number, tag_nm: string, scope: string}> } → 수정된 콘텐츠 정보
API EndpointPATCH /contents/{request_id}

patchContentsTags({request_id, tags_to_add, tags_to_remove})

특정 콘텐츠에 연결된 태그를 부분적으로 수정합니다.

Input Parametersrequest_id(string) : 태그를 수정할 콘텐츠의 request_id tags_to_add : 추가할 태그 목록 tags_to_remove : 제거할 태그 이름 목록
Output{ request_id: string, box_id: string, owner_public_client_id: string, title: string, content: string, url: string, created_dt: string, updated_dt: string, associated_tags: Array<{tag_id: number, tag_nm: string, scope: string}> } → 수정된 콘텐츠와 태그 정보
API EndpointPATCH /contents/{request_id}/tags
taggingBox - 초개인화된 태그를 활용해 정보를 분류하세요