이 페이지는 BlueTalk(블루톡)에서 사용하는 이미지/파일 업로드 API를
실제 코드 예제와 함께 설명합니다.
문서 내용과 예제는 모두 현재 서버 구현(/upload/chat-file)과
현재 JS 구조(new BlueTalk() + window.SITE_KEY / GLOBAL_*)에 맞게 정리되어 있습니다.
BlueTalk에서 채팅에 이미지를 붙이거나 파일을 첨부할 때 내부적으로는 다음과 같은 순서로 처리됩니다.
POST /upload/chat-file 로 파일 업로드 (multipart/form-data)file.id 등 메타데이터를 응답attachment_ids 형태로 파일 id를 함께 전송/chat-file/:id 경로를 통해 이미지/파일을 조회
보통은 bluetalk.js 내부가 이 과정을 자동으로 처리하지만,
이 문서는 “직접 REST 호출을 사용해서 파일을 올리고, 그 결과를 채팅에 붙이고 싶을 때” 참고할 수 있는 예제로 생각하시면 됩니다.
현재 서버 구현 기준으로, 업로드 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
아래 예제는 순수 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 위젯 예제를 참고하세요.
실제 bluetalk.js 내부에서는, 파일 업로드와 채팅메시지 전송이 다음과 같이 결합되어 동작합니다.
/upload/chat-file에 업로드file.id를 받아 메시지 payload에 attachment_ids: [file.id]로 포함channel:message 또는 global:message 이벤트 전송/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를 별도 화면/툴과 연동하고 싶을 때만 참고용으로 보시면 됩니다.
마지막으로, 파일 업로드 로그와 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 자체에 포함된 첨부 기능을 사용하는 것이 가장 간단합니다.
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> 태그에 바로 사용할 수 있습니다.
서버 환경/용량/보관 정책 등은 사이트 성격에 따라 달라질 수 있습니다.
정책 설계가 고민된다면 현재 상황을 정리해서
Q&A 게시판에 남겨주시면
구조·비용 관점까지 함께 검토해 볼 수 있습니다.