← Back to Blog
How to send Push Notifications with wsocket.io: Web Push, FCM and APNs — Practical guide
· 15 min read ·

How to send Push Notifications with wsocket.io: Web Push, FCM and APNs — Practical guide

Complete tutorial on sending push notifications using wsocket.io: register service worker, subscribe device, send from backend with Node.js/Python/Go, broadcast to segments, and delivery tracking.

#wsocket#push-notifications#web-push#fcm#apns#nodejs#javascript#tutorial
Share

Push notifications let you engage users even when they’re not on your site. With wsocket.io you can send Web Push (VAPID), FCM (Android) and APNs (iOS) from any backend — without configuring push servers, managing tokens, or dealing with Google/Apple APIs directly.

TL;DR: Register the service worker in the browser, subscribe the device via SDK, send notifications from your backend with 3 lines of code. Broadcast, segments and tracking included.


Architecture

Your Backend (Node.js, Python, Go, etc.)


wsocket.io Push Engine

    ├── Web Push (VAPID) → Browsers (Chrome, Firefox, Edge, Safari)
    ├── FCM → Android devices
    └── APNs → iOS devices

wsocket.io handles all the complexity: VAPID tokens, FCM keys, APNs certificates, retry with exponential backoff and delivery tracking.


1. Setup: Registering the Service Worker

Web Push requires a service worker in the browser. Create the file at the root of your project:

// public/sw.js
self.addEventListener('push', (event) => {
  const data = event.data?.json() || {};

  event.waitUntil(
    self.registration.showNotification(data.title || 'New notification', {
      body: data.body || '',
      icon: data.icon || '/icon-192.png',
      badge: data.badge || '/badge-72.png',
      data: { url: data.url || '/' },
      actions: data.actions || [],
    })
  );
});

self.addEventListener('notificationclick', (event) => {
  event.notification.close();
  const url = event.notification.data?.url || '/';
  event.waitUntil(clients.openWindow(url));
});

2. Subscribing the device in the Browser

<!-- index.html -->
<script>
  const WSOCKET_API_KEY = 'wsk_live_YOUR_API_KEY';
  const WSOCKET_PUSH_URL = 'wss://node00.wsocket.online';

  async function subscribePush() {
    // 1. Register service worker
    const registration = await navigator.serviceWorker.register('/sw.js');

    // 2. Request permission
    const permission = await Notification.requestPermission();
    if (permission !== 'granted') {
      console.log('❌ Permission denied');
      return;
    }

    // 3. Subscribe to push via wsocket.io
    const ws = new WebSocket(`${WSOCKET_PUSH_URL}/?key=${WSOCKET_API_KEY}`);

    ws.onopen = () => {
      ws.send(JSON.stringify({
        action: 'push.subscribe',
        registration: {
          endpoint: registration.pushManager.getSubscription()
            .then(sub => sub?.endpoint),
          // wsocket.io manages VAPID keys automatically
        },
        tags: ['news', 'promotions'],  // Optional segments
        userId: 'user_123'             // User ID (optional)
      }));
    };

    ws.onmessage = (e) => {
      const msg = JSON.parse(e.data);
      if (msg.action === 'push.subscribed') {
        console.log('✅ Subscribed for push notifications');
      }
    };
  }

  // Call on "Enable notifications" button click
  document.getElementById('btn-push')?.addEventListener('click', subscribePush);
</script>

UI Button

<button id="btn-push" class="btn btn-primary">
  🔔 Enable Notifications
</button>

3. Sending Push from Backend (Node.js)

npm install @wsocket-io/sdk
// push.js
const { WSocket } = require('@wsocket-io/sdk');

const client = new WSocket({
  url: 'wss://node00.wsocket.online',
  apiKey: process.env.WSOCKET_API_KEY
});

await client.connect();

// ── Send to a specific user ──
await client.push.send({
  userId: 'user_123',
  title: 'Order confirmed! 🎉',
  body: 'Your order #4521 has been confirmed and is being prepared.',
  icon: '/icon-192.png',
  url: '/orders/4521',
  data: { orderId: 4521 }
});

// ── Broadcast to ALL subscribers ──
await client.push.broadcast({
  title: 'News! 🚀',
  body: 'New feature available. Check it out now!',
  icon: '/icon-192.png',
  url: '/updates'
});

// ── Send to a segment ──
await client.push.send({
  tags: ['promotions'],
  title: 'Special offer 💰',
  body: '50% off the Pro plan — today only!',
  url: '/pricing',
  ttl: 3600  // Expires in 1 hour
});

4. Sending Push from Backend (Python)

pip install wsocket-io
# push.py
from wsocket import WSocket
import asyncio

async def main():
    client = WSocket(
        url="wss://node00.wsocket.online",
        api_key="wsk_live_YOUR_API_KEY"
    )
    await client.connect()

    # Send to a user
    await client.push.send(
        user_id="user_123",
        title="Order shipped! 📦",
        body="Your order is on its way. Track it now.",
        url="/orders/4521"
    )

    # Broadcast
    await client.push.broadcast(
        title="Scheduled maintenance ⚠️",
        body="System will be unavailable tomorrow from 2am to 4am.",
        tags=["system"]
    )

asyncio.run(main())

5. Sending Push from Backend (Go)

go get github.com/wsocket-io/sdk-go
// main.go
package main

import (
    "github.com/wsocket-io/sdk-go"
)

func main() {
    client := wsocket.New(wsocket.Config{
        URL:    "wss://node00.wsocket.online",
        APIKey: "wsk_live_YOUR_API_KEY",
    })
    defer client.Close()

    // Send push
    client.Push.Send(wsocket.PushMessage{
        UserID: "user_123",
        Title:  "New message! 💬",
        Body:   "Alice sent you a message.",
        URL:    "/chat",
    })

    // Broadcast to segment
    client.Push.Send(wsocket.PushMessage{
        Tags:  []string{"news"},
        Title: "System update 🔄",
        Body:  "Version 2.5 available with new features.",
        URL:   "/changelog",
    })
}

6. Express.js Integration (REST API)

// routes/push.js
const express = require('express');
const { WSocket } = require('@wsocket-io/sdk');
const router = express.Router();

const ws = new WSocket({
  url: 'wss://node00.wsocket.online',
  apiKey: process.env.WSOCKET_API_KEY
});
ws.connect();

// POST /api/push/send — send push to a user
router.post('/send', async (req, res) => {
  const { userId, title, body, url } = req.body;

  await ws.push.send({ userId, title, body, url });

  res.json({ ok: true, sent: true });
});

// POST /api/push/broadcast — broadcast to segment
router.post('/broadcast', async (req, res) => {
  const { tags, title, body, url } = req.body;

  await ws.push.send({ tags, title, body, url });

  res.json({ ok: true, broadcast: true });
});

module.exports = router;

7. Real-world use cases

E-commerce — Order status

// When order status changes:
await ws.push.send({
  userId: order.userId,
  title: `Order #${order.id} — ${statusLabel[order.status]}`,
  body: statusMessages[order.status],
  icon: '/icon-order.png',
  url: `/orders/${order.id}`,
  data: { orderId: order.id, status: order.status }
});

SaaS — System notifications

// Broadcast to all Pro plan users
await ws.push.send({
  tags: ['plan:pro'],
  title: 'New feature available 🎉',
  body: 'Webhooks now support automatic retry with backoff.',
  url: '/docs/webhooks'
});

Chat — Direct message

// When someone sends a DM
await ws.push.send({
  userId: recipientId,
  title: `${senderName} sent you a message`,
  body: message.text.substring(0, 100),
  icon: senderAvatar,
  url: `/chat/${conversationId}`
});

8. Push Notifications plans

FeatureFreeProEnterprise
Push subscriptions10050KUnlimited
Notifications/day1K100KUnlimited
Web Push (VAPID)YesYesYes
FCM + APNsNoYesYes
Broadcast & segmentsNoYesYes
Delivery trackingNoYesYes
Dedicated infraNoNoYes

9. Best practices

  1. Ask permission at the right time — Don’t show the notification popup immediately. Wait for the user to interact with a relevant feature
  2. Segment your sends — Use tags to categorize users (plan, interest, region)
  3. Set TTL — Promotional notifications that expire make more sense than stale messages
  4. Use actions — Add buttons to the notification (“View order”, “Reply”)
  5. Respect timing — Avoid sending push at 3am (do server-side scheduling)

Conclusion

wsocket.io eliminates all push notification complexity:

  • No configuring VAPID keys manually
  • No managing tokens for FCM/APNs
  • No implementing retry with backoff
  • No maintaining infrastructure for push

You focus on your product, wsocket.io handles delivery.

Links: