feat(ntfy): Phase 2 — sendPushToUsers() ntfy 연동 + 구독 관리 UI
- ntfy_subscriptions 테이블 마이그레이션 추가 - ntfySender.js 유틸 (ntfy HTTP POST 래퍼) - sendPushToUsers() ntfy 우선 분기 (ntfy 구독자 → ntfy, 나머지 → Web Push) - ntfy subscribe/unsubscribe/status API 엔드포인트 - notification-bell.js ntfy 토글 버튼 + 앱 설정 안내 모달 - docker-compose system1-api에 NTFY 환경변수 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
31
system1-factory/api/utils/ntfySender.js
Normal file
31
system1-factory/api/utils/ntfySender.js
Normal file
@@ -0,0 +1,31 @@
|
||||
// utils/ntfySender.js — ntfy HTTP POST 래퍼
|
||||
const NTFY_BASE_URL = process.env.NTFY_BASE_URL || 'http://ntfy:80';
|
||||
const NTFY_PUBLISH_TOKEN = process.env.NTFY_PUBLISH_TOKEN;
|
||||
const TKFB_BASE_URL = process.env.TKFB_BASE_URL || 'https://tkfb.technicalkorea.net';
|
||||
|
||||
async function sendNtfy(userId, { title, body, url }) {
|
||||
if (!NTFY_PUBLISH_TOKEN) return;
|
||||
|
||||
const topic = `tkfactory-user-${userId}`;
|
||||
const headers = {
|
||||
'Authorization': `Bearer ${NTFY_PUBLISH_TOKEN}`,
|
||||
'Title': title || '',
|
||||
'Tags': 'bell',
|
||||
};
|
||||
if (url) {
|
||||
headers['Click'] = url.startsWith('http') ? url : `${TKFB_BASE_URL}${url}`;
|
||||
}
|
||||
|
||||
try {
|
||||
const resp = await fetch(`${NTFY_BASE_URL}/${topic}`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: body || '',
|
||||
});
|
||||
if (!resp.ok) console.warn(`[ntfy] ${userId} 발송 실패: ${resp.status}`);
|
||||
} catch (e) {
|
||||
console.error(`[ntfy] ${userId} 발송 오류:`, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { sendNtfy };
|
||||
Reference in New Issue
Block a user