Add a development-only button to send test push notifications to all subscribers.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0aa507c2-4fa6-42bc-9ce7-ee6f559c10a5
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/9dda30b6-4149-4bce-89dc-76333005952c/c6cce535-1f81-43c1-8b69-181a5f1f9aa1.jpg
This commit is contained in:
TerribleDev
2025-03-02 07:33:21 +00:00
parent 9ff5623653
commit 544b55132d
2 changed files with 101 additions and 10 deletions

View File

@@ -22,6 +22,7 @@ import {
Rss,
Bell,
BellOff,
BellRing,
} from "lucide-react";
import { useNewsletters, useNewsletterSearch, type NewslettersResponse } from "@/lib/newsletter-data";
import { useToast } from "@/hooks/use-toast";
@@ -35,6 +36,7 @@ const ITEMS_PER_PAGE = 20;
export default function Home() {
const [searchQuery, setSearchQuery] = useState("");
const [isImporting, setIsImporting] = useState(false);
const [isSendingTestNotification, setIsSendingTestNotification] = useState(false);
const [page, setPage] = useState(1);
const [isSubscribed, setIsSubscribed] = useState(false);
const [allItems, setAllItems] = useState<Newsletter[]>([]);
@@ -134,6 +136,25 @@ export default function Home() {
}
};
const handleSendTestNotification = async () => {
try {
setIsSendingTestNotification(true);
const response = await apiRequest("POST", "/api/notifications/test");
toast({
title: "Test Notifications Sent",
description: `Results: ${response.succeeded} succeeded, ${response.failed} failed out of ${response.total} subscriptions`,
});
} catch (error: any) {
toast({
title: "Error",
description: error.message || "Failed to send test notifications",
variant: "destructive",
});
} finally {
setIsSendingTestNotification(false);
}
};
const handleSubscribe = async () => {
try {
if (!("serviceWorker" in navigator) || !("Notification" in window)) {
@@ -243,16 +264,29 @@ export default function Home() {
/>
</div>
{isDevelopment && (
<Button
variant="outline"
size="icon"
onClick={handleImport}
disabled={isImporting}
>
<RefreshCw
className={`h-4 w-4 ${isImporting ? "animate-spin" : ""}`}
/>
</Button>
<>
<Button
variant="outline"
size="icon"
onClick={handleImport}
disabled={isImporting}
>
<RefreshCw
className={`h-4 w-4 ${isImporting ? "animate-spin" : ""}`}
/>
</Button>
<Button
variant="outline"
size="icon"
onClick={handleSendTestNotification}
disabled={isSendingTestNotification}
title="Send test notification to all subscribers"
>
<BellRing
className={`h-4 w-4 ${isSendingTestNotification ? "animate-pulse" : ""}`}
/>
</Button>
</>
)}
<Button
variant="outline"

View File

@@ -309,6 +309,63 @@ export async function registerRoutes(app: Express): Promise<Server> {
}
});
// New endpoint for sending test notifications to all subscribers
app.post("/api/notifications/test", async (_req, res) => {
try {
// Only allow this in development mode
if (process.env.NODE_ENV === 'production') {
return res.status(403).json({ message: "This endpoint is only available in development mode" });
}
const subscriptions = await storage.getActiveSubscriptions();
if (subscriptions.length === 0) {
return res.status(200).json({ message: "No active subscriptions found" });
}
console.log(`Sending test notification to ${subscriptions.length} subscribers`);
const notificationPayload = JSON.stringify({
title: "Test Notification",
body: "This is a test notification from The Downtowner",
icon: "/icon.png",
});
const results = await Promise.allSettled(
subscriptions.map((subscription) =>
webpush.sendNotification(
{
endpoint: subscription.endpoint,
keys: {
auth: subscription.auth,
p256dh: subscription.p256dh,
},
},
notificationPayload,
),
),
);
const succeeded = results.filter((r) => r.status === "fulfilled").length;
const failed = results.filter((r) => r.status === "rejected").length;
console.log(`Test notification results: ${succeeded} succeeded, ${failed} failed`);
res.status(200).json({
message: `Test notifications sent: ${succeeded} succeeded, ${failed} failed`,
succeeded,
failed,
total: subscriptions.length
});
} catch (error) {
console.error("Error sending test notifications:", error);
res.status(500).json({
message: "Failed to send test notifications",
error: error instanceof Error ? error.message : String(error),
});
}
});
app.post("/api/subscriptions", async (req, res) => {
try {
console.log("Received subscription request:", {