푸시 (Push)
iOS(APNS), Android(FCM), Web Push를 지원하는 통합 푸시 알림 API입니다.
디바이스 등록
iOS/Android 디바이스 등록
typescript
// iOS 디바이스 등록 (APNS)
const device = await cb.push.registerDevice({
device_token: 'apns-device-token-here',
platform: 'ios',
device_name: 'iPhone 15 Pro',
device_model: 'iPhone15,2',
os_version: '17.0',
app_version: '1.0.0',
language: 'ko',
timezone: 'Asia/Seoul'
})
// Android 디바이스 등록 (FCM)
const device = await cb.push.registerDevice({
device_token: 'fcm-registration-token-here',
platform: 'android',
device_name: 'Galaxy S24',
device_model: 'SM-S928N',
os_version: '14',
app_version: '1.0.0'
})파라미터
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
device_token | string | ✅ | APNS/FCM 토큰 |
platform | 'ios' | 'android' | 'web' | ✅ | 디바이스 플랫폼 |
device_id | string | ❌ | 디바이스 고유 ID |
device_name | string | ❌ | 디바이스 이름 |
device_model | string | ❌ | 디바이스 모델 |
os_version | string | ❌ | OS 버전 |
app_version | string | ❌ | 앱 버전 |
language | string | ❌ | 언어 코드 (예: "ko") |
timezone | string | ❌ | 타임존 (예: "Asia/Seoul") |
디바이스 관리
typescript
// 디바이스 등록 해제 (등록 시 사용한 device_token 그대로 전달)
await cb.push.unregisterDevice('apns-or-fcm-device-token')📌 SDK는
getDevices()/getSubscribedTopics()메서드를 제공하지 않습니다. 디바이스/토픽 목록은 콘솔이나 REST API 를 사용하세요.
토픽 구독
토픽을 사용하면 특정 그룹에만 푸시 알림을 보낼 수 있습니다. 디바이스 단위로 구독합니다.
typescript
const deviceToken = 'apns-or-fcm-device-token'
// 토픽 구독
await cb.push.subscribeTopic(deviceToken, 'announcements')
await cb.push.subscribeTopic(deviceToken, 'marketing')
// 토픽 구독 해제
await cb.push.unsubscribeTopic(deviceToken, 'marketing')Web Push (브라우저 푸시)
브라우저에서 푸시 알림을 받으려면 Service Worker와 VAPID 키를 사용합니다.
VAPID 키 조회 및 구독 등록
typescript
// 1. VAPID 공개키 조회
const vapidKey = await cb.push.getVAPIDPublicKey()
// 2. Service Worker 등록 및 Push 구독
const registration = await navigator.serviceWorker.register('/sw.js')
await navigator.serviceWorker.ready
const permission = await Notification.requestPermission()
if (permission === 'granted') {
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(vapidKey.public_key)
})
// 3. Connect Base에 구독 정보 등록
await cb.push.registerWebPush(subscription)
console.log('Web Push 등록 완료!')
}Web Push 구독 해제
typescript
// 등록 시 받은 device_token 을 그대로 전달
await cb.push.unregisterWebPush(deviceToken)Base64 변환 헬퍼 함수
typescript
function urlBase64ToUint8Array(base64String: string): Uint8Array {
const padding = '='.repeat((4 - base64String.length % 4) % 4)
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/')
const rawData = window.atob(base64)
const outputArray = new Uint8Array(rawData.length)
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i)
}
return outputArray
}Service Worker 예제
javascript
// sw.js
self.addEventListener('push', (event) => {
const data = event.data?.json() || {}
const options = {
body: data.body || '새 알림이 있습니다',
icon: data.icon || '/icon-192.png',
badge: data.badge || '/badge-72.png',
image: data.image,
data: data.data,
actions: data.actions || []
}
event.waitUntil(
self.registration.showNotification(data.title || '알림', options)
)
})
// 알림 클릭 처리
self.addEventListener('notificationclick', (event) => {
event.notification.close()
const url = event.notification.data?.url || '/'
event.waitUntil(clients.openWindow(url))
})API 레퍼런스
| 메서드 | 설명 | 반환 타입 |
|---|---|---|
registerDevice(request) | 디바이스 등록 | Promise<DeviceInfo> |
unregisterDevice(deviceToken) | 디바이스 해제 | Promise<void> |
subscribeTopic(deviceToken, topicName) | 토픽 구독 | Promise<void> |
unsubscribeTopic(deviceToken, topicName) | 토픽 구독 해제 | Promise<void> |
getVAPIDPublicKey() | VAPID 공개키 조회 | Promise<VAPIDPublicKeyResponse> |
registerWebPush(subscription) | Web Push 등록 | Promise<DeviceInfo> |
unregisterWebPush(deviceToken) | Web Push 해제 | Promise<void> |
DeviceInfo 응답 타입
typescript
interface DeviceInfo {
id: string // 디바이스 고유 ID
device_token: string // APNS/FCM/Web Push 토큰
platform: 'ios' | 'android' | 'web'
device_id?: string // 사용자 지정 디바이스 ID
device_name?: string // 디바이스 이름
device_model?: string // 디바이스 모델
os_version?: string // OS 버전
app_version?: string // 앱 버전
language?: string // 언어
timezone?: string // 타임존
is_active: boolean // 활성 상태
last_active_at?: string // 마지막 활성 시간
created_at: string // 등록 시간
updated_at: string // 수정 시간
}