push增加详细消息
This commit is contained in:
+70
-6
@@ -27,6 +27,18 @@ type PushDeliverySummary = {
|
||||
failedCount: number;
|
||||
};
|
||||
|
||||
type PushFailureDetail = {
|
||||
endpointHost: string;
|
||||
statusCode: number | null;
|
||||
message: string;
|
||||
body: string | null;
|
||||
reason: string | null;
|
||||
};
|
||||
|
||||
type PushDeliveryResult = PushDeliverySummary & {
|
||||
failureDetails?: PushFailureDetail[];
|
||||
};
|
||||
|
||||
const APP_BASE_URL = (
|
||||
process.env.NEXT_PUBLIC_APP_URL || "https://digital-human.xn--876a.net"
|
||||
).replace(/\/+$/, "");
|
||||
@@ -133,10 +145,53 @@ export async function removePushSubscription(input: {
|
||||
});
|
||||
}
|
||||
|
||||
function getEndpointHost(endpoint: string) {
|
||||
try {
|
||||
return new URL(endpoint).host;
|
||||
} catch {
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
function getPushFailureDetail(subscription: StoredPushSubscription, error: unknown) {
|
||||
const statusCode =
|
||||
error && typeof error === "object" && "statusCode" in error
|
||||
? Number((error as { statusCode?: number }).statusCode)
|
||||
: null;
|
||||
const message =
|
||||
error && typeof error === "object" && "message" in error
|
||||
? String((error as { message?: string }).message || "推送发送失败")
|
||||
: "推送发送失败";
|
||||
const body =
|
||||
error && typeof error === "object" && "body" in error
|
||||
? String((error as { body?: string }).body || "") || null
|
||||
: null;
|
||||
|
||||
let reason: string | null = null;
|
||||
|
||||
if (body) {
|
||||
try {
|
||||
const parsedBody = JSON.parse(body) as { reason?: unknown };
|
||||
reason = typeof parsedBody.reason === "string" ? parsedBody.reason : null;
|
||||
} catch {
|
||||
reason = null;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
endpointHost: getEndpointHost(subscription.endpoint),
|
||||
statusCode,
|
||||
message,
|
||||
body,
|
||||
reason,
|
||||
} satisfies PushFailureDetail;
|
||||
}
|
||||
|
||||
async function deliverPushToSubscriptions(input: {
|
||||
subscriptions: StoredPushSubscription[];
|
||||
payload: string;
|
||||
topic: string;
|
||||
collectFailureDetails?: boolean;
|
||||
}) {
|
||||
if (input.subscriptions.length === 0) {
|
||||
return {
|
||||
@@ -144,11 +199,14 @@ async function deliverPushToSubscriptions(input: {
|
||||
sentCount: 0,
|
||||
removedCount: 0,
|
||||
failedCount: 0,
|
||||
} satisfies PushDeliverySummary;
|
||||
failureDetails: [],
|
||||
} satisfies PushDeliveryResult;
|
||||
}
|
||||
|
||||
ensureVapidDetails();
|
||||
|
||||
const failureDetails: PushFailureDetail[] = [];
|
||||
|
||||
const results = await Promise.all(
|
||||
input.subscriptions.map(async (subscription) => {
|
||||
try {
|
||||
@@ -171,10 +229,14 @@ async function deliverPushToSubscriptions(input: {
|
||||
|
||||
return "sent" as const;
|
||||
} catch (error) {
|
||||
const statusCode =
|
||||
error && typeof error === "object" && "statusCode" in error
|
||||
? Number((error as { statusCode?: number }).statusCode)
|
||||
: 0;
|
||||
const detail = getPushFailureDetail(subscription, error);
|
||||
const statusCode = detail.statusCode || 0;
|
||||
|
||||
console.error("Push notification delivery failed", detail);
|
||||
|
||||
if (input.collectFailureDetails) {
|
||||
failureDetails.push(detail);
|
||||
}
|
||||
|
||||
if (statusCode === 404 || statusCode === 410) {
|
||||
await prisma.pushSubscription.deleteMany({
|
||||
@@ -194,7 +256,8 @@ async function deliverPushToSubscriptions(input: {
|
||||
sentCount: results.filter((result) => result === "sent").length,
|
||||
removedCount: results.filter((result) => result === "removed").length,
|
||||
failedCount: results.filter((result) => result === "failed").length,
|
||||
} satisfies PushDeliverySummary;
|
||||
failureDetails,
|
||||
} satisfies PushDeliveryResult;
|
||||
}
|
||||
|
||||
export async function sendIncomingMessagePush(publicId: number) {
|
||||
@@ -291,5 +354,6 @@ export async function sendCaregiverTestPush(input: {
|
||||
subscriptions,
|
||||
payload,
|
||||
topic: `test-${input.caregiverId.slice(0, 20)}`,
|
||||
collectFailureDetails: true,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user