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.
- 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).
- 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.
- 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.
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.
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 |
Access to Apple Developer Account.
Initialize Podfile if already is not initialized
$ cd your_project_name
$ pod init
Open XCode Workspace instead of Project
Add to your target our library:
target 'your_project_name' do
use_frameworks!
pod 'PpgCoreSDK', '~> 0.0.11'
end
Then install pods and open xcode with workspace env
$ pod install
$ xed your_project_name.xcworkspace
- Select your root item in files tree called "your_project_name" with blue icon and select your_project_name in Target section.
- Go to Signing & Capabilities tab and click on "+ Capability" under tabs.
- Select Push Notifications and Background Modes
- On Background Modes select items:
- Remote notifications
- Background fetch
- Go to file -> New -> Target
- Search for Notification Service Extension and choose product name may be for example NSE
- Finish process and on prompt about Activate “NSE” scheme? click Cancel
- Add to previously used name NSE
target to
Podfile
:
target 'NSE' do
use_frameworks!
pod 'PpgCoreSDK', '~> 0.0.11'
end
- Install pods
$ pod install
- Open file NotificationService.swift
- Paste this code:
import UserNotifications
import PpgCoreSDK
class NotificationService: PpgCoreNotificationServiceExtension {
override func onExternalData(data: String) {
PpgCoreLogger.info("NSE RECEIVED EXTERNAL DATA" + data)
}
}
- Create AppDelegate.swift
import Foundation
import SwiftUI
class AppDelegate: NSObject, UIApplicationDelegate {
}
- In your App file wrap delegate via decorator
struct your_project_nameApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
...
}
- Add imports and create instance
import Foundation
import SwiftUI
import UserNotifications
import PpgCoreSDK
class AppDelegate: NSObject, UIApplicationDelegate {
let ppgCoreClient: PpgCoreClient = PpgCoreClient()
}
- Add method for willFinishLaunchingWithOptions
/// Handles data "externalData" from notification (silent, data)
func onPpgCoreExternalData(data: String) -> Void {
PpgCoreLogger.info("EXTERNAL DATA RECEIVED: " + data);
}
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
UNUserNotificationCenter.current().delegate = self
ppgCoreClient.initialize(actionLabels: ["Open", "Check more"], onExternalData: self.onPpgCoreExternalData)
return true
}
- Add method for didFinishLaunchingWithOptions
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
ppgCoreClient.registerForNotifications(handler: {
result in
switch result {
case .success:
PpgCoreLogger.info("Granted")
break
case .error:
PpgCoreLogger.error("Denied")
break
}
})
ppgCoreClient.resetBadge()
return true
}
- Add method for didRegisterForRemoteNotificationsWithDeviceToken
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// TODO: Save this in your database!
PpgCoreLogger.info(Subscription(token: deviceToken).toJSONString())
}
- Add method for didReceiveRemoteNotification
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
ppgCoreClient.handleBackgroundRemoteNotification(userInfo: userInfo, completionHandler: completionHandler)
}
- On the end of
AppDelegate.swift
add extension
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
ppgCoreClient.handleNotification(notification: notification, completionHandler: completionHandler)
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler:
@escaping () -> Void) {
ppgCoreClient.handleNotificationResponse(response: response, completionHandler: completionHandler)
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didDismissNotification notification: UNNotification) {
ppgCoreClient.handleNotificationDismiss(notification: notification)
}
}
- (optional) If you need to overwrite endpoint or prepare channels (with customized actions) create PpgCore.plist
Important: Select target for your app and notification service extension!
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PpgCoreSDKEndpoint</key>
<string>https://api-core.pushpushgo.com/v1</string>
<key>PpgCoreChannels</key>
<array>
<dict>
<key>name</key>
<string>testing_channel</string>
<key>sound</key>
<string>Submarine.aiff</string>
<key>actions</key>
<array>
<string>Reply</string>
</array>
</dict>
<dict>
<key>name</key>
<string>testing_channel_nowy</string>
<key>sound</key>
<string>sub.caf</string>
<key>actions</key>
<array>
<string>Open</string>
<string>Show more</string>
</array>
</dict>
</array>
</dict>
</plist>
- Go to Apple Developer Portal - Identities and go to Identifiers section
- Select from list your appBundleId like
com.example.your_project_name
- Look for PushNotifications and click "Configure" button
- Select your Certificate Singing Request file
- Download Certificates and open in KeyChain Access (double click in macos)
- Find this certificate in list select then in context menu (right click) select export and export to .p12 format file with password.
- Wrap exported certficates with Base64 with command
$ cat Certificate.p12 | base64
- Prepare JSON with provider configuration
{
"type": "apns_cert",
"payload": {
"p12": "encoded base64 Certficiate.p12",
"passphrase": "PASSWORD",
"production": false,
"appBundleId": "com.example.your_product_name",
}
3. Go to example SenderSDK docs
In examples please use prepared "providerConfig" and token returned from SDK to send notifications.
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 [email protected]