이미지 · 파일 업로드 예제 > BlueTalk::블루톡 무료 실시간 채팅 위젯 · 1:1 DM · 웹 채팅 연동

이미지/파일 업로드 예제
1. 개요

BlueTalk에서 채팅에 이미지를 붙이거나 파일을 첨부할 때 내부적으로는 다음과 같은 순서로 처리됩니다.

  1. 브라우저에서 파일 선택
  2. POST /upload/chat-file 로 파일 업로드 (multipart/form-data)
  3. 서버가 DB/저장소에 파일을 보관하고 file.id 등 메타데이터를 응답
  4. 채팅 메시지에 attachment_ids 형태로 파일 id를 함께 전송
  5. 다른 클라이언트에서는 /chat-file/:id 경로를 통해 이미지/파일을 조회

보통은 bluetalk.js 내부가 이 과정을 자동으로 처리하지만,
이 문서는 “직접 REST 호출을 사용해서 파일을 올리고, 그 결과를 채팅에 붙이고 싶을 때” 참고할 수 있는 예제로 생각하시면 됩니다.

2. /upload/chat-file 요청 포맷

현재 서버 구현 기준으로, 업로드 API는 다음과 같은 엔드포인트와 필드를 사용합니다.

필드 타입 설명
file binary 업로드할 실제 파일 (이미지, 문서 등) – 필수
site_key string 블루톡 사이트 키 (window.SITE_KEY와 동일)
channel_key string 채널 식별값 (예: global, board_free, room_123)
글로벌 채팅에서만 쓸 경우 global로 통일해도 무방합니다.
user_id string 사용자 아이디 또는 PK (예: 그누보드 $member['mb_id'])
user_key string 서버에서 생성한 서명/토큰 값 (window.GLOBAL_USER_KEY와 동일)
POST /upload/chat-file
Content-Type: multipart/form-data

- file        : (binary)
- site_key    : 발급받은_site_key
- channel_key : global
- user_id     : testuser
- user_key    : 서버에서_생성한_user_key
3. 순수 HTML/JS 업로드 예제

아래 예제는 순수 HTML + 자바스크립트만으로 파일을 업로드하고 응답을 확인해 보는 코드입니다.
(실사용 시에는 PHP/Node 등 서버에서 user_id/user_key를 내려주고 사용해야 합니다.)

<!-- 예제 HTML -->
<div class="upload-box">
  <h3>이미지/파일 업로드 후 로그 확인</h3>
  <input type="file" id="file-input">
  <button type="button" id="btn-upload">업로드</button>
  <div class="upload-log" id="upload-log">업로드 로그가 여기에 표시됩니다.</div>
</div>

<script>
  const API_BASE  = "https://server.bluetalk.kr";   // 실제 서버 주소에 맞게 수정
  const SITE_KEY  = "발급받은_site_key";
  const USER_ID   = "testuser";                     // ★ 실제로는 서버에서 내려줘야 함
  const USER_KEY  = "user_key_from_server";         // ★ 서버 생성값
  const CHANNEL   = "global";

  async function uploadFile() {
    const input = document.getElementById("file-input");
    const logEl = document.getElementById("upload-log");

    if (!input.files || input.files.length === 0) {
      logEl.textContent = "업로드할 파일을 선택해 주세요.";
      return;
    }

    const file = input.files[0];
    const form = new FormData();
    form.append("file",        file);
    form.append("site_key",    SITE_KEY);
    form.append("channel_key", CHANNEL);
    form.append("user_id",     USER_ID);
    form.append("user_key",    USER_KEY);

    logEl.textContent = "업로드 중...";

    try {
      const rsp  = await fetch(API_BASE + "/upload/chat-file", {
        method: "POST",
        body: form
      });

      const json = await rsp.json();
      if (!json.ok) {
        const reason = json.reason || "UNKNOWN";
        logEl.textContent = "업로드 실패: " + reason;
        return;
      }

      // 성공시 파일 메타데이터
      const f = json.file; // { id, type, name, size, mime }
      logEl.textContent = "업로드 성공! file_id=" + f.id +
                          ", name=" + f.name + ", type=" + f.type;

      // 이미지라면 미리보기용 IMG 태그 예시
      if (f.type === "image") {
        const img = document.createElement("img");
        img.src   = API_BASE + "/chat-file/" + f.id;
        img.alt   = f.name;
        img.style.maxWidth = "120px";
        img.style.display  = "block";
        img.style.marginTop = "8px";
        logEl.appendChild(img);
      }
    } catch (e) {
      console.error(e);
      logEl.textContent = "업로드 중 오류가 발생했습니다.";
    }
  }

  document.getElementById("btn-upload").addEventListener("click", uploadFile);
</script>

이 예제는 “파일 업로드 API만 테스트”하기 위한 용도입니다.
실제 채팅 연동은 아래의 BlueTalk 위젯 예제를 참고하세요.

4. BlueTalk 위젯 + 업로드 연동 예제 (개념)

실제 bluetalk.js 내부에서는, 파일 업로드와 채팅메시지 전송이 다음과 같이 결합되어 동작합니다.

  1. 사용자가 채팅 입력창 옆 “첨부” 아이콘을 클릭
  2. 선택한 파일을 /upload/chat-file에 업로드
  3. 응답에서 file.id를 받아 메시지 payload에 attachment_ids: [file.id]로 포함
  4. WebSocket으로 channel:message 또는 global:message 이벤트 전송
  5. 수신 측에서는 /chat-file/:id URL을 이용해 이미지/파일을 표시

참고용으로, “만약 bluetalk.js 없이 순수 JS + socket.io로 구현한다면” 어떤 코드가 될지 개념 예제를 보여드립니다. (실제 서비스에서는 직접 이렇게 구현할 필요는 없습니다.)

// ※ 순수 socket.io + fetch 조합의 개념 예제입니다.
//    실제 bluetalk.js 내부가 비슷한 과정을 자동으로 처리합니다.

import io from "socket.io-client";

const socket = io("wss://server.bluetalk.kr", {
  auth: {
    site:      SITE_KEY,
    user_id:   USER_ID,
    nickname:  NICKNAME,
    user_key:  USER_KEY
  }
});

async function sendMessageWithFile(file, messageText) {
  // 1) 파일 업로드
  const form = new FormData();
  form.append("file",        file);
  form.append("site_key",    SITE_KEY);
  form.append("channel_key", "global");
  form.append("user_id",     USER_ID);
  form.append("user_key",    USER_KEY);

  const rsp  = await fetch(API_BASE + "/upload/chat-file", {
    method: "POST",
    body: form
  });
  const json = await rsp.json();
  if (!json.ok) throw new Error("UPLOAD_FAIL: " + (json.reason || "UNKNOWN"));

  const f = json.file; // { id, type, ... }

  // 2) 업로드된 파일 id를 첨부한 채팅 메시지 전송
  const payload = {
    channel_key: "global",
    content:     messageText,
    attachment_ids: [ f.id ]
  };

  socket.emit("channel:message", payload, (res) => {
    if (!res || !res.ok) {
      console.log("메시지 전송 실패:", res && res.error);
      return;
    }
    console.log("메시지 전송 성공");
  });
}

위 코드는 “개념 설명용” 코드이며, 실제 사이트에서는 이미 완성된 BlueTalk 위젯을 사용하시는 것을 추천드립니다.
파일 업로드 API를 별도 화면/툴과 연동하고 싶을 때만 참고용으로 보시면 됩니다.

5. BlueTalk 위젯 + 업로드 UI를 한 페이지에 두는 예제

마지막으로, 파일 업로드 로그BlueTalk 채팅 UI를 한 페이지에 같이 띄우는 예제를 보여드립니다.

<div class="row">
  <div class="col-sm-4">
    <h4>업로드 테스트</h4>
    <input type="file" id="file-input">
    <button type="button" id="btn-upload">업로드</button>
    <div id="upload-log" style="margin-top:10px; font-size:12px;">
      업로드 로그가 여기에 표시됩니다.
    </div>
  </div>
  <div class="col-sm-8">
    <h4>BlueTalk 채팅</h4>
    <div id="bluetalk" style="height:480px;"></div>
  </div>
</div>

<script src="https://bluetalk.kr/talk/bluetalk.js"></script>
<script>
  // 서버에서 내려준 값이라고 가정
  window.SITE_KEY          = "발급받은_site_key";
  window.GLOBAL_USER_ID    = "user123";
  window.GLOBAL_USER_KEY   = "user_key_from_server";
  window.GLOBAL_NICKNAME   = "홍길동";

  // BlueTalk 위젯 초기화
  const bt = new BlueTalk({
    mode:     "global",
    targetId: "bluetalk"
  });
  bt.init();

  // REST 업로드 테스트 (3번 예제 재사용)
  const API_BASE  = "https://server.bluetalk.kr";
  const SITE_KEY  = window.SITE_KEY;
  const USER_ID   = window.GLOBAL_USER_ID;
  const USER_KEY  = window.GLOBAL_USER_KEY;
  const CHANNEL   = "global";

  async function uploadFile() {
    const input = document.getElementById("file-input");
    const logEl = document.getElementById("upload-log");

    if (!input.files || input.files.length === 0) {
      logEl.textContent = "업로드할 파일을 선택해 주세요.";
      return;
    }
    const file = input.files[0];

    const form = new FormData();
    form.append("file",        file);
    form.append("site_key",    SITE_KEY);
    form.append("channel_key", CHANNEL);
    form.append("user_id",     USER_ID);
    form.append("user_key",    USER_KEY);

    logEl.textContent = "업로드 중...";

    try {
      const rsp  = await fetch(API_BASE + "/upload/chat-file", {
        method: "POST",
        body: form
      });
      const json = await rsp.json();
      if (!json.ok) {
        logEl.textContent = "업로드 실패: " + (json.reason || "UNKNOWN");
        return;
      }

      const f = json.file;
      logEl.textContent = "업로드 성공! file_id=" + f.id +
                          ", name=" + f.name + ", type=" + f.type;

    } catch (e) {
      console.error(e);
      logEl.textContent = "업로드 중 오류가 발생했습니다.";
    }
  }

  document.getElementById("btn-upload").addEventListener("click", uploadFile);
</script>

이 예제는 “REST 업로드 API를 이해하고, BlueTalk와 함께 테스트해 보는 용도”에 적합합니다.
실제 서비스에서는 블루톡 UI 자체에 포함된 첨부 기능을 사용하는 것이 가장 간단합니다.

6. 정리
  • 현재 파일 업로드 엔드포인트는 POST /upload/chat-file 입니다.
  • 필수 필드는 file, site_key, channel_key, user_id, user_key 입니다.
  • 성공 시 { ok:true, file:{ id, type, name, size, mime } } 형태의 JSON이 반환됩니다.
  • 이미지는 /chat-file/:id 주소로 <img> 태그에 바로 사용할 수 있습니다.
  • 실제 BlueTalk 위젯(bluetalk.js) 내부는 이 과정을 자동으로 처리하며, 이 문서는 별도 REST 연동이 필요할 때 참고용으로 보시면 됩니다.

서버 환경/용량/보관 정책 등은 사이트 성격에 따라 달라질 수 있습니다.
정책 설계가 고민된다면 현재 상황을 정리해서 Q&A 게시판에 남겨주시면
구조·비용 관점까지 함께 검토해 볼 수 있습니다.

팔로팡 오일보이&커스텀 AI코인봇 AI Coin Bot 코스퀀트