-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsend-push.ts
More file actions
121 lines (103 loc) · 2.54 KB
/
Copy pathsend-push.ts
File metadata and controls
121 lines (103 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import "server-only";
import { cert, getApps, initializeApp } from "firebase-admin/app";
import { getMessaging } from "firebase-admin/messaging";
type PushPayload = {
title: string;
message: string;
type: string;
redirect: string;
groupId?: string | null;
createdBy?: string | null;
};
const FIREBASE_SERVICE_ACCOUNT_JSON = process.env.FIREBASE_SERVICE_ACCOUNT_JSON;
const FIREBASE_SERVICE_ACCOUNT_BASE64 =
process.env.FIREBASE_SERVICE_ACCOUNT_BASE64;
let warnedMissingConfig = false;
function parseServiceAccount(): {
projectId: string;
clientEmail: string;
privateKey: string;
} | null {
let raw = FIREBASE_SERVICE_ACCOUNT_JSON?.trim();
if (!raw && FIREBASE_SERVICE_ACCOUNT_BASE64) {
raw = Buffer.from(FIREBASE_SERVICE_ACCOUNT_BASE64, "base64").toString(
"utf8",
);
}
if (!raw) return null;
try {
const parsed = JSON.parse(raw) as {
project_id?: string;
client_email?: string;
private_key?: string;
};
if (!parsed.project_id || !parsed.client_email || !parsed.private_key) {
return null;
}
return {
projectId: parsed.project_id,
clientEmail: parsed.client_email,
privateKey: parsed.private_key,
};
} catch {
return null;
}
}
function getOrInitFirebaseMessaging() {
if (getApps().length > 0) {
return getMessaging();
}
const serviceAccount = parseServiceAccount();
if (!serviceAccount) {
if (!warnedMissingConfig) {
console.warn(
"Push notifications are disabled: missing Firebase service account configuration.",
);
warnedMissingConfig = true;
}
return null;
}
const app = initializeApp({
credential: cert(serviceAccount),
});
return getMessaging(app);
}
function topicForUser(userId: string) {
return `user_${userId}`;
}
export async function sendPushToUsers(userIds: string[], payload: PushPayload) {
if (userIds.length === 0) return;
const messaging = getOrInitFirebaseMessaging();
if (!messaging) return;
const sendResults = await Promise.allSettled(
userIds.map((userId) =>
messaging.send({
topic: topicForUser(userId),
notification: {
title: payload.title,
body: payload.message,
},
data: {
type: payload.type,
redirect: payload.redirect,
title: payload.title,
message: payload.message,
groupId: payload.groupId ?? "",
createdBy: payload.createdBy ?? "",
},
apns: {
payload: {
aps: {
sound: "default",
},
},
},
}),
),
);
for (const result of sendResults) {
if (result.status === "rejected") {
console.error("Failed to send push notification:", result.reason);
}
}
}