diff --git a/express_webpack/index.html b/express_webpack/index.html index 25f077142..8bd717122 100644 --- a/express_webpack/index.html +++ b/express_webpack/index.html @@ -33,6 +33,12 @@ OneSignalDeferred.push(async function(onesignal) { await onesignal.init({ appId, + welcomeNotification: { + disable: false, + title: "Custom Welcome Notification Title", + message: "Custom Welcome Notification Message", + url: "https://example.com", + }, serviceWorkerParam: { scope: '/' + SERVICE_WORKER_PATH }, serviceWorkerPath: SERVICE_WORKER_PATH + 'OneSignalSDKWorker.js', notifyButton: { diff --git a/package.json b/package.json index 11bfc688b..471774c42 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "jest": "jest --coverage" }, "config": { - "sdkVersion": "160201" + "sdkVersion": "160202" }, "repository": { "type": "git", diff --git a/src/shared/api/OneSignalApi.ts b/src/shared/api/OneSignalApi.ts index 656ed357c..d0b15418b 100755 --- a/src/shared/api/OneSignalApi.ts +++ b/src/shared/api/OneSignalApi.ts @@ -2,32 +2,9 @@ import JSONP from 'jsonp'; import SdkEnvironment from '../managers/SdkEnvironment'; import { WindowEnvironmentKind } from '../models/WindowEnvironmentKind'; import OneSignalApiSW from './OneSignalApiSW'; -import OneSignalApiShared from './OneSignalApiShared'; import { ServerAppConfig } from '../models/AppConfig'; export default class OneSignalApi { - static sendNotification( - appId: string, - playerIds: Array, - titles, - contents, - url, - icon, - data, - buttons, - ) { - return OneSignalApiShared.sendNotification( - appId, - playerIds, - titles, - contents, - url, - icon, - data, - buttons, - ); - } - static jsonpLib( url: string, fn: (err: Error, data: ServerAppConfig) => void, diff --git a/src/shared/api/OneSignalApiShared.ts b/src/shared/api/OneSignalApiShared.ts index 1ba6f6263..9531397f9 100644 --- a/src/shared/api/OneSignalApiShared.ts +++ b/src/shared/api/OneSignalApiShared.ts @@ -1,41 +1,8 @@ import { OutcomeRequestData } from '../../page/models/OutcomeRequestData'; -import Utils from '../context/Utils'; import Log from '../libraries/Log'; import OneSignalApiBase from './OneSignalApiBase'; export default class OneSignalApiShared { - static sendNotification( - appId: string, - playerIds: Array, - titles, - contents, - url, - icon, - data, - buttons, - ) { - const params = { - app_id: appId, - contents: contents, - include_player_ids: playerIds, - isAnyWeb: true, - data: data, - web_buttons: buttons, - }; - if (titles) { - (params as any).headings = titles; - } - if (url) { - (params as any).url = url; - } - if (icon) { - (params as any).chrome_web_icon = icon; - (params as any).firefox_icon = icon; - } - Utils.trimUndefined(params); - return OneSignalApiBase.post('notifications', params); - } - static async sendOutcome(data: OutcomeRequestData): Promise { Log.info('Outcome payload:', data); try { diff --git a/src/shared/helpers/EventHelper.ts b/src/shared/helpers/EventHelper.ts index 1d6c8e39c..f5dded02a 100755 --- a/src/shared/helpers/EventHelper.ts +++ b/src/shared/helpers/EventHelper.ts @@ -146,7 +146,6 @@ export default class EventHelper { return; } - const { appId } = await Database.getAppConfig(); let title = welcome_notification_opts !== undefined && welcome_notification_opts['title'] !== undefined && @@ -172,13 +171,11 @@ export default class EventHelper { message = BrowserUtils.decodeHtmlEntities(message); Log.debug('Sending welcome notification.'); - OneSignalApiShared.sendNotification( - appId, - [pushSubscriptionId], - { en: title }, - { en: message }, + MainHelper.showLocalNotification( + title, + message, url, - null, + undefined, { __isOneSignalWelcomeNotification: true }, undefined, ); diff --git a/src/shared/helpers/MainHelper.ts b/src/shared/helpers/MainHelper.ts index d8d538d5b..44ed23523 100755 --- a/src/shared/helpers/MainHelper.ts +++ b/src/shared/helpers/MainHelper.ts @@ -12,8 +12,97 @@ import Utils from '../context/Utils'; import Database from '../services/Database'; import { PermissionUtils } from '../utils/PermissionUtils'; import Environment from './Environment'; +import { getPlatformNotificationIcon, logMethodCall } from '../utils/utils'; +import { + NotSubscribedError, + NotSubscribedReason, +} from '../errors/NotSubscribedError'; +import { + InvalidArgumentError, + InvalidArgumentReason, +} from '../errors/InvalidArgumentError'; +import { ValidatorUtils } from '../../page/utils/ValidatorUtils'; export default class MainHelper { + static async showLocalNotification( + title: string, + message: string, + url: string, + icon?: string, + data?: Record, + buttons?: Array, + ): Promise { + logMethodCall( + 'MainHelper:showLocalNotification: ', + title, + message, + url, + icon, + data, + buttons, + ); + + const appConfig = await Database.getAppConfig(); + + if (!appConfig.appId) + throw new InvalidStateError(InvalidStateReason.MissingAppId); + if (!OneSignal.Notifications.permission) + throw new NotSubscribedError(NotSubscribedReason.NoDeviceId); + if (!ValidatorUtils.isValidUrl(url)) + throw new InvalidArgumentError('url', InvalidArgumentReason.Malformed); + if ( + !ValidatorUtils.isValidUrl(icon, { allowEmpty: true, requireHttps: true }) + ) + throw new InvalidArgumentError('icon', InvalidArgumentReason.Malformed); + if (!icon) { + // get default icon + const icons = await MainHelper.getNotificationIcons(); + icon = getPlatformNotificationIcon(icons); + } + + const convertButtonsToNotificationActionType = (buttons: Array) => { + const convertedButtons = []; + + for (let i = 0; i < buttons.length; i++) { + const button = buttons[i]; + convertedButtons.push({ + action: button.id, + title: button.text, + icon: button.icon, + url: button.url, + }); + } + + return convertedButtons; + }; + const dataPayload = { + data, + url, + buttons: buttons + ? convertButtonsToNotificationActionType(buttons) + : undefined, + }; + + OneSignal.context.serviceWorkerManager + .getRegistration() + .then(async (registration?: ServiceWorkerRegistration | null) => { + if (!registration) { + Log.error('Service worker registration not available.'); + return; + } + + const options = { + body: message, + data: dataPayload, + icon: icon, + actions: buttons + ? convertButtonsToNotificationActionType(buttons) + : [], + }; + registration.showNotification(title, options); + }); + } + static async checkAndTriggerNotificationPermissionChanged() { const previousPermission = await Database.get( 'Options', diff --git a/src/shared/services/Database.ts b/src/shared/services/Database.ts index 3338a7567..6b77cd10b 100644 --- a/src/shared/services/Database.ts +++ b/src/shared/services/Database.ts @@ -129,7 +129,7 @@ export default class Database { * @param keypath */ async put(table: OneSignalDbTable, keypath: any): Promise { - await new Promise((resolve, reject) => { + await new Promise((resolve) => { this.database.put(table, keypath).then(() => resolve()); }); this.emitter.emit(Database.EVENTS.SET, keypath); diff --git a/src/shared/services/IndexedDb.ts b/src/shared/services/IndexedDb.ts index ecfff0df8..1c5398e79 100644 --- a/src/shared/services/IndexedDb.ts +++ b/src/shared/services/IndexedDb.ts @@ -109,7 +109,7 @@ export default class IndexedDb { * * Ref: https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/onversionchange */ - private onDatabaseVersionChange(_: IDBVersionChangeEvent): void { + private onDatabaseVersionChange(): void { Log.debug('IndexedDb: versionchange event'); } @@ -330,16 +330,20 @@ export default class IndexedDb { await this.ensureDatabaseOpen(); return await new Promise((resolve, reject) => { try { - const request = this.database!.transaction([table], 'readwrite') + const request = this.database + ?.transaction([table], 'readwrite') .objectStore(table) .put(key); - request.onsuccess = () => { - resolve(key); - }; - request.onerror = (e) => { - Log.error('Database PUT Transaction Error:', e); - reject(e); - }; + + if (request) { + request.onsuccess = () => { + resolve(key); + }; + request.onerror = (e) => { + Log.error('Database PUT Transaction Error:', e); + reject(e); + }; + } } catch (e) { Log.error('Database PUT Error:', e); reject(e); diff --git a/src/shared/services/OneSignalEvent.ts b/src/shared/services/OneSignalEvent.ts index ae2a82215..ccb51ab51 100755 --- a/src/shared/services/OneSignalEvent.ts +++ b/src/shared/services/OneSignalEvent.ts @@ -29,7 +29,7 @@ export default class OneSignalEvent { static async trigger(eventName: string, data?: any, emitter?: Emitter) { if (!Utils.contains(SILENT_EVENTS, eventName)) { const displayData = data; - let env = Utils.capitalize(SdkEnvironment.getWindowEnv().toString()); + const env = Utils.capitalize(SdkEnvironment.getWindowEnv().toString()); if (displayData || displayData === false) { Log.debug(`(${env}) ยป ${eventName}:`, displayData); diff --git a/src/sw/serviceWorker/ServiceWorker.ts b/src/sw/serviceWorker/ServiceWorker.ts index 3d0990f26..622994a7c 100755 --- a/src/sw/serviceWorker/ServiceWorker.ts +++ b/src/sw/serviceWorker/ServiceWorker.ts @@ -193,7 +193,7 @@ export class ServiceWorker { static setupMessageListeners() { ServiceWorker.workerMessenger.on( WorkerMessengerCommand.WorkerVersion, - (_) => { + () => { Log.debug('[Service Worker] Received worker version message.'); ServiceWorker.workerMessenger.broadcast( WorkerMessengerCommand.WorkerVersion, @@ -241,7 +241,7 @@ export class ServiceWorker { ); ServiceWorker.workerMessenger.on( WorkerMessengerCommand.AmpSubscriptionState, - async (_appConfigBundle: any) => { + async () => { Log.debug('[Service Worker] Received AMP subscription state message.'); const pushSubscription = await self.registration.pushManager.getSubscription();