0.0.10 • Published 1 year ago

@pushpushgo/core-sdk-js v0.0.10

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

CORE by PushPushGo SDK for JavaScript / TypeScript

npmjs version GitHub Workflow Status (main) GitHub tag (latest) Discord

Product Info

CORE by PushPushGo is a hassle-free building block for all your web and mobile push needs.

Send your transactional and bulk messages, and we'll take care of the rest.

What we offer:

  • Ready SDK for client/server integration - we have SDK for the most popular platforms.
  • Mobile and WebPush implementation (APNS, FCM, VAPID).
  • Transactional and bulk push notifications through API.
  • Hassle-free usage. Our servers handle traffic peaks and store images.
  • Event aggregation in bulk sent to your webhook for easy analysis or running your business logic.
  • GDPR-ready solution protecting private data in accordance with EU regulations.
  • No vendor lock-in - build and own your subscriber base (stateless solution).

What you get:

  • Cost-effective solution: pay for sent pushes, not for infrastructure, traffic, and storage.
  • Save time and effort on developing the sender and infrastructure.
  • Simple API interface for all channels with bulk support.
  • Support on our Discord Server.
  • You can implement notification features your way.

Try it if:

  • You want to control the flow in your transactional messages and add a push notification channel.
  • You're looking for an easy push notifications tool for your organization, whether it's finance, e-commerce, online publishing, or any other sector.
  • You work in a software house and build solutions for your clients.
  • You want a hassle-free solution to focus on other tasks at hand.
  • You want to implement an on-premise solution for sending notifications.
  • You have issues with an in-house solution.
  • You're looking for a reliable provider and cooperation based on your needs.

How it works

When client register for notifications you will get object with:

  • Credentials
  • Token/endpoint
  • Type of provider
  • Identifier of provider

We call this Recipient - it's your subscription data, store it in your database.

When you try to send message you will prepare:

  • Bucket - your temporary credentials bucket - this bucket can be reused any time, or recreated when credentials changed,

  • Context - your message - this context can be reused to send bulk messages or just used once when you send transactional message then is context is temporary

When you send message you will authorize via bucket data, prepare message with context and send to recipients that can be bulked up to 1000 per request.

On the server side:

  • We validate and prepare the message body.
  • Then, we upload and resize images to our CDN.
  • Next, we connect and send to different providers.

On the client side:

  • Get notifications via our SDK in your App/Website.
  • When interacting with a notification, we collect events with our API.

On the server side:

  • We aggregate events and deliver them in bulk to your webhook endpoint.

Architecture

image

When a message is delivered to the device and interacts with the user, we collect events and pass them to our API. The collected events are resent to your webhook endpoint.

Webhooks events

During the journey of push we will trigger webhook events.

Push TypeEventForegroundBackground
Data
delivered
clicked
sent
close
Silent1
delivered
sent

1 - webpush doesn't support silent messages due to Push API implementation

If foreignId field was passed with receiver then it will also be included in event in message.

Example events package:

{
    "messages": [
        {
            "messageId": "8e3075f1-6b21-425a-bb4f-eeaf0eac93a2",
            "foreignId": "my_id",
            "result": {
                "kind": "delivered"
            },
            "ts": 1685009020243
        }
    ]
}

Pricing

We charge $0.50 USD for every 1000 sent notifications.

Open API Specification

Please visit our Swagger

Support & Sales

Join our Discord for docs, support, talk or just to keep in touch.

CORE by PushPushGo is not the same as our main PushPushGo product - are you looking for PushPushGo - Push Notifications Management Platform?

Client side SDK - supported platforms / providers

PlatformProviderSDK
Android / HuaweiFCM / HMSCORE Android SDK
iOSAPNSCORE iOS SDK
FlutterFCM / HMS / APNSCORE Flutter SDK
WebVapid (WebPush)CORE JS SDK

Server side SDK (sending notifications)

PlatformSDK
JavaScript / TypeScriptCORE JS SDK
.NETWIP - ask
JavaWIP - ask

SDK Integration instructions

To use this SDK you need to have account in CORE by PushPushGo! and token to authorize your requests.

This package contains two modules "client" and "server".

ClientSDK is for requesting push notifications.

ServerSDK is for sending push notifications via CORE by PushPushGo API Swagger

Autogenerated Docs

Client SDK:

  • Service Worker implementation for Push Notifications
  • Client for registering Service Worker and manage Subscription (Receiver)

How to use as modules in browser via jsdelivr?

import { PpgCoreClient } from "https://cdn.jsdelivr.net/npm/@pushpushgo/core-sdk-js@latest/dist/browser/client/index.js"
import { Worker } from "https://cdn.jsdelivr.net/npm/@pushpushgo/core-sdk-js@latest/dist/browser/worker/index.js"

Worker

Worker must be initialized with ServiceWorkerGlobalScope which is self in Service Worker example initialization:

sw.js file example code:

import { Worker } from "https://cdn.jsdelivr.net/npm/@pushpushgo/core-sdk-js@latest/dist/browser/worker/index.js"

new Worker(self, {
    // Endpoint to our server default fallback to https://api-core.pushpushgo.com/v1 - optional value
    endpoint: "", 
    // When "subscription change was triggered" we will inform your endpoint (webhook) - can be same endpoint 
    onSubscriptionChange: {
        // Url to your endpoint that will receive this information
        endpoint: "" 
        headers: {
             // Custom headers
            "Some": "Header",
        }
    } 
})

On subscription change we will inform endpoint from onSubscriptionChange with POST method and Headers from headers field with payload:

{
    "type": "change"
    "payload": {
        "oldSubscription": {
            "endpoint": "",
            "expirationTime": 0,
            "keys": {
                "p256dh": "",
                "auth": "",
            }
        },
        "newSubscription": {
            "endpoint": "",
            "expirationTime": 0,
            "keys": {
                "p256dh": "",
                "auth": "",
            }
        }
    }    
}

Client Browser - Subscribe to nofications

const ppgClient = PpgCoreClient
.builder()
.setVapidSupport({
    // Set scope - root scope preferred
    scope: '/',
    // Set path of service worker module file
    swPath: '/worker.js',
    // Service worker parameters
    userVisibleOnly: true,
    // Public Vapid Key
    applicationServerKey: "BMLa3ig2yYnIv-TcpqiShHjy8mRjGFt2vPq-AHEx4ARGen-g8_GfF5ybpqVeXy_zdaEUxYEz1kF1IsLwyIHmP2w"
})
.build();

Client contains method:

  browserSupportsWebPush(): boolean;
  isSubscribed(): Promise<boolean>;
  // prompt for allow notifications if accept then you will get subscription - store this in you database for future sending
  subscribe(): Promise<object>; 
  // returns actual subscription
  getSubscription(): Promise<null | object>; 
  unsubscribe(): Promise<boolean>;

Full example how to subscribe for notifications in directory browser jsdelivr example

Server SDK:

Definitions of vocabulary:

  • Bucket - it's a configuration (credentials to providers) - once created can be used 24 hours with it's reference. We implement buckets because of traffic and performance. Once you send to us credentials to providers you can reuse this for multiple "campaigns".

  • Context - it's a configuration of content and behaviour of notification. It can also be reusable (in case when you want to send "campaign" to multiple receivers)

  • Receiver - it's a "subscription" that you get from our sdk.

Server SDK covers:

  • Bucket builder
  • Context builder
  • Send Data / Silent / Transactional messages

How to install?

Server and client version is in one package and available via esm module. Module can be used on browser and server side.

$ yarn add @pushpushgo/core-sdk-js

How to use as modules in backend?

import { Worker } from "@pushpushgo/core-sdk-js/browser/worker";
import { PpgCoreClient} from "@pushpushgo/core-sdk-js/server/client";

Server client

Server client may be used to create bucket, context, and send notifications

import { PpgCoreClient } from "https://cdn.jsdelivr.net/npm/@pushpushgo/core-sdk-js@latest/dist/browser/client/index.js"

// Initialize client
const client = new PpgCoreClient({
  // Optional field with endpoint to our service default fallback to https://api-core.pushpushgo.com/v1 use only when you want to override this param
  endpoint: "",
  // Api key for auth your account, to caim a production API key please contact with us (via discord, email)
  apiKey: ""
});

Client instance can create bucket. Bucket contains all provider configurations that you want to use during sending session

const bucket = await client.createBucket({
    // You can declare multiple providers for one session
    providers: [
        {
            // Provider type
            type: "vapid" | "hms" | "fcm_v1" | "fcm_legacy" | "apns_token" | "apns_cert"
            // Here please define providers credentials, available providers you can see in table below
            payload: {}
        },
        {
            ...
        }
    ],
    // Optional - This field declare a endpoint that will receive all events gathered from our SDK clients (ios, android, js, flutter) and send aggregated bulks every 1000k or 60 seconds.
    httpCallbackConfig: {
        url: "https://...",
        headers: {}
    },
})

Available providers:

vapid payload

{
    "type": "vapid",
    "payload": {
        // You previously generated vapid keys
        "privateKey": "",
        "publicKey": "",
    }
}

hms

{
    "type": "hms",
    "payload": {
        // Your appId and appSecret from developer.huawei.com
        "appId": "",
        "appSecret": "",
        "pushUrl" : "https://push-api.cloud.huawei.com/v1",
        "authUrl" : "https://oauth-login.cloud.huawei.com/oauth2/v2/token"
    }
}

fcm_v1

{
    "type": "fcm_v1",
    "payload": {
        // service-account google json config
        "type": "",
        "project_id": "",
        "private_key_id": "",
        "private_key": "",
        "client_email": "",
        "client_id": "",
        "auth_uri": "",
        "token_uri": "",
        "auth_provider_x509_cert_url": "",
        "client_x509_cert_url": ""
    }
}

fcm_legacy

{
    "type": "fcm_legacy",
    "payload": {
        // Values from console.firebase.google.com
        "senderId": "",
        "authorizationKey": "",
    }
}

apns_token

{
    "type": "apns_token",
    "payload": {
        // You can get this from developer.apple.com
        "teamId": "",
        "keyId": "",
        "key": "",
        "production": true,
        /**
        * One of depends what you want authorize mobile app or safari
        */
        "appBundleId": "",
        "websitePushId": "web."
    }
}

apns_cert

{
    "type": "apns_cert",
    "payload": {
        // Certificate store with p12 format (on ppg-core-ios-sdk you can see instruction for that)
        "p12": "", // base64 encoded
        "passphrase": "",
        "production": true,
        /**
        * One of depends what you want authorize mobile app or safari
        */
        "appBundleId": "",
        "websitePushId": "web."
    }
}

Now in this bucket you can create "multiple contexts"

  • data context
  • silent context
const dataContext = await bucket.createContext({
    channelName: "default",
    title: "Hello world",
    body: "This is my first message!",
    subtitle: "My subtitle for ios or legacy safari"
    behaviour: "https://example.com",
    behaviourIos: "app://com.example.ios/deep/link", // optional if not pass get from "behaviour"
    behaviourAndroid: "app://com.example.android/deep/link", // optional if not pass get from "behaviour"
    behaviourHuawei: "app://com.example.huawei/deep/link" // optional if not pass get from "behaviour"

    smallIcon: "https://placehold.co/64",
    icon: "https://placehold.co/256",
    image: "https://placehold.co/768x512",

    // One of 
    expiresAt: "YYYY-MM-DDT00:00:00.000Z",
    ttl: "3600", // seconds

    badgeMobile: 1, // set badge number on app icon 
    externalData: "{\"sample\": true}",
    actions: [
        { 
            behaviour: "https://example.com/action1",
            behaviourIos: "app://com.example.ios/deep/link/action1", // optional if not pass get from "behaviour"
            behaviourAndroid: "app://com.example.android/deep/link/action1", // optional if not pass get from "behaviour"
            behaviourHuawei: "app://com.example.huawei/deep/link/action1", // optional if not pass get from "behaviour"
            behaviourWebPush: "https://example.com/action1", // optional if not pass get from "behaviour"

            title: "My action",
            icon: "https://placehold.co/64",
            action: "action_1"
        }
    ]

});

const silentContext = await bucket.createSilentContext({
    expiresAt: new Date(Date.now() + 3600_000).toISOString()
});

Platform specific params for DataContext table | Parameter | WebPush(VAPID)| Android(FCM) | Huawei(HMS) | iOS (APNS) | Safari (APNS)1 | | ------------------ |:-------------:|:-------------:|:-------------:|:-------------:|:-------------:| | title | ✓ | ✓ | ✓ | ✓ | ✓ | | body | ✓ | ✓ | ✓ | ✓ | ✓ | | smallIcon | ✓ | ✓ | ✓ | - | - | | icon | ✓ | ✓ | ✓ | ✓ | ✓2 | | image | ✓ | ✓ | ✓ | ✓ | - | | bahviour | ✓ | ✓ | ✓ | ✓ | ✓ | | behaviourIos | - | - | - | ✓ | - | | behaviourAndroid | - | ✓ | - | - | - | | behaviourHuawei | - | - | ✓ | - | - | | behaviourWebPush | ✓ | - | - | - | - | | badge | ✓3 | ✓ | ✓ | ✓ | - | | actions | ✓ | ✓ | ✓ | ✓ | - | | actions.title | ✓ | - | - | ✓4 | - | | actions.icon | - | - | - | - | - | | actions.action | ✓ | ✓ | ✓ | ✓ | - | | actions.behaviour | ✓ | ✓ | ✓ | ✓ | - | | subtitle | - | - | - | ✓ | ✓ | | externalData | ✓ | ✓ | ✓ | ✓ | - | | expiresAt | ✓ | ✓ | ✓ | ✓ | ✓ | | ttl | ✓ | ✓ | ✓ | ✓ | ✓ | | channelName | ✓ | ✓ | ✓ | ✓ | - |

Now when you have context you can send notifications to your subscribers up to 1000 in one request

const result = await dataContext.sendMessages([
    bucket.createReceiver(
        //TODO: Paste your subscription data here
    ),
    bucket.createReceiver(
        //TODO: Paste your subscription data here
    ),
]);

You can also send "transactional" message without creating context direcly on bucket:

Data context:

const result = await bucket.sendMessage(
    bucket.createReceiver(
        //TODO: Paste your subscription data here
    ),
    {
        title: "...",
        body: "...",
        behaviour: "...",
        // other params from context
    }
]);

Silent context:

const result = await bucket.sendSilentMessage(
    bucket.createReceiver(
        //TODO: Paste your subscription data here
    ),
    {
        externalData: "..."
    }
]);

Full example how to send notifications in directory server sender example

How to use with bundlers (tsc, webpack, parcel, etc)

This package should compile well with all bundlers. If you have any issues please give us feedback in Issues section.

Full example how to subscribe for notifications in directory browser bundle example

How to generate vapid keys to configure Client SDK?

$ yarn global add web-push
$ web-push generate-vapid-keys
Important!

Store this keys!

You need to do this action only once per one website.

This keys will be associated with your subscriptions and to encrypt your requests to providers.

In SDK provide only publicKey, privateKey is for sender.

Support & production run

All API keys available in this documentation allows you to test service with very low rate-limits. If you need production credentials or just help with integration please visit us in discord or just mail to support+core@pushpushgo.com

0.0.10

1 year ago

0.0.9

1 year ago

0.0.8

1 year ago

0.0.7

1 year ago

0.0.6

1 year ago

0.0.5

1 year ago

0.0.4

1 year ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago