Skip to content

게임플레이 JS SDK 레퍼런스 1.0.0-beta.3 ​

게임플레이 JS SDK 는 베타 버전입니다. 베타 테스트 기간 동안 스펙이 변경될 수 있습니다.

베타 기간 중 변경 사항은 릴리즈 노트의 SDK 탭에서 확인하세요.
연동 중 문제가 생기거나 궁금한 점이 있으면 데브톡으로 문의해 주세요.

이 문서는 Gameplay 객체가 제공하는 메서드와 에러 코드 전체를 다룹니다.
설치와 초기화 방법은 먼저 설치·초기화 를 참고해 주세요.

초기화 ​

init(options) ​

ts
declare function init(options: GameplayInitOptions): Promise<void>;

type GameplayInitOptions = {
  gameName: string;
  gameCode: string;
  appId: number;
  clientKey?: string;
  accessToken?: string;
  appUserId?: string;
  tiara?: boolean | GameplayTiaraOptions;
  ad?: GameplayAdOptions;
  webview?: GameplayWebviewOptions;
  ui?: GameplayManagedUIOptions;
};

type GameplayTiaraOptions = {
  thirdAdAgree?: boolean;
};

type GameplayManagedUIOptions = {
  container?: HTMLElement;
  navigation?: GameplayNavigationControlsOptions;
};

type GameplayAdOptions = {
  preload?: boolean;
};

type GameplayWebviewOptions = {
  statusBarOverlay?: boolean;
  statusBarColor?: string;
  orientation?: 'portrait' | 'landscape';
  scrollEnabled?: boolean;
  bouncesEnabled?: boolean;
  pullToRefreshEnabled?: boolean;
  linkPreviewEnabled?: boolean;
  backSwipeEnabled?: boolean;
};

SDK를 초기화합니다.
페이지 라이프사이클당 1회 호출을 권장하며, 초기화가 끝나기 전에 다시 호출하면 먼저 시작된 호출과 동일한 Promise를 공유합니다.

옵션타입설명
gameNamestring필수게임 이름.
닫기 버튼을 눌렀을 때 SDK가 띄우는 이탈 확인 팝업의 제목으로 쓰입니다
gameCodestring필수파트너사가 정해 게임플레이 파트너센터오픈 예정에 등록한 게임 코드.
단축 URL 생성의 gameCode · 광고 CPID 와 같은 값입니다
appIdnumber필수카카오디벨로퍼스 앱 ID.
게임 로그에서 appUserId 의 짝으로 쓰입니다.
확인 방법은 앱 ID 참고
clientKeystring카카오디벨로퍼스가 발급하는 JavaScript 키.
생략하면 카카오 JS SDK 로드를 건너뜁니다.
이후 talkShare 호출은 KAKAO_NOT_AVAILABLE 이 됩니다
accessTokenstring카카오 계정 access token.
게임 로그를 카카오 계정과 연결합니다.
appUserId 와 둘 중 하나를 지정합니다
appUserIdstring카카오 앱 사용자 ID.
단독으로는 쓸 수 없고 appId 와 짝을 이룹니다
tiaraboolean | GameplayTiaraOptions기본값 true게임 로그 자동 전송.
이미 Tiara Web SDK를 직접 연동한 게임은 false 로 끕니다.
아래 표 참고
adGameplayAdOptions기본값 {preload: true}끄더라도 광고 API 를 호출하면 그 시점에 로드됩니다
webviewGameplayWebviewOptions웹뷰 초기 상태를 선언형으로 지정합니다
uiGameplayManagedUIOptionsmanaged UI 부트스트랩.
아래 표 참고

accessToken · appUserId · tiara 는 게임 로그에 쓰입니다.
아래 게임 로그를 참고하세요.

webview 의 각 필드는 톡 버전과 플랫폼 제약이 다릅니다.

필드톡 버전플랫폼설명
statusBarOverlay26.5.0+Android · iOS웹뷰를 상태바 영역까지 확장합니다 (전체화면)
statusBarColor26.6.0+Android · iOS상태바 배경색.
#RRGGBB 형식
orientation26.3.0+Android · iOS화면 방향
scrollEnabled26.7.0+Android · iOS웹뷰 스크롤·오버스크롤 제스처
bouncesEnabled26.7.0+iOS오버스크롤 바운스만 개별 제어
pullToRefreshEnabled26.7.0+iOS당겨서 새로고침
linkPreviewEnabled26.7.0+iOS링크 롱프레스 미리보기
backSwipeEnabled26.3.0+iOS좌측 엣지 백 스와이프.
26.8.0 부터 게임웹뷰 기본값은 false 이므로, 켜야 할 때만 지정합니다

webview 로 지정한 항목은 대응하는 개별 메서드와 같은 동작이며, init 에서 선언하는 것이 권장 경로입니다.
개별 메서드는 게임 도중 값을 다시 바꿔야 할 때만 사용합니다.
각 필드와 대응하는 메서드의 관계는 이 문서의 해당 메서드 항목에서 밝힙니다.

ui 의 각 필드는 다음과 같습니다.

필드타입설명
containerHTMLElement기본값 document.bodySDK가 UI를 붙일 요소.
게임이 별도 루트 안에서 화면을 그리는 경우에만 지정합니다
navigationGameplayNavigationControlsOptions초기 navigation 구성.
표시 여부는 이 안의 visible 이 정합니다

ui 를 생략하면 navigation이 기본 구성으로 표시됩니다.

modal·toast·bottom sheet·loader는 ui 값과 무관하게 호출한 시점에 뜹니다.
ui 가 정하는 것은 navigation 하나입니다.

안전영역과 상태바 오버레이는 navigation 표시 여부와 무관하게 늘 조회해 반영합니다.
navigation을 띄우지 않아도 modal·toast가 그 기준선을 그대로 씁니다.

navigation.visible 을 false 로 주면 init 이 navigation을 그리지 않습니다.
UI를 끄는 것이 아닙니다 — 호출한 컴포넌트는 그때 뜨고, container 도 그대로 적용됩니다.

구성과 표시는 다른 축이라, 구성은 미리 해두고 숨긴 채 시작할 수 있습니다.

ts
await Gameplay.init({
  gameName: '게임 이름',
  gameCode: 'sample-game',
  appId: 1234567,
  ui: {navigation: {visible: false, backgroundColor: '#000000'}, container: myRoot},
});

// navigation은 뜨지 않습니다. 부른 컴포넌트만 뜹니다.
Gameplay.UI.Modal.open({title: '알림'});

// 필요해지면 이때 뜹니다. 위에서 준 구성 그대로입니다.
Gameplay.UI.Navigation.show();

숨긴 동안에는 사용자가 게임웹뷰를 벗어날 수 없습니다

나가기(닫기) 버튼이 navigation 안에 있습니다.
숨긴 동안 게임이 자체 종료 동선을 제공하지 않으면 사용자가 게임에 갇힙니다.

연출 때문에 잠깐 숨겼다면 반드시 되돌리세요.
종료 경로가 있는지는 SDK가 보장하지 못하므로 심사에서 확인합니다.

자체 UI를 이미 가진 게임이 SDK를 단계적으로 들일 때 쓰는 값입니다.
새로 연동하는 게임은 visible 을 건드리지 마세요.

성공하면 별도 값 없이 Promise가 resolve됩니다.

clientKey 를 지정했거나 window.Kakao 객체가 이미 로드되어 있으면, init() 내부에서 카카오 JS SDK 를 로드합니다.
이 로드가 실패하거나 응답이 없으면 init() 이 KAKAO_NOT_AVAILABLE 로 reject됩니다.
clientKey 를 쓰는 게임은 init() 호출을 반드시 try/catch 로 감싸 주세요.
감싸지 않으면 광고 차단기·CSP 차단·네트워크 지연 같은 상황에서 unhandled rejection 이 됩니다.

그 외 내부 동작은 init() 을 막지 않습니다.
광고 SDK 선로드 실패는 init() 을 실패시키지 않고 광고 생성 메서드를 호출하는 시점에 AD_SDK_NOT_AVAILABLE 로 드러나며, webview 옵션 적용 실패와 안전영역·상태바 오버레이 조회 실패도 각각 내부에서 처리되어 init() 을 막지 않습니다.

ts
try {
  await Gameplay.init({
    gameName: '게임 이름',
    gameCode: 'sample-game',
    appId: 1234567,
    clientKey: 'YOUR_JAVASCRIPT_KEY',
    webview: {
      orientation: 'landscape',
      scrollEnabled: false,
    },
  });
} catch (error) {
  // isGameplaySdkError 의 정의는 아래 [에러](#gameplaysdkerror) 항목을 참고해 주세요.
  if (isGameplaySdkError(error) && error.code === 'KAKAO_NOT_AVAILABLE') {
    // clientKey 를 지정했으므로 카카오 JS SDK 로드에 실패하면 이 코드로 reject됩니다.
  } else {
    // 예상하지 못한 실패입니다.
    throw error;
  }
}

게임 로그 ​

게임 로그(Tiara)는 SDK 가 대신 보냅니다.
Tiara Web SDK 를 직접 연동하지 않아도 되고, 게임이 구현할 항목도 없습니다.

SDK 가 보내는 로그시점
SDK_UI_게임_조회init 직후
SDK_UI_게임_체류시간백그라운드 전환과 페이지 이탈
SDK_UI_더보기_클릭더보기 목록이 열릴 때
SDK_UI_더보기_{메뉴명}_클릭더보기 항목 클릭
SDK_UI_닫기_클릭 · SDK_UI_접기_클릭상단 버튼 클릭
SDK_UI_게임종료_팝업_노출종료 확인 팝업 노출
SDK_UI_게임종료_팝업_확인_클릭 · SDK_UI_게임종료_팝업_취소_클릭팝업 버튼 클릭

이미 Tiara 를 직접 연동했다면

tiara: false 로 꺼 주세요.
켠 채로 두면 같은 로그가 두 번 쌓입니다.

게임이 넣는 값은 gameCode 와 카카오 사용자 식별값입니다.
gameCode 는 로그의 section(sdk_ui_{gameCode})과 page_meta.id 가 되고, 식별값은 accessToken 하나이거나 appUserId + appId 입니다.
clientKey 를 준 경우에는 appUserId + clientKey 조합도 성립합니다.
svcDomain · page · thirdProvideAgree 같은 나머지 항목은 SDK 가 채웁니다.

식별값을 넣지 않아도 게임은 정상 동작하지만, 그 로그는 카카오 분석 환경에서 집계·활용할 수 없습니다.

더보기 항목 클릭은 메뉴명을 액션명에 넣어 하나로 보냅니다.
기본 항목은 SDK_UI_더보기_공유하기_클릭 · SDK_UI_더보기_문의하기_클릭 이 되고, dropdown.items 로 덧붙인 항목은 그 label 이 메뉴명이 됩니다.
액션명에 쓸 수 없는 문자는 빠집니다 — 글자·숫자·_ 만 남습니다(게임 가이드(신규) → SDK_UI_더보기_게임가이드신규_클릭).

액션명이 게임 로그 설정과 다릅니다

그 문서는 Tiara Web SDK 를 직접 연동하는 게임용입니다.
게임플레이 JS SDK 는 section · page · 액션명이 모두 다른 별도 명세를 씁니다 — 두 경로의 로그를 분석 단계에서 가를 수 있어야 하기 때문입니다.
직접 구현할 항목이 없으므로 게임이 두 명세를 구분할 필요는 없습니다.

직접 연동게임플레이 JS SDK
sectionSDK_{게임ID}sdk_ui_{gameCode}
pageSDK게임SDK_UI
액션명SDK_게임_조회 · 게임_더보기_클릭 등SDK_UI_ 접두어로 통일

tiara 는 boolean 또는 설정 객체를 받습니다.
켜지는 것은 true 와 같고 설정만 얹으므로, tiara: true 와 tiara: {} 는 결과가 같습니다.

필드타입설명
thirdAdAgreeboolean광고 마케팅 정보 제공 동의 여부.
사용자가 고르는 값이라 동의·미동의가 모두 발생합니다

값을 모르면 주지 않습니다.
주지 않으면 SDK 가 동의 여부를 설정하지 않아 미설정 상태로 남습니다.
로그인 전이라 아직 모르는 상태를 false 로 적어 보내면 동의한 사용자를 미동의로 기록하게 됩니다.

제3자 정보 제공 동의(thirdProvideAgree)는 옵션이 아닙니다.
게임플레이 진입 자체가 그 동의를 필수로 거치므로 SDK 가 true 로 고정합니다.

isAvailable(capability) ​

ts
declare function isAvailable(capability: GameplayCapability): boolean;

type GameplayCapability = Exclude<
  keyof typeof Gameplay,
  'version' | 'init' | 'isAvailable' | 'onTalkEventMessage' | 'UI'
>;

메서드가 현재 환경에서 실제로 지원되는지 동기적으로 점검합니다.
카카오톡 버전은 패치·백포트 빌드가 섞여 있어 버전 비교만으로는 지원 여부를 정확히 알 수 없으므로, 기능 분기가 필요하면 항상 이 메서드로 직접 확인합니다.

파라미터타입설명
capabilityGameplayCapability필수확인할 메서드 이름.
version · init · isAvailable · onTalkEventMessage · UI 를 제외한 Gameplay 의 모든 메서드 이름 중 하나입니다

메서드가 실제로 지원되면 true, 아니면 false 를 반환합니다.

동기 함수이며 어떤 코드도 던지지 않습니다.

ts
if (Gameplay.isAvailable('setScrollEnabled')) {
  await Gameplay.setScrollEnabled(false);
}

version ​

ts
declare const version: string;

로드된 SDK 번들의 버전입니다.
메서드가 아니라 값이라 호출하지 않으며, init() 전에도 읽을 수 있습니다.

SDK 1.0.0-beta.1 부터 제공합니다.
그 이전 버전에서는 undefined 입니다.

ts
console.log(Gameplay.version); // '1.0.0-beta.1'

평소에는 쓸 일이 없습니다.
<script> 에 적은 버전 경로가 곧 이 값이고 integrity 로 고정돼 있어, 적은 것과 다른 버전이 로드될 수 없기 때문입니다.

쓰임은 장애 대응입니다.
문의를 남길 때 이 값을 함께 적어 주시면 어느 빌드에서 생긴 문제인지 바로 좁혀집니다.

기능 분기에 쓰지 마세요

SDK 버전이 같아도 카카오톡 버전에 따라 쓸 수 있는 기능이 다릅니다.
분기가 필요하면 isAvailable 로 메서드가 실제로 있는지 확인하세요.

화면·레이아웃 ​

getSafeArea() 26.5.0+ ​

ts
declare function getSafeArea(): Promise<GameplaySafeAreaInsets>;

type GameplaySafeAreaInsets = {
  top: number;
  left: number;
  bottom: number;
  right: number;
};

기기의 안전영역 인셋을 픽셀 단위로 조회합니다.
노치·홈 인디케이터를 피해 UI를 배치할 때 사용합니다.

반환값의 각 값은 해당 방향에서 확보해야 하는 여백입니다.

필드타입설명
topnumber상단 인셋.
상태바·노치 영역
leftnumber좌측 인셋
bottomnumber하단 인셋.
홈 인디케이터 영역
rightnumber우측 인셋

실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
const insets = await Gameplay.getSafeArea();

document.body.style.paddingTop = `${insets.top}px`;
document.body.style.paddingBottom = `${insets.bottom}px`;

setOrientation(options) 26.3.0+ ​

ts
declare function setOrientation(
  options: GameplayTalkOrientationOptions
): Promise<GameplayTalkOrientationResult>;

type GameplayTalkOrientationMode = 'portrait' | 'landscape' | 'current';

type GameplayTalkOrientationOptions = {
  mode: GameplayTalkOrientationMode;
};

type GameplayTalkOrientationResult = {
  value: 'portrait' | 'landscape';
};

화면 방향을 런타임에 강제로 전환합니다.
init({webview: {orientation}}) 과 같은 동작이며, 초기 상태는 init 에서 선언하는 것이 권장 경로입니다.
이 메서드는 게임 도중 방향을 다시 바꿔야 할 때 사용합니다.

옵션타입설명
modeGameplayTalkOrientationMode필수강제로 전환할 방향.
'current' 는 강제 지정을 해제하고 호스트 기본 동작을 따르게 합니다

반환값의 value 는 전환 후 실제로 적용된 방향입니다.

실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
const result = await Gameplay.setOrientation({mode: 'landscape'});

console.log(result.value);

setStatusBarOverlay(enable) 26.5.0+ ​

ts
declare function setStatusBarOverlay(enable: boolean): Promise<void>;

웹뷰를 상태바 영역까지 확장하거나 기본 레이아웃으로 되돌립니다.
init({webview: {statusBarOverlay}}) 과 같은 동작이며, 초기 상태는 init 에서 선언하는 것이 권장 경로입니다.
이 메서드는 게임 진입·종료 시점처럼 실행 중에 값을 다시 바꿔야 할 때 사용합니다.

네이티브 게임웹뷰 SDK 의 setStatusBarOverlay({enable}) 과 시그니처가 다릅니다.
네이티브는 enable 을 담은 객체를 받지만, JS SDK 는 boolean 값을 그대로 받습니다.
게임웹뷰 SDK 문서에서 마이그레이션하는 경우 이 차이에 주의해 주세요.

레이아웃이 바뀌면 새 안전영역 인셋이 SAFE_AREA UPDATE 이벤트로 자동 전송됩니다.
호출 직후 getSafeArea 를 다시 부르는 대신 onTalkEventMessage 로 이 이벤트를 구독해 반영하는 편이 정확합니다.

파라미터타입설명
enableboolean필수true 면 웹뷰를 상태바 영역까지 확장하고, false 면 기본 레이아웃으로 되돌립니다

성공하면 별도 값 없이 Promise가 resolve됩니다.

실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.setStatusBarOverlay(true);

오버레이는 네이티브 웹뷰가 소유하는 레이아웃 속성이라 페이지를 이동해도 유지됩니다.
게임이 외부 URL 로 리디렉션하는 흐름이 있다면 상태바 오버레이 설정 방법을 함께 확인하세요.

주의사항

웹뷰 초기 상태는 init({webview}) 에 선언하는 것이 권장 경로지만 statusBarOverlay 는 예외입니다.
init 은 게임 진입 직후, 인증이 시작되기 전에 실행되므로 여기서 statusBarOverlay: true 를 선언하면 이어지는 동의창 리디렉션에서 상단이 잘리는 문제가 그대로 재발합니다.
인증과 약관 동의 왕복이 끝난 뒤에 이 메서드로 켜세요.

orientation 등 나머지 webview 필드는 계속 init 에서 선언하는 것이 권장 경로입니다.

changeStatusBarColor(color?) 26.6.0+ ​

ts
declare function changeStatusBarColor(color?: string): Promise<void>;

상태바 배경색을 변경합니다.
init({webview: {statusBarColor}}) 과 같은 동작이며, 초기 상태는 init 에서 선언하는 것이 권장 경로입니다.
이 메서드는 게임 진행 중 색상을 다시 바꿔야 할 때 사용합니다.

파라미터타입설명
colorstring#RRGGBB 또는 RRGGBB 형식의 색상값.
생략하면 기본 색상으로 초기화합니다

성공하면 별도 값 없이 Promise가 resolve됩니다.

색상 형식이 올바르지 않으면 INVALID_INPUT 을 throw 합니다.
브리지 접근이 모두 불가능하면 BRIDGE_NOT_AVAILABLE 을 throw 합니다.
공통 브리지로 폴백하는 경로가 있어 BRIDGE_METHOD_NOT_AVAILABLE 은 발생하지 않습니다.

ts
await Gameplay.changeStatusBarColor('#1A1A1A');

제스처·입력 ​

제스처 제어 메서드 5종(setScrollEnabled·setBouncesEnabled·setPullToRefreshEnabled·setLinkPreviewEnabled·setBackSwipeEnabled)은 모두 init({webview: {...}}) 에 같은 이름의 필드가 있습니다.
초기 상태는 init 에서 선언하는 것이 권장 경로이며, 이 메서드들은 게임 진행 중 값을 다시 바꿔야 할 때 사용합니다.
scrollEnabled: false 는 스크롤과 함께 바운스 효과도 없애므로, 스크롤을 끈 상태라면 setBouncesEnabled 를 별도로 호출할 필요가 없습니다.

setScrollEnabled(enabled) 26.7.0+ ​

ts
declare function setScrollEnabled(enabled: boolean): Promise<void>;

웹뷰의 스크롤 제스처를 켜고 끕니다.
연타형 게임처럼 스크롤 제스처가 터치 입력을 선점하는 문제에 대응할 때 사용합니다.
터치 이벤트(touchstart·touchmove·touchend)는 그대로 전달되므로 인게임 드래그 동작에는 영향이 없습니다.

플랫폼별로 다르게 동작합니다.
iOS 는 UIScrollView 의 scrollEnabled·bounces 를 함께 끄고, Android 는 오버스크롤(바운스·글로우) 효과를 제거하고 웹뷰 스크롤 이동을 억제합니다.

파라미터타입설명
enabledboolean필수true 면 스크롤 제스처를 허용하고, false 면 막습니다

성공하면 별도 값 없이 Promise가 resolve됩니다.

구버전 카카오톡에서는 호스트가 노출하지 않으므로, 호출 전 Gameplay.isAvailable('setScrollEnabled') 로 확인하는 것을 권장합니다.
실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.setScrollEnabled(false);

setBouncesEnabled(enabled) 26.7.0+ iOS ​

ts
declare function setBouncesEnabled(enabled: boolean): Promise<void>;

스크롤이 끝에 닿았을 때의 바운스(튕김) 효과를 켜고 끕니다.
iOS 의 UIScrollView 바운스 효과만 개별로 제어하는 iOS 전용 기능입니다.

파라미터타입설명
enabledboolean필수true 면 바운스 효과를 허용하고, false 면 막습니다

성공하면 별도 값 없이 Promise가 resolve됩니다.

Android 에서는 호스트가 이 메서드를 노출하지 않아 항상 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.
브리지 자체가 없으면 BRIDGE_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.setBouncesEnabled(false);

setPullToRefreshEnabled(enabled) 26.7.0+ iOS ​

ts
declare function setPullToRefreshEnabled(enabled: boolean): Promise<void>;

당겨서 새로고침 제스처를 켜고 끕니다.
iOS 전용 기능입니다.

파라미터타입설명
enabledboolean필수true 면 당겨서 새로고침을 허용하고, false 면 막습니다

성공하면 별도 값 없이 Promise가 resolve됩니다.

Android 에서는 호스트가 이 메서드를 노출하지 않아 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.
브리지 자체가 없으면 BRIDGE_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.setPullToRefreshEnabled(false);

setLinkPreviewEnabled(enabled) 26.7.0+ iOS ​

ts
declare function setLinkPreviewEnabled(enabled: boolean): Promise<void>;

링크를 길게 눌렀을 때 나타나는 3D Touch·Haptic Touch 미리보기를 켜고 끕니다.
iOS 전용 기능입니다.

파라미터타입설명
enabledboolean필수true 면 링크 미리보기를 허용하고, false 면 막습니다

성공하면 별도 값 없이 Promise가 resolve됩니다.

Android 에서는 호스트가 이 메서드를 노출하지 않아 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.
브리지 자체가 없으면 BRIDGE_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.setLinkPreviewEnabled(false);

setBackSwipeEnabled(enabled) 26.3.0+ iOS ​

ts
declare function setBackSwipeEnabled(enabled: boolean): Promise<void>;

iOS 에서 화면 왼쪽 끝을 스와이프해 뒤로가는 엣지 백 제스처를 켜고 끕니다.
iOS 전용 기능입니다.

카카오톡 26.8.0 부터 게임웹뷰는 이 제스처가 꺼진 상태로 생성됩니다.
끄기 위해 init({webview: {backSwipeEnabled: false}}) 나 이 메서드를 호출할 필요가 없고, 뒤로가기 스와이프가 필요한 게임만 true 로 켜면 됩니다.

파라미터타입설명
enabledboolean필수true 면 엣지 백 제스처를 허용하고, false 면 막습니다

성공하면 별도 값 없이 Promise가 resolve됩니다.

Android 에서는 호스트가 이 메서드를 노출하지 않아 항상 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.
호출 전 Gameplay.isAvailable('setBackSwipeEnabled') 로 확인하는 것을 권장합니다.
브리지 자체가 없으면 BRIDGE_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.setBackSwipeEnabled(true);

주의사항

카카오톡 26.8.0 미만에서는 게임웹뷰가 이 제스처를 켠 상태로 생성됩니다.
iOS 는 제스처가 켜진 웹뷰에 내부 제스처 인식기를 설치하고, 이후 값을 false 로 꺼도 그 인식기를 제거하지 않습니다.
그래서 뒤로가기 동작 자체는 막히지만, 화면 가장자리 근처의 터치가 인식기에 선점되어 게임까지 전달되지 않는 현상이 남습니다.

init 의 backSwipeEnabled: false 도 웹뷰 생성 이후에 적용되므로 이 현상을 없애지 못합니다.
가장자리 터치가 조작에 중요한 게임이라면 26.8.0 미만 기기를 고려해 조작 영역을 가장자리에서 띄워 배치하세요.
26.8.0 이상에서는 제스처 인식기 자체가 설치되지 않으므로 별도 대응 없이 해소됩니다.
Android 에서는 재현되지 않는 iOS 한정 현상입니다.

haptic(options) 26.3.0+ ​

ts
declare function haptic(options: GameplayHapticOptions): Promise<void>;

type GameplayHapticMode =
  'impact_light' | 'impact_medium' | 'impact_heavy' | 'success' | 'warning' | 'error' | 'custom';

type GameplayHapticOptions = {
  mode: GameplayHapticMode;
  duration?: number[];
  intensity?: number[];
};

디바이스 햅틱(진동) 피드백을 재생합니다.
내장 모드 6종과 커스텀 패턴을 지원하며, Android·iOS 모두 지원합니다.

옵션타입설명
modeGameplayHapticMode필수재생할 햅틱 모드.
내장 모드 6종(impact_light·impact_medium·impact_heavy·success·warning·error)과 커스텀 패턴(custom)을 지원합니다
durationnumber[]mode: 'custom' 전용.
각 진동 구간의 길이(ms) 배열
intensitynumber[]mode: 'custom' 전용.
각 진동 구간의 세기(0~255) 배열.
인덱스별로 duration 과 짝을 맞추므로 두 배열의 길이를 같게 지정합니다

성공하면 별도 값 없이 Promise가 resolve됩니다.

실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
// 내장 모드
await Gameplay.haptic({mode: 'success'});

// 커스텀 패턴
await Gameplay.haptic({
  mode: 'custom',
  duration: [100, 50, 200],
  intensity: [128, 0, 255],
});

startAccelerometer(options?) 26.5.0+ ​

ts
declare function startAccelerometer(options?: GameplayAccelerometerOptions): Promise<void>;

type GameplayAccelerometerOptions = {
  interval?: number;
};

가속도 센서 수집을 시작합니다.
센서 값은 이 메서드의 반환값이 아니라 네이티브 이벤트로 전달되며, onTalkEventMessage 로 구독해 수신합니다.

수신되는 값의 형태는 GameplayAccelerometerReading({x: number; y: number; z: number})이며, 단위는 m/s² 입니다(중력 포함, W3C DeviceMotionEvent.accelerationIncludingGravity 스펙과 동일). 기기를 수평으로 놓으면 z 축 값이 약 +9.81 이 됩니다.

옵션타입설명
intervalnumber기본값 50수집 주기(ms).
최소값 33

성공하면 별도 값 없이 Promise가 resolve됩니다.

실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.startAccelerometer({interval: 100});

stopAccelerometer() 26.5.0+ ​

ts
declare function stopAccelerometer(): Promise<void>;

가속도 센서 수집을 종료합니다.
게임 종료·백그라운드 전환 시점에 반드시 호출해 불필요한 배터리 소모를 막습니다.

성공하면 별도 값 없이 Promise가 resolve됩니다.

실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.stopAccelerometer();

웹뷰 생애주기 ​

close() 26.3.0+ ​

ts
declare function close(): Promise<void>;

현재 웹뷰를 닫습니다.
닫힌 뒤의 라우팅(이전 화면 복귀 등)은 카카오톡이 처리합니다.

성공하면 별도 값 없이 Promise가 resolve됩니다.

실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.close();

keepBrowser() 26.6.0+ iOS ​

ts
declare function keepBrowser(): Promise<void>;

웹뷰를 닫지 않고 화면 우측의 플로팅 아이콘으로 최소화합니다.
사용자가 아이콘을 다시 탭하면 직전 상태로 복귀합니다.
close() 는 웹뷰를 완전히 종료하지만, keepBrowser() 는 컨텍스트를 유지한 채 최소화한다는 점이 다릅니다.
iOS 전용 기능입니다.

성공하면 별도 값 없이 Promise가 resolve됩니다.

Android 에서는 호스트가 이 메서드를 노출하지 않아 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.
브리지 자체가 없으면 BRIDGE_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.keepBrowser();

접기 UI 는 iPhone 에서만 노출하세요

접기를 제공하는 환경은 카카오톡 안의 iPhone 뿐입니다.
나머지 환경에서는 접기 버튼을 노출하지 마세요.

환경접기호출하면
iPhone제공정상 동작
태블릿미제공웹뷰가 접히지 않고 그대로 종료됩니다
Android미제공BRIDGE_METHOD_NOT_AVAILABLE throw

태블릿이 특히 위험합니다.
카카오톡 인앱브라우저 자체에 접기 버튼이 없고, 호출해도 에러가 나지 않습니다.
Android 처럼 throw 로 걸러지지 않으므로 코드만으로는 드러나지 않은 채 사용자만 게임이 예고 없이 종료되는 경험을 하게 됩니다.

메서드를 막을 것이 아니라 UI 노출을 분기하세요.
제외 목록이 아니라 허용 조건으로 쓰는 편이 안전합니다.

ts
declare function showCollapseButton(): void;

const {isIOS, isTablet, isKakaoTalk} = await Gameplay.getDeviceInfo();

if (isKakaoTalk && isIOS && !isTablet) {
  showCollapseButton();
}

canGoBack() ​

ts
declare function canGoBack(): Promise<boolean>;

호스트 내비게이션 백 스택에서 뒤로가기가 가능한지 조회합니다.
플랫폼에 따라 먼저 시도하는 브리지가 다릅니다.
Android 는 window.webview 를 먼저 시도하고 없으면 window.kakaotalk 로 넘어가며, iOS 는 window.kakaotalk 을 먼저 시도하고 없으면 window.webview 로 넘어갑니다.

뒤로가기가 가능하면 true, 아니면 false 를 반환합니다.
두 브리지가 모두 없거나 canGoBack 메서드를 지원하지 않으면 false 를 반환합니다.

throw하는 에러 코드는 없습니다.
try/catch 가 아니라 반환값 분기로 처리해 주세요.

ts
if (await Gameplay.canGoBack()) {
  showBackButton();
}

resetWebViewHistory(url) 26.5.0+ ​

ts
declare function resetWebViewHistory(url: string): Promise<void>;

현재 웹뷰의 히스토리를 초기화하고 지정한 URL 로 이동합니다.
게임 결과 페이지처럼 뒤로가기로 되돌아가면 안 되는 화면으로 전환할 때 사용합니다.
페이지 이동과 히스토리 초기화가 이 호출 하나로 함께 처리되므로, 이동 후 별도 호출을 다시 부를 필요가 없습니다.

파라미터타입설명
urlstring필수이동할 URL. http 또는 https 스킴만 허용합니다

성공하면 별도 값 없이 Promise가 resolve됩니다.

구버전 카카오톡에서는 호스트가 노출하지 않으므로, 호출 전 Gameplay.isAvailable('resetWebViewHistory') 로 확인하는 것을 권장합니다.
url 이 http · https 외 스킴이면 INVALID_INPUT 을 throw 합니다.
실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
await Gameplay.resetWebViewHistory('https://example.com/result');

setBackClickHandler(handler) 26.3.0+ Android ​

ts
declare function setBackClickHandler(handler: GameplayBackClickHandler | null): Promise<void>;

type GameplayBackClickHandler = () => boolean;

Android 하드웨어·제스처 뒤로가기 입력을 웹이 먼저 가로챕니다.
게임 내 팝업을 닫는 등 웹이 먼저 처리해야 하는 뒤로가기 동작이 있을 때 사용합니다.

기존 게임웹뷰 SDK 문서에서 window.onBackClick에 직접 함수를 등록하던 방식을 이 메서드가 대체합니다.
window 객체에 함수를 대입하던 방식에서 Gameplay.setBackClickHandler(handler) 호출로 바뀐 지점이라, 마이그레이션 시 놓치기 쉽습니다.

window.onBackClick은 페이지 전체에서 하나만 사용할 수 있는 등록 위치입니다.
두 곳에서 등록하면 나중에 등록한 것만 남으므로, 게임 안 여러 레이어가 각자 등록하면 서로 덮어씁니다.
한 곳에서만 등록·관리해 주세요.
해제하려면 handler 자리에 null 을 전달합니다.

iOS 의 엣지 백 스와이프 제어는 이 메서드가 아니라 setBackSwipeEnabled 입니다.
이름이 비슷해 혼동하기 쉬우니 구분해 주세요.

파라미터타입설명
handlerGameplayBackClickHandler | null필수뒤로가기 입력 시 호출되는 콜백.
true 를 반환하면 웹이 처리한 것으로 간주되어 앱 기본 뒤로가기가 실행되지 않고, false 를 반환하면 앱이 기본 뒤로가기를 진행합니다.
null 을 전달하면 등록된 핸들러를 해제합니다

성공하면 별도 값 없이 Promise가 resolve됩니다.

window.onBackClick에 직접 등록하는 방식이므로 브리지에 의존하지 않으며, throw하는 에러 코드는 없습니다.

ts
// 레이어를 열 때 등록
await Gameplay.setBackClickHandler(() => {
  if (isPopupOpen()) {
    closePopup();
    return true;
  }

  return false;
});

// 레이어를 닫을 때 해제
await Gameplay.setBackClickHandler(null);

상태 조회 ​

getSoundState() 26.3.0+ ​

ts
declare function getSoundState(): Promise<TalkSoundState>;

type TalkSoundState = {
  /** 기기 볼륨. `0.0` ~ `1.0`. */
  volume: number;
};

단말의 사운드 볼륨 상태를 조회합니다.
게임 배경음·효과음의 초기 볼륨을 사용자 단말 설정에 맞춰 정할 때 사용합니다.

반환값은 단말의 현재 볼륨을 나타내는 값 하나로 구성됩니다.

필드타입설명
volumenumber단말의 현재 사운드 볼륨.
0.0 ~ 1.0 범위이며 0 이면 무음입니다

값이 이미 0~1 이므로 게임 오디오 볼륨에 그대로 넣을 수 있습니다.
volume * 100 같은 변환을 넣으면 어긋납니다.

실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
const {volume} = await Gameplay.getSoundState();

if (volume === 0) {
  showMuteIndicator();
}

getNetworkState() 26.5.0+ ​

ts
declare function getNetworkState(): Promise<GameplayNetworkState>;

type GameplayNetworkState = {
  isWifi: boolean;
  networkType: 'wifi' | 'cellular' | 'none' | 'unknown';
};

단말의 네트워크 연결 상태를 조회합니다.
큰 리소스를 내려받기 전 셀룰러 환경인지 확인해 안내하거나, 오프라인 상태를 감지해 재시도 UI를 보여줄 때 사용합니다.

반환값은 Wi-Fi 연결 여부와 상세 연결 유형을 함께 담습니다.

필드타입설명
isWifibooleanWi-Fi 연결 여부
networkType'wifi' | 'cellular' | 'none' | 'unknown'연결 유형.
'none' 은 오프라인, 'unknown' 은 판별 불가를 의미합니다

실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
const {networkType} = await Gameplay.getNetworkState();

if (networkType === 'cellular') {
  confirmCellularDownload();
}

getDeviceInfo() ​

ts
declare function getDeviceInfo(): Promise<GameplayDeviceInfo>;

type GameplayDeviceInfo = {
  platform: 'ios' | 'android' | 'unknown';
  isIOS: boolean;
  isAndroid: boolean;
  osVersion?: string;
  isTablet: boolean;
  isKakaoTalk: boolean;
  isGameWebView: boolean;
  talkVersion?: string;
};

플랫폼·OS 버전·폼팩터·카카오톡 여부·게임웹뷰 여부·카카오톡 버전을 한 번에 조회합니다.
네이티브 브리지를 쓰지 않고 navigator.userAgent 만 파싱하므로, 게임웹뷰뿐 아니라 일반 브라우저에서도 결과를 반환합니다.

반환값은 플랫폼 판별 결과와 카카오톡 관련 정보를 하나의 객체로 묶어 담습니다.

필드타입설명
platform'ios' | 'android' | 'unknown'판별된 플랫폼.
iPadOS 13+ 는 User-Agent 에 iPad 토큰이 없어 터치 지원 여부로 구분해 ios 로 판별합니다
isIOSbooleanplatform 이 'ios' 인지 여부
isAndroidbooleanplatform 이 'android' 인지 여부
osVersionstringplatform 의 OS 버전.
iOS 는 18.6, Android 는 14 형식입니다.
platform 과 짝이 맞을 때만 값이 있습니다: iPadOS 데스크톱 모드는 User-Agent 가 Macintosh 라 실제 iOS 버전을 알 수 없어 platform 이 'ios' 인데도 undefined 입니다
isTabletboolean태블릿 여부.
iPad(iPadOS 데스크톱 모드 포함)와 Android 태블릿입니다
isKakaoTalkboolean카카오톡 인앱 웹뷰 여부.
게임웹뷰를 포함합니다
isGameWebViewboolean게임웹뷰 여부.
일반 인앱브라우저와 구분됩니다
talkVersionstring카카오톡 버전(semver). Android 는 User-Agent 에 7자리 빌드번호로 실리며 semver 로 정규화됩니다.
판별 불가 시 undefined

talkVersion 을 기능 분기에 사용하지 마세요.
버전 비교는 패치·백포트 빌드에서 어긋나므로, 기능 지원 여부는 isAvailable 로 실제 메서드 존재를 직접 확인하는 것이 정확합니다.
talkVersion 의 용도는 카카오톡 업데이트 안내 UX, 분석 지표, 버그 리포트입니다.

isTablet 은 User-Agent 기준이며 화면 크기를 보지 않습니다.
폴더블 폰을 펼치면 화면이 태블릿만큼 넓어지지만 태블릿이 아니고, iPad 는 split view 에서 viewport 가 기기 크기와 무관해집니다.
레이아웃 분기가 필요하면 이 값과 CSS 미디어 쿼리를 함께 쓰는 것이 안전합니다.
판정 규칙과 환경별 결과는 디바이스 구분 방법 에 정리되어 있습니다.

네이티브 브리지를 쓰지 않고 navigator.userAgent 만 파싱하므로 throw하는 에러 코드는 없습니다.
navigator 가 없거나 User-Agent 를 해석하지 못해도 예외 대신 platform: 'unknown' 과 talkVersion: undefined 를 담은 결과를 반환합니다.
판별 실패는 에러가 아니라 정상 결과입니다.

ts
const info = await Gameplay.getDeviceInfo();

if (info.isGameWebView) {
  // 게임웹뷰 전용 UI 노출
}

네이티브 이벤트 ​

카카오톡은 게임웹뷰에서 실행 중인 페이지의 정해진 window 함수로 이벤트를 전달합니다.
기본 함수 이름은 onTalkEventMessage 이며, 그 이름으로 등록·구독하는 방법이 아래 두 메서드입니다.

전달되는 메시지의 형태는 아래 GameplayTalkEventMessage union으로 고정되어 있습니다.

ts
type GameplayLifecycleEventMessage = {
  event: 'REQUEST' | 'RESPONSE' | 'UPDATE';
  type: 'LIFECYCLE';
  payload: {
    state: 'BACKGROUND' | 'FOREGROUND';
  };
};

type GameplaySafeAreaEventMessage = {
  event: 'REQUEST' | 'RESPONSE' | 'UPDATE';
  type: 'SAFE_AREA';
  payload: GameplaySafeAreaInsets;
};

type GameplaySoundStateEventMessage = {
  event: 'REQUEST' | 'RESPONSE' | 'UPDATE';
  type: 'SOUND_STATE';
  payload: TalkSoundState;
};

type GameplayAccelerometerReading = {
  x: number;
  y: number;
  z: number;
};

type GameplayAccelerometerEventMessage = {
  event: 'REQUEST' | 'RESPONSE' | 'UPDATE';
  type: 'ACCELEROMETER';
  payload: GameplayAccelerometerReading;
};

type GameplayUnknownTalkEventMessage = {
  event: 'REQUEST' | 'RESPONSE' | 'UPDATE';
  type: string;
  payload?: unknown;
};

type GameplayTalkEventMessage =
  | GameplayLifecycleEventMessage
  | GameplaySafeAreaEventMessage
  | GameplaySoundStateEventMessage
  | GameplayAccelerometerEventMessage
  | GameplayUnknownTalkEventMessage;

메시지는 type 필드로 종류를 구분합니다.
event 필드는 모든 메시지에 공통으로 있으며 요청·응답·상태 변경 중 무엇에 의한 이벤트인지 나타냅니다.

typepayload설명
'LIFECYCLE'{state: 'BACKGROUND' | 'FOREGROUND'}웹뷰가 포그라운드·백그라운드로 전환될 때
'SAFE_AREA'GameplaySafeAreaInsets안전영역 인셋이 갱신될 때.
setStatusBarOverlay 호출 직후에도 UPDATE 로 전송됩니다
'SOUND_STATE'TalkSoundState단말 사운드 볼륨이 바뀔 때
'ACCELEROMETER'GameplayAccelerometerReadingstartAccelerometer 로 수집을 시작한 뒤 주기적으로
그 외 문자열unknown (있으면)아직 문서화되지 않은 이벤트.
type 이 위 4종에 해당하지 않으면 이 케이스로 들어옵니다

onTalkEventMessage(handler, options?) 26.3.0+ ​

ts
declare function onTalkEventMessage(
  handler: (message: GameplayTalkEventMessage) => void,
  options?: {handlerName?: string}
): Promise<() => void>;

네이티브가 push하는 이벤트를 구독합니다.
registerNativeHandler 를 기본 핸들러 이름('onTalkEventMessage')으로 호출하는 헬퍼이며, 대부분의 경우 이 메서드만으로 충분합니다.

옵션타입설명
handlerNamestring기본값 'onTalkEventMessage'window에 등록할 이벤트 처리 함수 이름.
같은 페이지에서 구독을 서로 다른 이름으로 분리하고 싶을 때만 지정합니다

반환값은 teardown 함수입니다.
호출하면 이 handler 하나만 구독 해제되며, 같은 이름으로 등록된 다른 handler는 계속 이벤트를 받습니다.
화면을 떠날 때 반드시 호출해 해제해 주세요.
게임 화면을 전환할 때마다 teardown 없이 다시 등록하면 handler가 계속 쌓이고, 이후 네이티브 이벤트 하나당 쌓인 handler 수만큼 콜백이 중복 실행됩니다(같은 갱신 로직이 여러 번 돌아 UI가 겹쳐 갱신되거나 사운드가 중복 재생되는 식으로 드러납니다).

실패 시 INVALID_INPUT · BRIDGE_NOT_AVAILABLE · BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.
INVALID_INPUT 이 발생하는 조건은 registerNativeHandler 항목과 같습니다.

ts
const teardown = await Gameplay.onTalkEventMessage((message) => {
  if (message.type === 'ACCELEROMETER') {
    // GameplayUnknownTalkEventMessage.type 이 string 이라 판별 유니언이 완전히 좁혀지지 않으므로 캐스팅합니다.
    const {x, y, z} = (message as GameplayAccelerometerEventMessage).payload;
    updateTilt(x, y, z);
  }
});

await Gameplay.startAccelerometer({interval: 100});

// 화면을 떠날 때
await Gameplay.stopAccelerometer();
teardown();

registerNativeHandler(handlerName, handler) 26.3.0+ ​

ts
declare function registerNativeHandler(
  handlerName: string,
  handler: (message: GameplayTalkEventMessage) => void
): Promise<() => void>;

onTalkEventMessage 가 감싸고 있는 저수준 API입니다.
대부분의 경우 onTalkEventMessage 를 쓰면 됩니다.
핸들러 이름을 직접 지정해 구독을 이름으로 분리해야 하는 경우에만 이 메서드를 직접 호출합니다.
같은 이름으로 여러 번 호출해도 네이티브 등록은 처음 한 번만 일어나고, 이후 등록한 handler들은 모두 같은 dispatcher 아래 누적되어 함께 호출됩니다.

파라미터타입설명
handlerNamestring필수window에 등록할 이벤트 처리 함수 이름.
유효한 JS 식별자 형식이어야 하며, 아래 예약 이름은 사용할 수 없습니다
handler(message: GameplayTalkEventMessage) => void필수이벤트 수신 콜백

반환값은 teardown 함수입니다.
호출하면 이 handler 하나만 구독 해제되며, 같은 이름으로 등록된 다른 handler는 영향받지 않습니다.
마지막 handler까지 해제되면 그 이름의 공통 이벤트 전달 함수도 함께 정리됩니다.
onTalkEventMessage 항목과 같은 이유로, 화면 전환마다 teardown 없이 등록만 반복하면 handler가 쌓여 콜백이 중복 실행됩니다.

handlerName 이 다음 중 하나에 해당하면 INVALID_INPUT 을 throw 합니다.

  • 유효한 JS 식별자 형식(/^[a-zA-Z_$][\w$]*$/)이 아닌 경우: 공백 포함, 숫자로 시작, 하이픈·점 포함, 빈 문자열 등
  • 다음 예약 이름 중 하나인 경우: __proto__·constructor·prototype·close·open·print·eval·Function·location·document·window·self·top·parent·onerror·Gameplay·GameplayUI·Kakao·kakaoAdFit·kakaotalkGamePlay·kakaotalk·webview

그 외 실패 시 BRIDGE_NOT_AVAILABLE 또는 BRIDGE_METHOD_NOT_AVAILABLE 을 throw 합니다.

ts
const teardown = await Gameplay.registerNativeHandler('scoreboardEvents', (message) => {
  if (message.type === 'SOUND_STATE') {
    // GameplayUnknownTalkEventMessage.type 이 string 이라 판별 유니언이 완전히 좁혀지지 않으므로 캐스팅합니다.
    syncVolumeUI((message as GameplaySoundStateEventMessage).payload.volume);
  }
});

// 화면을 떠날 때
teardown();

공유 ​

talkShare(options) ​

ts
declare function talkShare(options: GameplayTalkShareOptions): Promise<void>;

type GameplayTalkShareOptions = {
  templateId?: number | null;
  installTalk?: boolean;
  templateArgs?: Record<string, string>;
  serverCallbackArgs?: GameplayShareServerCallbackArgs;
  pickerSettings?: {
    groupId?: number;
    args?: Record<string, unknown>;
    limit?: number;
    type?: 'default' | 'chat' | 'friend';
    logs?: {
      section: string;
      customProps: Record<string, string | number | boolean>;
    };
  };
};

type GameplayShareServerCallbackArgs = {
  APP_USER_ID: number;
  APP_ID: number;
  GAME_TYPE: string;
  MESSAGE_TYPE: GameplayShareMessageType;
  HAS_REWARD: boolean;
  SHARE_ID?: string;
};

type GameplayShareMessageType = 'GAME_SHARE' | 'RANKING_SHARE';

카카오톡 친구에게 메시지 템플릿으로 게임을 공유합니다.
카카오 JS SDK 의 Share.sendCustom 을 그대로 호출하는 wrapper이며, templateId 를 제외한 값은 별도 검증 없이 그대로 전달됩니다.

옵션타입설명
templateIdnumber필수카카오 메시지 템플릿 ID. 누락하거나 null 이면 INVALID_INPUT
installTalkboolean카카오톡 미설치 사용자에게 설치 페이지를 노출할지 여부
templateArgsRecord<string, string>템플릿 치환 인자.
키와 값 모두 문자열이어야 하며, 게임플레이 서비스가 요구하는 키는 공유 설정 을 참고해 주세요
serverCallbackArgsGameplayShareServerCallbackArgs공유 보상 결과 통지 콜백으로 echo 되는 식별 파라미터
pickerSettings아래 하위 표의 객체친구 피커 설정.
게임 공유·랭킹 공유·보상 공유 모두 심사 체크리스트가 포함을 요구하므로 생략할 수 없습니다

serverCallbackArgs 에 담은 값은 카카오톡 공유가 발생한 뒤 게임플레이 서버가 그대로 echo 하여 공유 웹훅 연동 콜백 본문에 담아 파트너사 서버로 전달합니다.
필드가 하나라도 누락되면 공유 시점에는 에러가 나지 않고, 이후 발송 결과 집계와 보상 결과 콜백이 조용히 끊깁니다.
자체 점검 항목은 심사 체크리스트 를 참고해 주세요.

필드타입설명
APP_USER_IDnumber필수파트너사 앱 사용자 식별자.
공유 주체입니다
APP_IDnumber필수파트너사 식별자.
다중 게임 운영 시 라우팅에 쓰입니다
GAME_TYPEstring필수파트너사 게임 식별자.
게임플레이 파트너센터오픈 예정에 등록한 게임 코드와 같은 값입니다
MESSAGE_TYPE'GAME_SHARE' | 'RANKING_SHARE'필수공유 소재 구분
HAS_REWARDboolean필수true 면 보상 있는 공유, false 면 단순 공유.
보상 여부는 이 필드가 나타내며 MESSAGE_TYPE 은 나타내지 않습니다
SHARE_IDstring (UUID)파트너사가 공유 시점에 발급하는 트랜잭션 식별자.
보상 결과 콜백의 매칭 키이자 파트너사 멱등성 키이므로 공유 1건당 고유해야 합니다.
보상 결과를 매칭할 필요가 없으면 생략할 수 있습니다

pickerSettings 는 카카오톡 공유 시 노출되는 친구 피커 UI 를 설정합니다.
groupId · limit · type · args · logs 는 SDK 타입만으로는 알 수 없는 게임플레이 서비스 요구값이 있으므로, 채우기 전에 심사 체크리스트 를 함께 확인해 주세요.
게임 공유·랭킹 공유·보상 공유 어느 흐름이든 pickerSettings 를 생략하면 심사 승인을 받을 수 없습니다.

필드타입설명
groupIdnumber공유 피커 그룹 ID. 파트너사가 임의로 정하는 값이 아니라 카카오가 환경별로 지정합니다: CBT 10, PROD 12. 자세한 값은 공유 설정 을 참고해 주세요
limitnumber선택 가능한 친구 수 상한.
SDK 기본값은 없으며, 심사 체크리스트는 게임플레이 서비스 요구사항으로 1 을 요구합니다
type'default' | 'chat' | 'friend'피커 UI 종류.
SDK 기본값은 없으며, 심사 체크리스트는 게임플레이 서비스 요구사항으로 'default' 를 요구합니다
argsRecord<string, unknown>카카오 피커에 전달하는 부가 데이터.
심사 체크리스트가 요구하는 필드입니다
logs{section: string; customProps: Record<string, string | number | boolean>}공유 피커 노출 로그 태깅.
심사 체크리스트가 요구하는 필드입니다

args 는 타입상 Record<string, unknown> 으로 임의 키를 받지만, 게임플레이 서비스는 아래 키를 요구합니다.

필드타입설명
copy_urlstring단축 URL 생성 API 응답의 short_url. 공유 설정 에서 안내하는 templateArgs.BUTTON_URL 과 같은 값을 넣습니다

logs 는 공유 피커가 노출될 때 남기는 로그에 태깅할 값입니다.

필드타입설명
sectionstring필수로그를 남길 화면·섹션 식별자.
SDK 기본값은 없으며, 심사 체크리스트는 게임플레이 서비스 요구사항으로 고정값 'gameplay' 를 요구합니다
customPropsRecord<string, string | number | boolean>필수로그에 함께 남길 커스텀 속성.
아래 표의 키를 모두 포함해야 합니다

customProps 는 타입상 Record<string, string \| number \| boolean> 으로 임의 키를 받지만, 게임플레이 서비스는 아래 키를 요구합니다.

필드타입설명
gameplay_message_type'GAME_SHARE' | 'RANKING_SHARE' | 'REWARD_SHARE'필수공유 소재 구분 태깅.
serverCallbackArgs.MESSAGE_TYPE 은 이 중 앞의 두 값만 쓰므로, 이름이 비슷하다고 같은 값 집합으로 착각하지 마세요
gameplay_originstring필수파트너사 게임 출처 구분값.
{파트너사명}_GAME 형식이며, 값 확정 전 카카오와 사전 협의가 필요합니다
gameplay_game_typestring필수파트너사명과 게임 이름을 결합한 식별값.
{파트너사명}_${GAME_TITLE} 형식입니다
gameplay_template_idnumber필수사용 중인 공유 템플릿 ID. CBT 126532, PROD 126533

성공하면 별도 값 없이 Promise가 resolve됩니다.

templateId 가 없거나 null 이면 INVALID_INPUT 을 throw 합니다.
KAKAO_NOT_AVAILABLE 은 카카오 JS SDK 를 찾거나 로드하지 못한 경우, KAKAO_SHARE_NOT_AVAILABLE 은 카카오 JS SDK 는 있으나 Share.sendCustom 이 없는 경우입니다.
init 에 clientKey 를 전달하지 않으면 카카오 JS SDK 로드를 건너뛰므로, 이후 talkShare 호출은 KAKAO_NOT_AVAILABLE 이 됩니다.

ts
// 단축 URL 생성 API 응답의 short_url. templateArgs.BUTTON_URL 과 pickerSettings.args.copy_url 에 같은 값을 넣습니다.
const shortUrl = 'https://vo.kakao.com/AbCdEfGh12';

await Gameplay.talkShare({
  templateId: 126533, // CBT=126532, PROD=126533
  templateArgs: {
    THU: 'https://example.com/thumbnail.png',
    TITLE: '친구가 신기록에 도전 중!',
    DESCRIPTION: '지금 바로 참여해 보세요.',
    BUTTON_TEXT: '지금 플레이',
    BUTTON_URL: shortUrl,
  },
  serverCallbackArgs: {
    APP_USER_ID: 1111111,
    APP_ID: 1234567,
    GAME_TYPE: 'sample-game',
    MESSAGE_TYPE: 'GAME_SHARE',
    HAS_REWARD: false,
    SHARE_ID: 'a3f2c5b7-9d11-4e8a-9f01-2b6c7e8a9d10',
  },
  pickerSettings: {
    groupId: 12, // CBT=10, PROD=12
    limit: 1,
    type: 'default',
    args: {
      copy_url: shortUrl,
    },
    logs: {
      section: 'gameplay',
      customProps: {
        gameplay_message_type: 'GAME_SHARE',
        gameplay_origin: 'sample-partner_GAME',
        gameplay_game_type: 'sample-partner_sample-game',
        gameplay_template_id: 126533, // CBT=126532, PROD=126533
      },
    },
  },
});

광고 ​

애드핏 전면 광고 SDK를 감싸 전면 광고와 보상형 전면 광고 인스턴스를 생성합니다.
광고 소재 심사·노출 UX·부가설정은 애드핏 광고 SDK 문서를 따르며, 이 문서는 JS SDK가 노출하는 호출 표면만 다룹니다.

광고 SDK는 init 시점에 미리 로드됩니다.
로드 실패는 init 을 실패시키지 않고, 광고 생성 메서드를 호출하는 시점에 드러납니다: 광고 문제로 광고와 무관한 기능까지 막지 않기 위함입니다.
광고를 쓰지 않는 게임은 init({ad: {preload: false}}) 로 선로드를 끌 수 있으며, 끄더라도 광고 생성 메서드를 호출하면 그 시점에 로드됩니다.

createInterstitialAd(options) ​

ts
declare function createInterstitialAd(
  options: GameplayAdCreateOptions
): Promise<GameplayInterstitialAd>;

type GameplayAdCreateOptions = {
  adUnit: string;
  ctag?: GameplayAdCtag;
  safeAreaInset?: GameplaySafeAreaInsets | false;
};

type GameplayAdCtag = {
  cp: string;
  channel: string;
};

전면 광고 인스턴스를 생성합니다.
생성만으로는 노출되지 않으며, open()을 호출해야 노출을 요청합니다.

adUnit 은 init 이 아니라 이 메서드 호출 시점에 받습니다.
게임 안의 여러 광고 지면이 서로 다른 광고단위를 쓸 수 있기 때문입니다.

옵션타입설명
adUnitstring필수발급받은 광고단위 ID
ctagGameplayAdCtag게임별 매출 집계 키.
애드핏 스펙상 지면 단위로 받으므로, 광고를 생성하는 모든 지점에 넣어야 합니다
safeAreaInsetGameplaySafeAreaInsets | false광고가 노치·홈 인디케이터를 침범하지 않도록 전달하는 inset. 생략하면 자동으로 채워집니다

ctag 의 두 필드는 타입만 보면 string 이라 무엇을 넣어야 하는지 알 수 없습니다.
심사 체크리스트가 이 두 필드를 확인하므로 아래 표대로 정확히 채워 주세요.

필드타입설명
cpstring필수CPID. 파트너센터오픈 예정에 등록한 게임 코드와 같은 값이어야 합니다
channelstring필수카카오가 제공하는 채널 ID

cp가 파트너센터의 게임 코드와 어긋나면 매출이 그 게임에 연결되지 않습니다.
메타데이터 API로 게임을 등록했던 파트너사는 그 code 값을 그대로 유지합니다.
애드핏 스펙상 ctag는 지면 단위로 받으므로, 광고를 생성하는 모든 지면에 같은 값을 빠짐없이 넣어야 합니다.

주의사항

여러 지면 중 한 곳에서 ctag 를 빠뜨리면 그 지면 매출만 조용히 누락됩니다.
에러가 발생하지 않아 발견이 늦습니다.
광고 생성 지점을 한 곳으로 감싸 두는 것을 권장합니다.

safeAreaInset 은 값에 따라 다르게 동작합니다.

값동작
생략getSafeArea() 결과로 자동 채움.
브리지가 없거나 조회에 실패하면 옵션 없이 생성
객체그 값을 그대로 전달.
자동 채움보다 우선
false자동 채움을 끄고 옵션에서 제외

조회 실패로 광고 생성을 막지 않습니다: inset 없이 만드는 편이 못 만드는 것보다 낫기 때문입니다.

전면 광고는 화면 전체를 덮으므로, 게임 페이지의 viewport 메타태그에 viewport-fit=cover 가 필요합니다.
없으면 광고가 안전영역까지 확장되지 않아 닫기 버튼이 노치나 홈 인디케이터에 가릴 수 있습니다.

html
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />

생성된 전면 광고 인스턴스를 반환합니다.
인스턴스가 제공하는 메서드·이벤트는 광고 인스턴스 항목에서 다룹니다.

AD_SDK_NOT_AVAILABLE 은 광고 SDK 스크립트 로드부터 애드핏 초기화 완료까지 전 과정에서 발생하며, 원인은 네 가지입니다.
메시지로 원인이 구분되며, 어느 단계에서 멈췄는지가 대응을 가릅니다.

  • 스크립트 로드 실패 (error 이벤트)
  • 스크립트 무응답: load · error 어느 쪽도 오지 않음 (광고 차단기, CSP 차단, 네트워크 stall)
  • 애드핏 초기화 미완료: window.kakaoAdFit 객체는 생성됐지만 광고 팩토리가 끝내 나타나지 않음
  • cmd 큐 미실행: 큐에 넣은 생성 콜백이 상한(5초) 내에 실행되지 않음

AD_INSTANCE_NOT_AVAILABLE 은 애드핏 팩토리 호출 결과가 nullish인 경우 발생합니다.
destroy() 이후 재사용으로 발생하는 경우는 광고 인스턴스 항목에서 다룹니다.

ts
const ad = await Gameplay.createInterstitialAd({
  adUnit: 'DAN-AbCdEfGhIjKl',
  ctag: {cp: 'my_game_001', channel: 'CHANNEL_ID'},
});

ad.onOpen(() => {
  console.log('전면 광고 노출 시작');
});

ad.onClose(() => {
  ad.destroy();
});

ad.load();
ad.open();

createRewardedInterstitialAd(options) ​

ts
declare function createRewardedInterstitialAd(
  options: GameplayAdCreateOptions
): Promise<GameplayRewardedInterstitialAd>;

보상형 전면 광고 인스턴스를 생성합니다.
옵션은 createInterstitialAd와 동일한 GameplayAdCreateOptions 를 받습니다.

옵션타입설명
adUnitstring필수발급받은 광고단위 ID
ctagGameplayAdCtag게임별 매출 집계 키.
cp·channel 의 의미와 누락 주의사항은 createInterstitialAd 항목을 참고해 주세요
safeAreaInsetGameplaySafeAreaInsets | false광고가 노치·홈 인디케이터를 침범하지 않도록 전달하는 inset. 값에 따른 동작은 createInterstitialAd 항목과 같습니다

생성된 보상형 전면 광고 인스턴스를 반환합니다.
광고 인스턴스의 모든 메서드·이벤트에 더해 onReward/offReward 를 추가로 제공합니다.
보상 지급 판정 흐름은 애드핏 광고 SDK: 보상 지급 시점 을 참고해 주세요.

throw 가능 코드는 createInterstitialAd와 같습니다: AD_SDK_NOT_AVAILABLE, AD_INSTANCE_NOT_AVAILABLE.

ts
const rewardedAd = await Gameplay.createRewardedInterstitialAd({
  adUnit: 'DAN-ZzYyXxWwVvUu',
  ctag: {cp: 'my_game_001', channel: 'CHANNEL_ID'},
});

rewardedAd.onReward(() => {
  console.log('보상 지급 대상 이벤트 수신');
});

rewardedAd.load();
rewardedAd.open();

광고 인스턴스 ​

ts
interface GameplayInterstitialAd {
  load(): void;
  open(): void;
  close(): void;
  destroy(): void;
  onLoad(callback: GameplayAdCallback): void;
  offLoad(callback: GameplayAdCallback): void;
  onOpen(callback: GameplayAdCallback): void;
  offOpen(callback: GameplayAdCallback): void;
  onClose(callback: GameplayAdCallback): void;
  offClose(callback: GameplayAdCallback): void;
  onUnload(callback: GameplayAdCallback): void;
  offUnload(callback: GameplayAdCallback): void;
  onError(callback: GameplayAdErrorCallback): void;
  offError(callback: GameplayAdErrorCallback): void;
}

interface GameplayRewardedInterstitialAd extends GameplayInterstitialAd {
  onReward(callback: GameplayAdCallback): void;
  offReward(callback: GameplayAdCallback): void;
}

type GameplayAdCallback = () => void;

/** 애드핏 이 `failed` 리스너를 인자 없이 호출하는 경우가 있어 `error` 는 선택 파라미터입니다. */
type GameplayAdErrorCallback = (error?: unknown) => void;

createInterstitialAd·createRewardedInterstitialAd 로 생성한 인스턴스가 제공하는 메서드와 이벤트입니다.
보상형 인스턴스는 위 메서드에 더해 onReward/offReward 를 추가로 제공합니다.

메서드설명
load()광고 소재를 불러옵니다
open()광고 노출을 요청합니다.
요청일 뿐 노출 성사를 보장하지 않으므로, 노출 집계나 게임 일시정지 처리는 open() 호출이 아니라 onOpen 콜백을 기준으로 해야 합니다
close()노출 중인 광고를 닫습니다
destroy()인스턴스를 정리합니다.
이미 정리된 인스턴스에 다시 호출해도 안전합니다(멱등)

destroy() 이후 load() · open() · close() 를 호출하면 AD_INSTANCE_NOT_AVAILABLE 을 throw합니다.

이벤트는 애드핏 이 발생시키는 원본 이벤트를 Gameplay 메서드로 구독합니다.

애드핏 이벤트Gameplay 메서드
loadedonLoad / offLoad
openedonOpen / offOpen
closedonClose / offClose
unloadedonUnload / offUnload
failedonError / offError
rewardedonReward / offReward (보상형 전용)

opened 는 광고가 실제로 노출된 시점입니다.
open() 호출은 노출 요청일 뿐이므로, 두 시점을 같은 것으로 취급하면 노출 집계와 게임 일시정지 타이밍이 어긋납니다.

애드핏 은 현재 failed 리스너를 인자 없이 호출합니다.
onError 콜백의 error 파라미터는 항상 undefined 라고 보는 편이 안전합니다.

ts
const ad = await Gameplay.createInterstitialAd({
  adUnit: 'DAN-AbCdEfGhIjKl',
  ctag: {cp: 'my_game_001', channel: 'CHANNEL_ID'},
});

ad.onOpen(() => {
  console.log('광고 노출 확인');
});

ad.onUnload(() => {
  ad.destroy();
});

ad.onError(() => {
  console.log('광고 로드 또는 노출 실패');
});

ad.load();
ad.open();

UI ​

게임플레이 JS SDK는 managed UI를 SDK 번들 안에 포함합니다.
Gameplay.init() 을 호출하면 별도 스크립트를 추가로 로드하지 않아도 managed UI가 함께 준비되며, 기본적으로 활성 상태입니다.

navigation의 닫기 버튼, 더보기 메뉴, 이탈 확인 modal은 SDK가 managed UI로 제공하는 필수 범위입니다.
게임웹뷰에서 반복적으로 필요한 이 3가지 요소는 SDK가 전담하므로, 게임이 직접 만들지 않습니다.

managed UI를 직접 호출해야 하는 경우 Gameplay.UI 를 사용합니다.
컴포넌트별 네임스페이스 5개로 구성됩니다.

ts
type GameplayUiFacade = {
  Navigation: GameplayNavigationApi;
  Toast: GameplayToastApi;
  Modal: GameplayModalApi;
  BottomSheet: GameplayBottomSheetApi;
  Loader: GameplayLoaderApi;
};

각 컴포넌트의 옵션과 표시 정책은 UI 컴포넌트에서 다룹니다.

에러 ​

게임플레이 JS SDK의 메서드는 실패 시 예외를 throw합니다.
아래는 이 문서 전체에서 쓰는 에러 코드 목록과, 메서드별로 어떤 코드를 throw하는지 정리한 매핑입니다.

GameplaySdkError ​

ts
type GameplaySdkErrorCode =
  | 'SDK_NOT_INITIALIZED'
  | 'INVALID_INPUT'
  | 'KAKAO_NOT_AVAILABLE'
  | 'KAKAO_SHARE_NOT_AVAILABLE'
  | 'AD_SDK_NOT_AVAILABLE'
  | 'AD_INSTANCE_NOT_AVAILABLE'
  | 'BRIDGE_NOT_AVAILABLE'
  | 'BRIDGE_METHOD_NOT_AVAILABLE';

type GameplaySdkErrorLike = {
  name: string;
  code: GameplaySdkErrorCode;
  message: string;
  cause?: unknown;
};

게임플레이 JS SDK가 throw하는 에러는 Error를 상속한 하나의 타입으로 표준화되어 있습니다.
안정적인 분기 키인 code와 사람이 읽을 수 있는 message를 함께 담으며, 원인이 된 원본 에러(스크립트 로드 실패 이벤트 등)가 있으면 cause로 보존됩니다.

이 에러 클래스는 instanceof로 검사할 수 없습니다.
파트너사는 <script> 태그로 게임플레이 JS SDK를 로드해 Gameplay 객체만 사용하며, 에러 클래스 자체는 이 객체에 제공되지 않습니다.
아래처럼 code 값으로 분기해 주세요.

ts
function isGameplaySdkError(error: unknown): error is GameplaySdkErrorLike {
  return typeof error === 'object' && error !== null && 'code' in error && 'name' in error;
}

try {
  await Gameplay.haptic({mode: 'impact_light'});
} catch (error) {
  if (isGameplaySdkError(error) && error.code === 'BRIDGE_NOT_AVAILABLE') {
    // 게임웹뷰 밖에서 호출된 경우의 대체 처리
  } else {
    throw error;
  }
}

에러 코드 ​

코드의미발생 상황
SDK_NOT_INITIALIZEDinit() 이전에 다른 메서드를 호출init · isAvailable 을 제외한 모든 메서드
INVALID_INPUT입력 검증 실패talkShare(templateId 누락) · changeStatusBarColor(색상 형식) · resetWebViewHistory(http/https 외 스킴) · registerNativeHandler(예약·비식별자 이름)
KAKAO_NOT_AVAILABLE카카오 JS SDK 를 찾거나 로드하지 못함talkShare
KAKAO_SHARE_NOT_AVAILABLE카카오 JS SDK 는 있으나 Share.sendCustom 이 없음talkShare
AD_SDK_NOT_AVAILABLE카카오 애드핏 SDK(kakaoAdFit)를 찾거나 로드하지 못함광고 생성 2종
AD_INSTANCE_NOT_AVAILABLE광고 인스턴스 생성 실패 또는 destroy() 이후 조작광고 생성 2종, 광고 인스턴스 메서드
BRIDGE_NOT_AVAILABLE게임웹뷰 브리지 자체가 없음게임웹뷰 브리지에 의존하는 메서드
BRIDGE_METHOD_NOT_AVAILABLE브리지는 있으나 호출하려는 메서드가 없음게임웹뷰 브리지에 의존하는 메서드

BRIDGE_NOT_AVAILABLE 과 BRIDGE_METHOD_NOT_AVAILABLE 은 우선순위를 가집니다.
브리지 객체 자체가 없으면 항상 BRIDGE_NOT_AVAILABLE 이고, 브리지는 있으나 호출하려는 메서드만 없으면 BRIDGE_METHOD_NOT_AVAILABLE 입니다.

AD_SDK_NOT_AVAILABLE 의 발생 원인은 넷이며, 메시지로 구분됩니다.
어느 단계에서 멈췄는지가 대응을 가르므로 구분해 두었습니다.

  • 스크립트 로드 실패 (error 이벤트)
  • 스크립트 무응답: load · error 어느 쪽도 오지 않음 (광고 차단기, CSP 차단, 네트워크 stall)
  • 애드핏 초기화 미완료: window.kakaoAdFit 객체는 생성됐지만 광고 팩토리가 끝내 나타나지 않음
  • cmd 큐 미실행: 큐에 넣은 생성 콜백이 상한(5초) 내에 실행되지 않음

AD_INSTANCE_NOT_AVAILABLE 은 두 경우에서 발생합니다: 광고 생성 시점에 raw 인스턴스 생성 결과가 nullish인 경우, 그리고 destroy() 이후의 광고 인스턴스에 load() · open() · close() 를 호출하는 경우입니다.

메서드별 throw 매핑 ​

SDK_NOT_INITIALIZED 는 init · isAvailable 을 제외한 모든 메서드에서 init() 이전에 호출되면 공통으로 발생하므로, 아래 표에서는 생략합니다.
isAvailable 은 동기 함수이며 어떤 코드도 던지지 않으므로 표에서 제외합니다.
init 은 SDK_NOT_INITIALIZED 대상은 아니지만 별도 조건에서 KAKAO_NOT_AVAILABLE 을 던질 수 있어 아래 표에 포함합니다.

메서드throw 가능 코드
init(options)KAKAO_NOT_AVAILABLE
getSafeArea()BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
setOrientation(options)BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
setStatusBarOverlay(enable)BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
changeStatusBarColor(color?)INVALID_INPUT, BRIDGE_NOT_AVAILABLE
setScrollEnabled(enabled)BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
setBouncesEnabled(enabled)BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
setPullToRefreshEnabled(enabled)BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
setLinkPreviewEnabled(enabled)BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
setBackSwipeEnabled(enabled)BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
haptic(options)BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
startAccelerometer(options?)BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
stopAccelerometer()BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
close()BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
keepBrowser()BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
canGoBack()없음: throw 대신 반환값 false 로 알립니다
resetWebViewHistory(url)INVALID_INPUT, BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
setBackClickHandler(handler)없음: window.onBackClick에 직접 등록하는 방식이라 브리지에 의존하지 않습니다
getSoundState()BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
getNetworkState()BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
getDeviceInfo()없음: User-Agent 만 파싱하므로 어떤 환경에서도 throw하지 않습니다
onTalkEventMessage(handler, options?)INVALID_INPUT, BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
registerNativeHandler(handlerName, handler)INVALID_INPUT, BRIDGE_NOT_AVAILABLE, BRIDGE_METHOD_NOT_AVAILABLE
talkShare(options)INVALID_INPUT, KAKAO_NOT_AVAILABLE, KAKAO_SHARE_NOT_AVAILABLE
createInterstitialAd(options)AD_SDK_NOT_AVAILABLE, AD_INSTANCE_NOT_AVAILABLE
createRewardedInterstitialAd(options)AD_SDK_NOT_AVAILABLE, AD_INSTANCE_NOT_AVAILABLE

init(options) 은 clientKey 를 지정했거나 window.Kakao 객체가 이미 로드되어 있을 때만 카카오 JS SDK 를 로드하며, 이 로드가 실패하거나 응답이 없으면 KAKAO_NOT_AVAILABLE 로 reject됩니다.
그 외 조건(둘 다 없는 경우)에서는 이 경로를 타지 않아 throw하지 않습니다.
광고 SDK 선로드 실패, webview 옵션 적용 실패, 안전영역·상태바 오버레이 조회 실패는 각각 내부에서 처리되어 init() 을 막지 않습니다.

canGoBack() 은 게임웹뷰 브리지가 없거나 지원하지 않아도 예외를 던지지 않고 false 를 반환합니다.
try/catch 가 아니라 반환값 분기로 처리해 주세요.

changeStatusBarColor(color?) 는 게임웹뷰 브리지가 실패하면 iOS · Android 공통 브리지로 순차 폴백하므로, 브리지 자체가 모두 없을 때만 BRIDGE_NOT_AVAILABLE 을 throw합니다.
BRIDGE_METHOD_NOT_AVAILABLE 은 발생하지 않습니다.

부록: 네이티브 브리지 대조 ​

이 문서는 레퍼런스를 화면·제스처·상태 조회 같은 파트너 관심사 기준으로 재편했기 때문에, 네이티브 게임웹뷰 SDK 문서와 항목 순서가 1:1로 대응하지 않습니다.
기존 게임웹뷰 SDK 문서에서 옮겨오는 파트너사를 위해 이 표가 대조 경로를 복원합니다.

대부분의 메서드는 window.kakaotalkGamePlay.{같은 이름} 으로 1:1 대응합니다.
아래 표에는 이름이나 형태가 달라지는 메서드만 남겼습니다.

Gameplay 메서드네이티브 대응
setStatusBarOverlay(enable)window.kakaotalkGamePlay.setStatusBarOverlay({enable}): boolean 이 아니라 {enable} 객체를 받습니다
setBackClickHandler(handler)window.onBackClick = handler (Android): 브리지 메서드 호출이 아니라 window 객체에 직접 등록하는 방식입니다
canGoBack()iOS 는 window.kakaotalk.canGoBack() 을 먼저 시도하고 없으면 window.webview.canGoBack() 으로, Android 는 반대 순서로 시도합니다
changeStatusBarColor(color?)window.kakaotalkGamePlay.changeStatusBarColor 를 우선 시도하고, 없으면 iOS window.kakaotalk.changeBackgroundColor · Android window.webview.changeStatusBarColor 로 폴백합니다
talkShare(options)window.Kakao.Share.sendCustom(options): 게임웹뷰 브리지가 아니라 카카오 JS SDK 호출입니다
createInterstitialAd(options)window.kakaoAdFit.createInterstitialAd(adUnit, options): 옵션 객체 하나가 아니라 adUnit 과 나머지 옵션을 분리한 두 인자로 받습니다
createRewardedInterstitialAd(options)window.kakaoAdFit.createRewardedInterstitialAd(adUnit, options): 형태 차이는 createInterstitialAd 항목과 같습니다
getDeviceInfo()대응하는 네이티브 브리지가 없습니다: navigator.userAgent 파싱으로 자체 판별합니다

getStatusBarOverlay() 는 JS SDK 에 없습니다.
기존 게임웹뷰 SDK 문서에는 26.6.0+ 로 존재하지만, JS SDK 는 이 조회를 init 내부에서 managed UI 초기 상태를 잡는 데만 쓰고 별도 공개 메서드로 노출하지 않습니다.
상태바 오버레이의 현재 값을 직접 조회해야 하면 데브톡으로 문의해 주세요.

참고 문서 ​