← 전체 가이드

푸시 알림

푸시 알림 연동 가이드

Hibira Push로 iOS, Android, 브라우저에 알림을 보내세요. API는 Beams와 호환되어 공식 Beams 서버 SDK는 엔드포인트만 지정하면 동작하고, 저희 클라이언트 SDK는 호스트를 설정할 수 있게 만든 Beams SDK의 포크입니다.

로그인하면 스니펫이 내 엔드포인트로 바뀌고, 앱 페이지에서는 인스턴스 ID도 채워집니다. 로그인

동작 방식

  • 포털의 앱 페이지에서 푸시 알림을 켜면 인스턴스 ID, 시크릿 키, 엔드포인트가 발급됩니다.
  • 각 기기나 브라우저는 클라이언트 SDK로 등록하고 news, order-1024 같은 주제인 관심사(interest)를 구독합니다. 서버는 관심사로 발송하고, 기기가 로그인한 사용자와 연결되면 사용자 ID로도 발송할 수 있습니다.
  • 인스턴스 ID와 엔드포인트는 앱에 넣습니다. 시크릿 키는 모든 기기에 발송할 수 있으므로 서버의 HIBIRA_PUSH_SECRET_KEY 환경 변수에만 두고, 앱이나 저장소에는 절대 넣지 마세요.
  • 푸시는 모든 플랜에 포함됩니다. 플랜에 따라 등록할 수 있는 기기와 브라우저 수, 발송 속도가 정해집니다.

1. 자격 증명 업로드

Apple (APNs)
Apple Developer의 Certificates, Identifiers & Profiles › Keys에서 Apple Push Notifications service(APNs)를 켠 키를 만들고 .p8 파일을 내려받으세요. 앱 페이지의 푸시 알림 › Apple(APNs)에서 키 ID, 팀 ID, 앱의 번들 ID를 입력하고 환경을 고른 뒤 .p8 파일을 업로드하세요. Xcode에서 실행하는 빌드는 개발(샌드박스), TestFlight와 App Store 빌드는 프로덕션을 선택하세요.
Android (FCM)
Firebase 콘솔에서 프로젝트 설정 › 서비스 계정을 열고 새 비공개 키 생성을 클릭하세요. JSON 파일을 푸시 알림 › Android(FCM)에 업로드하고, 같은 프로젝트의 google-services.json을 Android 앱에 추가하세요.
Web Push
업로드할 것이 없습니다. VAPID 키는 푸시를 켤 때 만들어집니다. 사이트는 HTTPS로 제공해야 합니다(개발 중에는 localhost도 됩니다).

키와 서비스 계정은 암호화해 저장하며 다시 표시되지 않습니다.

2. 기기와 브라우저 등록

클라이언트 SDK

플랫폼

Chrome, Edge, Firefox, Opera, Safari 16.4 이상에서 표준 Web Push와 서비스 워커로 동작합니다. @hibira-io/push-web ↗

  1. 설치

    npm install @hibira-io/push-web
  2. 서비스 워커 추가

    // public/service-worker.js, served at https://your-site/service-worker.js
    importScripts('https://cdn.jsdelivr.net/npm/@hibira-io/push-web@1/dist/service-worker.js');
    self.HibiraPush.endpoint = 'https://ws.hibira.io';
  3. 브라우저 등록

    import { Client } from '@hibira-io/push-web';
    
    const push = new Client({
      instanceId: 'YOUR_INSTANCE_ID',
      endpoint: 'https://ws.hibira.io',
    });
    
    // Browsers only show the permission prompt after a click or tap.
    document.querySelector('#enable-notifications').addEventListener('click', async () => {
      await push.start();
      await push.addDeviceInterest('hello');
    });
  4. 로그인한 사용자 연결

    import { TokenProvider } from '@hibira-io/push-web';
    
    // After sign-in. Your backend answers GET /push/user-token?user_id=... (see the server guide).
    await push.setUserId(currentUser.id, new TokenProvider({ url: '/push/user-token' }));
    
    // On sign-out, so the next person on this browser doesn't get their notifications.
    await push.stop();
Web용 에이전트 프롬프트

Claude Code, Cursor, GitHub Copilot 등 AI 코딩 에이전트에 붙여 넣으세요. 인스턴스 ID와 엔드포인트가 들어 있고, 시크릿 키는 환경 변수로 남습니다.

Add Hibira push notifications to this Web project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the Hibira client SDK (here: @hibira-io/push-web, https://github.com/hibira-io/hibira-push-web).

Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- No secret key: it belongs on the server, never in this app

What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Install @hibira-io/push-web (it replaces @pusher/push-notifications-web; the API is the same apart from the import and the endpoint option).
3. Serve service-worker.js from the site root (for example public/service-worker.js in Vite, Next.js or Create React App) with the importScripts line and the endpoint from the reference.
4. Create one shared push client module and call start() from a user action such as an "Enable notifications" button, never on page load: browsers block permission prompts that are not triggered by a click.
5. If the app has signed-in users, call setUserId with a TokenProvider pointing at the backend token endpoint after sign-in, and stop() on sign-out.
6. Web Push needs HTTPS (localhost is fine for development); on iPhone and iPad it works only once the site is added to the Home Screen.
7. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent).
8. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
9. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
10. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
11. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.

Reference setup from the Hibira push notifications guide (adapt it to the project's structure):

Install:

```shell
npm install @hibira-io/push-web
```

Add the service worker:

```js
// public/service-worker.js, served at https://your-site/service-worker.js
importScripts('https://cdn.jsdelivr.net/npm/@hibira-io/push-web@1/dist/service-worker.js');
self.HibiraPush.endpoint = 'https://ws.hibira.io';
```

Register the browser:

```js
import { Client } from '@hibira-io/push-web';

const push = new Client({
  instanceId: 'YOUR_INSTANCE_ID',
  endpoint: 'https://ws.hibira.io',
});

// Browsers only show the permission prompt after a click or tap.
document.querySelector('#enable-notifications').addEventListener('click', async () => {
  await push.start();
  await push.addDeviceInterest('hello');
});
```

Link the signed-in user:

```js
import { TokenProvider } from '@hibira-io/push-web';

// After sign-in. Your backend answers GET /push/user-token?user_id=... (see the server guide).
await push.setUserId(currentUser.id, new TokenProvider({ url: '/push/user-token' }));

// On sign-out, so the next person on this browser doesn't get their notifications.
await push.stop();
```

3. 서버에서 발송

서버 SDK

언어

공식 Beams 서버 SDK를 엔드포인트로 지정해 Node.js에서 발송합니다. @pusher/push-notifications-server ↗

  1. 설치

    npm install @pusher/push-notifications-server
  2. 관심사에 발송

    const PushNotifications = require('@pusher/push-notifications-server');
    
    const beams = new PushNotifications({
      instanceId: 'YOUR_INSTANCE_ID',
      secretKey: process.env.HIBIRA_PUSH_SECRET_KEY,
      endpoint: 'ws.hibira.io',
    });
    beams.protocol = 'https'; // the SDK switches to http when an endpoint is set
    
    await beams.publishToInterests(['hello'], {
      apns: { aps: { alert: { title: 'Hello', body: 'Hello, world!' } } },
      fcm: { notification: { title: 'Hello', body: 'Hello, world!' } },
      web: { notification: { title: 'Hello', body: 'Hello, world!', deep_link: 'https://your-site.example/' } },
    });
  3. 사용자 토큰 엔드포인트 추가

    // Express: the client SDKs call GET /push/user-token?user_id=...
    app.get('/push/user-token', requireLogin, (req, res) => {
      if (req.query.user_id !== String(req.user.id)) return res.sendStatus(401);
      res.json(beams.generateToken(String(req.user.id))); // { token: '...' }
    });
  4. 로그인한 사용자에게 발송

    await beams.publishToUsers(['user-1'], {
      apns: { aps: { alert: { title: 'Order shipped', body: 'Order #1024 is on its way.' } } },
      fcm: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } },
      web: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } },
    });
Node.js용 에이전트 프롬프트

Claude Code, Cursor, GitHub Copilot 등 AI 코딩 에이전트에 붙여 넣으세요. 인스턴스 ID와 엔드포인트가 들어 있고, 시크릿 키는 환경 변수로 남습니다.

Add Hibira push notifications to this Node.js project. Hibira Push sends to iOS (APNs), Android (FCM) and browsers (Web Push) through a Beams-compatible API, so it works with the official Beams server SDKs pointed at the Hibira endpoint (here: @pusher/push-notifications-server, https://github.com/pusher/push-notifications-node).

Connection details:
- Instance ID: YOUR_INSTANCE_ID
- Endpoint: https://ws.hibira.io
- Secret key: read it from the HIBIRA_PUSH_SECRET_KEY environment variable (server-side only)

What to do:
1. Look at the project first (framework version, package manager, config and env conventions, where similar integrations live) and follow what it already does.
2. Create one shared module that builds the PushNotifications client from environment variables, with the endpoint option and beams.protocol set as in the reference (without them the SDK talks to pusher.com, or to the endpoint over plain http).
3. If the app has signed-in users, add the token route behind the project's existing authentication middleware; it must refuse a user_id that is not the signed-in user's.
4. Publish from the places that should notify (jobs, controllers, event handlers) through the shared module, and log the publish ID it returns.
5. Read the instance ID and endpoint from the project's config or environment, and add placeholder entries to .env.example (or its equivalent). Never commit the secret key or send it to a browser or mobile app.
6. Always set the endpoint above. The Pusher Beams SDKs and their defaults point at pusher.com.
7. If YOUR_INSTANCE_ID above is still a placeholder, keep it as a config placeholder and tell me where to fill it in rather than inventing a value.
8. Subscribe test devices to the "hello" interest so the portal's Send a test reaches them.
9. When you are done, list the files you changed and tell me how to check it works: on the Hibira portal app page, Push notifications › Send a test to the hello interest.

Reference setup from the Hibira push notifications guide (adapt it to the project's structure):

Install:

```shell
npm install @pusher/push-notifications-server
```

Publish to an interest:

```js
const PushNotifications = require('@pusher/push-notifications-server');

const beams = new PushNotifications({
  instanceId: 'YOUR_INSTANCE_ID',
  secretKey: process.env.HIBIRA_PUSH_SECRET_KEY,
  endpoint: 'ws.hibira.io',
});
beams.protocol = 'https'; // the SDK switches to http when an endpoint is set

await beams.publishToInterests(['hello'], {
  apns: { aps: { alert: { title: 'Hello', body: 'Hello, world!' } } },
  fcm: { notification: { title: 'Hello', body: 'Hello, world!' } },
  web: { notification: { title: 'Hello', body: 'Hello, world!', deep_link: 'https://your-site.example/' } },
});
```

Add the user token endpoint:

```js
// Express: the client SDKs call GET /push/user-token?user_id=...
app.get('/push/user-token', requireLogin, (req, res) => {
  if (req.query.user_id !== String(req.user.id)) return res.sendStatus(401);
  res.json(beams.generateToken(String(req.user.id))); // { token: '...' }
});
```

Publish to a signed-in user:

```js
await beams.publishToUsers(['user-1'], {
  apns: { aps: { alert: { title: 'Order shipped', body: 'Order #1024 is on its way.' } } },
  fcm: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } },
  web: { notification: { title: 'Order shipped', body: 'Order #1024 is on its way.' } },
});
```

4. 로그인한 사용자

한 사람이 쓰는 모든 기기로 보내려면 각 기기를 자체 사용자 ID에 연결하세요. 클라이언트 SDK는 ?user_id=…를 붙여 토큰 엔드포인트를 호출하고, 엔드포인트는 요청이 그 로그인한 사용자에게서 왔는지 확인한 뒤 시크릿 키로 generateToken이 만든 토큰을 돌려줍니다(모든 Beams 서버 SDK에 있습니다). 그다음 관심사 대신 사용자 ID로 발송하세요. 사용자를 삭제하면 그 사용자의 모든 기기 연결이 해제됩니다.

사용자가 로그아웃하면 stop을 호출해, 같은 기기의 다음 사용자가 그 사람의 알림을 받지 않게 하세요.

5. 테스트 전송

앱 페이지의 푸시 알림 › 테스트 전송에서 관심사(위 스니펫에서는 hello), 제목, 본문을 입력하고 테스트 전송을 클릭하세요. 그 관심사를 구독한 기기에 몇 초 안에 도착하며, 구독자 미터에 등록된 기기와 브라우저 수가 표시됩니다.

문제 해결

기기나 브라우저가 구독자에 나타나지 않음
클라이언트가 이 앱의 인스턴스 ID와 엔드포인트로 start를 호출하는지, 사용자가 알림을 허용했는지 확인하세요. Android에서는 google-services.json이 업로드한 서비스 계정과 같은 Firebase 프로젝트의 것이어야 합니다.
iPhone과 iPad에 아무것도 오지 않음
APNs 환경은 빌드와 일치해야 합니다. Xcode에서 실행한 빌드는 개발(샌드박스), TestFlight와 App Store는 프로덕션입니다. 번들 ID가 앱과 정확히 같아야 하고, 앱 타깃에 Push Notifications 기능이 켜져 있어야 합니다.
start()가 “service worker missing”으로 실패함
/service-worker.js를 사이트 루트에 두고 HTTPS로 제공하며, 웹 가이드의 importScripts 줄을 넣으세요. 하위 폴더의 서비스 워커는 그 폴더만 제어합니다.
iPhone의 Safari가 권한을 묻지 않음
iOS·iPadOS 16.4 이상의 Web Push는 사이트를 홈 화면에 추가한 뒤에만 동작하며, 권한 요청은 탭으로 시작해야 합니다.
서버 SDK가 여전히 pusher.com에 연결하거나 http로 실패함
endpoint 옵션을 설정하세요. Node.js SDK는 beams.protocol = 'https'도 필요하고, Go SDK는 WithCustomBaseURL을 사용합니다.
발송이 401을 반환함
서버가 잘못된 시크릿 키나 유예 기간이 지난 교체 전 키를 쓰고 있습니다. 앱 페이지에서 현재 키를 복사하세요.
발송이 429를 반환함
플랜이 허용하는 것보다 빠르게 발송하고 있습니다. Retry-After만큼 기다리고, 하나씩 요청하는 대신 한 번의 발송에 관심사 최대 100개 또는 사용자 최대 1,000명을 지정하세요.
기기 등록이 402를 반환함
앱이 플랜의 구독자 한도에 도달했습니다. 플랜을 업그레이드하거나, 떠난 사용자를 삭제해 그 기기를 제거하세요.
setUserId가 실패함
토큰 엔드포인트는 요청받은 user_id에 대해 이 앱의 시크릿 키로 generateToken이 반환한 JSON을 200으로 응답해야 합니다. 다른 사용자와 연결된 기기는 먼저 stop을 호출해야 합니다.

Pusher Beams에서 옮겨 오시나요? 클라이언트 SDK 패키지를 저희 것으로 바꾸고, 서버 SDK에 엔드포인트를 설정하고, APNs 키와 FCM 서비스 계정을 업로드한 뒤, 사용자가 앱을 업데이트할 때까지 두 서비스 모두로 발송하세요. 기기는 처음 시작할 때 다시 등록됩니다. Pusher에서 이전하기 →