Skip to content

Getting Started

Ilhwan Seo edited this page Aug 29, 2026 · 2 revisions

Getting Started

처음 붙이는 사람을 위한 최단 경로입니다. 로그인 → 이벤트 한 건 전송까지가 목표입니다.

전체 그림

앱은 SDK 하나만 알면 됩니다. SDK가 역할별 서비스로 나눠 보내고, 마켓·AdMob·백오피스는 서버 쪽에서 붙습니다.

flowchart LR
  subgraph Client["앱"]
    SDK["Platform SDK<br/>TypeScript 또는 GDScript"]
  end
  subgraph Roles["Cloud Run — asia-northeast3"]
    API["platform-api<br/>세션 · 설정 · 계정 연결"]
    IAP["platform-iap<br/>결제 검증 · 마켓 자격증명 격리"]
    INGEST["platform-ingest<br/>이벤트 · presence 토큰"]
    ADS["platform-ads<br/>광고 정책 · reward claim"]
    ADMIN["platform-admin<br/>운영 API — Google OIDC 전용"]
    WORKER["platform-worker<br/>마켓 완료 재시도"]
  end
  FS[("Firestore<br/>사용자 매핑 · IAP 원장 · 레지스트리")]
  MARKET["Google Play · App Store · AppsInToss"]
  ADMOB["AdMob SSV"]
  EDGE["presence edge — RPI"]
  BO["Backoffice"]
  SDK --> API
  SDK --> IAP
  SDK --> INGEST
  SDK --> ADS
  SDK -.->|opt-in heartbeat| EDGE
  API --> FS
  IAP --> FS
  INGEST --> FS
  ADS --> FS
  WORKER --> FS
  ADMIN --> FS
  IAP -->|구매 확인| MARKET
  MARKET -->|환불 웹훅| IAP
  ADMOB -->|SSV 콜백| ADS
  BO -->|OIDC| ADMIN
Loading

1. 사전 준비

항목 필요한 것
appId 레지스트리에 등록된 앱 ID. 없으면 등록 PR부터
인증 수단 앱별 Firebase Auth의 ID 토큰, 또는 AppsInToss appLogin() 결과, 또는 익명 키
런타임 TypeScript: Node 20+ / React Native / Web (fetch 전역) · GDScript: Godot 4.3

appId가 서버에 없으면 모든 호출이 app_unknown으로 거부됩니다. 자격증명은 X-Seori-App 헤더가 아니라 토큰의 aud 검증이 담당하므로, 다른 앱의 토큰으로는 이 앱의 세션을 열 수 없습니다.

2. 서비스 URL

역할별 Cloud Run 서비스입니다. 전부 asia-northeast3이고 Secret이 아닙니다.

역할 URL 담당
api https://platform-api-306278488979.asia-northeast3.run.app 세션, 설정, 계정 연결, 콘텐츠
iap https://platform-iap-306278488979.asia-northeast3.run.app 결제 검증, entitlement, AppsInToss 세션
ingest https://platform-ingest-306278488979.asia-northeast3.run.app 이벤트 수집, presence 토큰
ads https://platform-ads-306278488979.asia-northeast3.run.app 광고 정책, reward claim
admin — 백오피스 전용. Google OIDC 없이는 403

역할별 URL을 생략하면 SDK가 baseUrl로 대신 보냅니다. 동작은 하지만 결제 트래픽이 api 서비스로 가므로 production 앱은 넷 다 지정하세요.

세션 발급은 기본 api입니다. AppsInToss 로그인(ait-login)은 Toss mTLS 자격증명이 격리된 iap 또는 ads 역할에서만 됩니다 — TypeScript는 adsBaseUrl을 지정하면 세션 요청이 그리로 가고, GDScript는 auth_base_url로 따로 지정합니다.

살아 있는지 확인:

curl -s https://platform-api-306278488979.asia-northeast3.run.app/health/live

3. TypeScript — 10줄

pnpm add https://github.com/seorilabs/platform/releases/download/v0.6.7/seorilabs-platform-sdk-0.4.0.tgz
import { createPlatform } from "@seorilabs/platform-sdk";

const platform = createPlatform({
  baseUrl:       "https://platform-api-306278488979.asia-northeast3.run.app",
  iapBaseUrl:    "https://platform-iap-306278488979.asia-northeast3.run.app",
  ingestBaseUrl: "https://platform-ingest-306278488979.asia-northeast3.run.app",
  adsBaseUrl:    "https://platform-ads-306278488979.asia-northeast3.run.app",
  appId: "my-app",
  eventContext: { platform: "android", appVersion: "1.0.0", locale: "ko-KR" },
});

await platform.signIn({ kind: "firebase-id-token", value: firebaseIdToken });
platform.events.track({ name: "onboarding_complete" });
await platform.events.flush();

세션이 열리면 platform.session.current()에 platformUserId와 CS용 supportCode가 들어 있습니다. 나머지는 TypeScript SDK.

4. GDScript — 10줄

V=0.6.7; B=https://github.com/seorilabs/platform/releases/download/v$V
curl -fsSLO "$B/seorilabs-platform-gdscript-$V.tar.gz"
curl -fsSLO "$B/seorilabs-platform-gdscript-$V.tar.gz.sha256"
sha256sum -c "seorilabs-platform-gdscript-$V.tar.gz.sha256"
tar -xzf "seorilabs-platform-gdscript-$V.tar.gz" -C addons/
var platform := SeoriPlatformClient.new()
platform.configure({
    "base_url": "https://platform-api-306278488979.asia-northeast3.run.app",
    "iap_base_url": "https://platform-iap-306278488979.asia-northeast3.run.app",
    "ingest_base_url": "https://platform-ingest-306278488979.asia-northeast3.run.app",
    "ads_base_url": "https://platform-ads-306278488979.asia-northeast3.run.app",
    "app_id": "my-app",
    "event_context": {"platform": "android", "appVersion": "1.0.0", "locale": "ko-KR"},
})
add_child(platform)   # HTTPRequest가 동작하려면 트리에 있어야 한다

platform.sign_in({"kind": "firebase-id-token", "value": firebase_id_token},
    func(res): if res["ok"]: platform.track("onboarding_complete"))

콜백은 항상 {ok, result, code, message, local} Dictionary 하나를 받습니다. 나머지는 GDScript SDK.

5. 확인

세션이 열렸는지, 이벤트가 나갔는지는 클라이언트에서 바로 볼 수 있습니다.

확인 TypeScript GDScript
세션 await platform.session.current() platform.current_session()
남은 이벤트 await platform.events.flush() 후 outbox 크기 platform.pending_event_count()
설정 await platform.config.fetch({...}) platform.fetch_config({...}, cb)

서버 쪽 반영(원장, 백오피스 화면)은 메인테이너가 확인합니다.

6. 다음 단계

  • 결제를 붙이려면 레지스트리에 features.iap와 entitlement_ids가 있어야 합니다. → App Registration
  • 오류 코드로 UI를 분기합니다. message는 언제든 바뀝니다. → Error Codes
  • 이벤트 이름은 spec/events.md의 3층 구조를 따릅니다. seori_*는 SDK 예약이라 앱이 보낼 수 없습니다.
  • 레퍼런스 배선: React Native · Godot

Clone this wiki locally