콘텐츠로 이동

Notification

Electron Notification 호환 — macOS UNUserNotificationCenter (NSUserNotification은 deprecated 후 macOS 26 제거), Linux freedesktop notification D-Bus, Windows Shell_NotifyIconW balloon notification. Frontend JS + Zig/Rust/Go/Node 백엔드 SDK 모두 노출.

APImacOSLinuxWindows
notification.isSupported✅ Bundle ID 있을 때만 true✅ notification daemon probe✅ true (Shell_NotifyIcon balloon)
notification.requestPermission✅ OS 다이얼로그✅ daemon reachable (no prompt)✅ true (권한 프롬프트 없음)
notification.show✅ UNUserNotificationCenter✅ D-Bus NotifyNIF_INFO balloon
notification.close✅ pending + delivered✅ D-Bus CloseNotification✅ backing tray icon 제거
Click eventnotification:click✅ balloon click

Linux는 org.freedesktop.Notifications 서비스가 없으면 graceful false. Windows는 WinRT XML toast가 아니라 Shell notification balloon 경로다. Windows 10+에서는 OS가 balloon을 toast UI처럼 렌더링하지만 action button/reply/custom image는 지원하지 않는다.

⚠️ macOS Bundle ID 필수 (dev 모드 한계)

섹션 제목: “⚠️ macOS Bundle ID 필수 (dev 모드 한계)”

UNUserNotificationCentervalid Bundle ID + Info.plist 필요. suji dev로 실행하면 binary가 loose라 Bundle ID 없음 → isSupported() false 반환 + 알림 안 뜸.

정상 동작 조건:

  • suji build.app 번들 생성 (Info.plist에 CFBundleIdentifier 자동 포함)
  • 또는 Info.plist 수동 작성 + 코드사인

dev 모드에서:

  • isSupported() → false
  • show()success: false (notification 안 뜸)
  • 실제 알림 표시는 .app 번들로 빌드한 후 확인한다.
미지원비고
Actions / 버튼코어 notification에는 없음. 공식 notification-rich 플러그인은 macOS/Linux action click 라우팅을 지원한다. Windows에서는 action 버튼 클릭 콜백이 아직 지원되지 않는다.
Reply inputmacOS/Windows native reply input은 지원하지 않는다.
커스텀 iconmacOS는 앱 아이콘만 자동 표시되고, iconPath/attachment는 지원하지 않는다.
커스텀 soundsilent: true로 소리를 끌 수 있다. 커스텀 사운드 파일은 지원하지 않는다.
import { notification } from '@suji/api';
// 플랫폼 + Bundle ID 검사
const supported = await notification.isSupported();
if (!supported) {
console.warn('Notifications require a bundled app (.app)');
return;
}
// 권한 요청 — 첫 호출만 OS 다이얼로그
const granted = await notification.requestPermission();
if (!granted) return;
// 알림 표시
const { notificationId, success } = await notification.show({
title: 'Build complete',
body: 'Your project compiled successfully.',
silent: false,
});
// 클릭 수신
suji.on('notification:click', ({ notificationId: clickedId }) => {
if (clickedId === notificationId) {
// bring main window forward etc.
}
});
// 명시 close (자동 dismiss 외에)
await notification.close(notificationId);
const sup = suji.notification.isSupported();
const grant = suji.notification.requestPermission();
const show = suji.notification.show("Title", "Body", false);
_ = suji.notification.close("suji-notif-1");
let sup = suji::notification::is_supported();
let grant = suji::notification::request_permission();
let show = suji::notification::show("Title", "Body", false);
let _ = suji::notification::close("suji-notif-1");
import "github.com/ohah/suji-go/notification"
notification.IsSupported()
notification.RequestPermission()
notification.Show("Title", "Body", false)
notification.Close("suji-notif-1")
import { notification } from '@suji/node';
const supported = await notification.isSupported();
const granted = await notification.requestPermission();
const { notificationId } = await notification.show({ title: 'Hi', body: 'World' });
await notification.close(notificationId);

UNUserNotificationCenter를 사용한다. silent: true면 소리 없이 표시된다. foreground 상태에서도 banner를 표시한다. Bundle ID가 없으면(dev 모드) isSupported()가 false를 반환하고 알림이 뜨지 않는다. close()는 pending 및 delivered 알림 모두 제거한다.

org.freedesktop.Notifications D-Bus 서비스가 있을 때 Notify 호출로 알림을 표시한다. freedesktop spec에는 권한 프롬프트가 없어 requestPermission()은 서비스 도달 가능 여부를 반환한다. silent: truesuppress-sound hint를 전달한다. action button이 필요하면 공식 notification-rich 플러그인을 사용한다.

Shell_NotifyIcon balloon 경로를 사용한다. Windows 10+에서는 OS가 balloon을 toast UI처럼 렌더링한다. silent: true면 소리 없이 표시된다. 사용자가 balloon을 클릭하면 notification:click 이벤트가 발화된다. action button/reply/custom image는 지원하지 않는다.

macOS에서 알림의 실제 표시와 클릭 동작은 .app 번들로 빌드한 뒤 권한을 허용한 상태에서만 확인할 수 있다.