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.
When client register for notifications you will get object with:
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:
On the client side:
On the server side:
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.
During the journey of push we will trigger webhook events.
Push Type | Event | Foreground | Background |
---|---|---|---|
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
}
]
}
We charge $0.50 USD for every 1000 sent notifications.
Please visit our Swagger
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?
Platform | Provider | SDK |
---|---|---|
Android / Huawei | FCM / HMS | CORE Android SDK |
iOS | APNS | CORE iOS SDK |
Flutter | FCM / HMS / APNS | CORE Flutter SDK |
Web | Vapid (WebPush) | CORE JS SDK |
Platform | SDK |
---|---|
JavaScript / TypeScript | CORE JS SDK |
.NET | WIP - ask |
Java | WIP - ask |
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
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 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": "",
}
}
}
}
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
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:
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
import { Worker } from "@pushpushgo/core-sdk-js/browser/worker";
import { PpgCoreClient} from "@pushpushgo/core-sdk-js/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:
{
"type": "vapid",
"payload": {
// You previously generated vapid keys
"privateKey": "",
"publicKey": "",
}
}
{
"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"
}
}
{
"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": ""
}
}
{
"type": "fcm_legacy",
"payload": {
// Values from console.firebase.google.com
"senderId": "",
"authorizationKey": "",
}
}
{
"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."
}
}
{
"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"
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
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
$ yarn global add web-push
$ web-push generate-vapid-keys
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.
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
Generated using TypeDoc