아바타 API 연동 가이드

방구석 여행 사용자가 만든 3D 아바타(표준 형식 VRM 1.0)를 내 메타버스에서 불러올 수 있습니다. three.js 기반이라면 코드 몇 줄로 붙일 수 있어요.

1. 연동 신청

먼저 내 메타버스를 방 등록으로 등록하고, 관리자에게 아바타 연동을 요청하세요. 관리자가 방 설정에서 아바타 연동됨을 켜면, 사용자가 입장할 때 토큰이 전달되고 사용자의 내 아바타 화면에 내 메타버스가 표시됩니다.

2. 동작 흐름

1. 사용자가 방구석 여행에서 아바타(VRM 1.0)를 만들어 저장합니다.
2. 사용자가 방구석 여행에서 내 메타버스에 입장합니다.
   → 내 메타버스 주소에 토큰이 붙어서 열립니다.
     https://내-메타버스.com/?metatrip_token=<토큰>
3. 내 메타버스가 토큰으로 API 를 호출해 사용자와 아바타를 가져옵니다.
4. 받은 VRM 파일을 three.js + three-vrm 으로 불러와 씬에 배치합니다.
  • 토큰은 사용자 + 메타버스 조합마다 새로 발급되며 24시간 유효합니다. 로그인하지 않은 사용자는 토큰 없이 입장합니다.
  • user.id 는 방구석 여행이 사용자마다 만든 고유 ID 입니다. 카카오 회원번호나 이메일은 전달하지 않습니다.

3. API

GET /api/v1/me — 토큰의 사용자와 아바타 정보

curl -H "Authorization: Bearer <토큰>" https://test.metatrip.net/api/v1/me
{
  "user": {
    "id": "0b6f2c1e-....",        // 방구석 여행 사용자 고유 ID (방이 달라도 같은 사람이면 같은 값)
    "name": "홍길동"
  },
  "avatar": {                      // 아바타를 만들지 않은 사용자는 null
    "format": "vrm",
    "specVersion": "1.0",
    "url": "https://....supabase.co/storage/v1/object/sign/...",  // VRM 파일 (1시간 유효)
    "thumbnailUrl": "https://....",                                 // PNG 썸네일 (없으면 null)
    "updatedAt": "2026-10-31T09:00:00Z",
    "urlExpiresIn": 3600
  },
  "app": { "id": "…", "name": "내 메타버스" },
  "tokenExpiresAt": "2026-11-01T09:00:00Z"   // 토큰은 발급 후 24시간 유효
}

GET /api/v1/avatar?token=<토큰> — VRM 파일로 바로 이동(302). 로더에 주소를 바로 넣을 때 편합니다.

토큰은 Authorization: Bearer <토큰> 헤더(권장) 또는 ?token= 으로 보냅니다. 모든 출처에서 브라우저로 호출할 수 있도록 CORS 가 열려 있습니다.

401 missing_token   토큰이 없음
401 invalid_token   토큰이 틀렸거나 만료됨, 또는 방의 아바타 연동이 꺼짐
404 no_avatar       (GET /avatar) 사용자가 아바타를 만들지 않음
429 rate_limited    요청이 너무 많음 (IP 당 분당 120회)

오류 응답 형식: { "error": { "code": "invalid_token", "message": "..." } }

4. three.js 예제

<!-- three.js + three-vrm (CDN, 빌드 도구 없이) -->
<script type="importmap">
{ "imports": {
  "three": "https://cdn.jsdelivr.net/npm/three@0.180.0/build/three.module.js",
  "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.180.0/examples/jsm/",
  "@pixiv/three-vrm": "https://cdn.jsdelivr.net/npm/@pixiv/three-vrm@3.5.5/lib/three-vrm.module.min.js"
} }
</script>
<script type="module">
import * as THREE from "three";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import { VRMLoaderPlugin, VRMUtils } from "@pixiv/three-vrm";

// 1) 주소에서 토큰을 꺼내고, 주소창에서는 지운다 (토큰 노출 방지)
const params = new URLSearchParams(location.search);
const token = params.get("metatrip_token") ?? sessionStorage.getItem("metatrip_token");
if (params.has("metatrip_token")) {
  sessionStorage.setItem("metatrip_token", token);
  params.delete("metatrip_token");
  history.replaceState(null, "", location.pathname + (params.size ? "?" + params : "") + location.hash);
}

// 2) 사용자와 아바타 정보 가져오기
async function loadMetatripUser() {
  if (!token) return null;
  const res = await fetch("https://test.metatrip.net/api/v1/me", { headers: { Authorization: "Bearer " + token } });
  if (!res.ok) return null; // 토큰 만료 등 → 기본 아바타 사용
  return res.json();
}

// 3) VRM 불러와 씬에 추가
const scene = new THREE.Scene();
const loader = new GLTFLoader();
loader.register((parser) => new VRMLoaderPlugin(parser));

const me = await loadMetatripUser();
if (me?.avatar) {
  const gltf = await loader.loadAsync(me.avatar.url);
  const vrm = gltf.userData.vrm;
  VRMUtils.removeUnnecessaryVertices(gltf.scene);
  scene.add(vrm.scene);           // VRM 1.0: 정면 +Z, 키 약 1.3m, T 포즈
  // 팔 내리기 예시: vrm.humanoid.getNormalizedBoneNode("leftUpperArm").rotation.z = -1.2;
  // 매 프레임 vrm.update(delta) 를 호출해야 뼈 회전이 반영됩니다.
}
</script>

5. AI 에게 개발 맡기기 (프롬프트 예제)

아래 프롬프트를 복사해 ChatGPT, Claude 등 AI 코딩 도구에 붙여 넣으세요. 마지막의 [내 프로젝트 정보]만 채우면 됩니다.

너는 three.js 웹 메타버스 개발자야. 내 메타버스에 "방구석 여행" 아바타 연동을 추가해 줘.

[연동 규격]
- 사용자가 방구석 여행에서 내 사이트로 입장하면 주소에 ?metatrip_token=<토큰> 이 붙는다. 토큰은 24시간 유효하다.
- 사용자 정보 API: GET https://test.metatrip.net/api/v1/me
  - 헤더: Authorization: Bearer <토큰>
  - 응답: { user: { id, name }, avatar: { format: "vrm", specVersion: "1.0", url, thumbnailUrl, updatedAt } | null, app, tokenExpiresAt }
  - avatar.url 은 VRM 1.0 파일 주소이고 1시간 후 만료된다. 오래 머무는 경우 /me 를 다시 호출해 새 주소를 받는다.
  - 오류: 401 missing_token / invalid_token, 429 rate_limited. 형식 { error: { code, message } }
- VRM 파일: glTF 바이너리 + VRMC_vrm 확장, 정면 +Z, 키 약 1.3m, T 포즈, 휴머노이드 뼈(hips, spine, chest, neck, head, 팔·다리) 포함.

[해야 할 일]
1. 페이지 로드 시 URL 에서 metatrip_token 을 읽어 sessionStorage 에 저장하고 history.replaceState 로 주소창에서 지운다.
2. 토큰이 있으면 /me 를 호출하고, avatar 가 있으면 GLTFLoader + @pixiv/three-vrm 의 VRMLoaderPlugin 으로 avatar.url 을 불러온다.
3. 불러온 VRM 을 내 플레이어 캐릭터 대신 사용한다. 기존 캐릭터의 위치·이동·카메라 추적 로직은 그대로 두고 모델만 바꾼다.
   - 높이를 내 월드 스케일에 맞게 조정하고, 매 프레임 vrm.update(delta) 를 호출한다.
   - 걷는 동안 팔다리를 흔드는 간단한 애니메이션을 vrm.humanoid.getNormalizedBoneNode(...) 회전으로 만든다.
4. 토큰이 없거나 API 가 실패하거나 avatar 가 null 이면 기존 기본 캐릭터를 그대로 쓴다. 오류 때문에 페이지가 멈추면 안 된다.
5. 화면 구석에 "방구석 여행 아바타로 입장 중 (이름)" 표시를 작게 띄운다.
6. 토큰을 콘솔이나 외부 분석 도구에 기록하지 않는다.

[내 프로젝트 정보]
- (여기에 사용 중인 three.js 버전, 빌드 도구(Vite 등), 플레이어 캐릭터 코드 파일 위치를 적어 주세요)

변경할 파일과 전체 코드를 보여 주고, 테스트 방법도 알려 줘.

6. 지켜 주세요

  • 토큰은 비밀번호처럼 다뤄 주세요. 주소창에서 지우고, 로그나 분석 도구로 보내지 마세요.
  • 아바타는 사용자 본인의 것입니다. 내 메타버스 안에서 그 사용자를 표시하는 용도로만 쓰고, 파일을 따로 저장해 재배포하지 마세요. (VRM 라이선스: 본인만 사용, 재배포·수정 금지)
  • 아바타 파일 주소는 1시간 후 만료됩니다. 필요하면 /me 를 다시 호출하세요.