├── .editorconfig ├── .eslintignore ├── .eslintrc.cjs ├── .github ├── ISSUE_TEMPLATE │ ├── ask-question.yml │ ├── bug-report.yml │ ├── general-feedback.yml │ └── workflows │ │ ├── Zapier.yml │ │ └── release-drafter.yml ├── release-drafter.yml └── workflows │ ├── project.yml │ └── release.yml ├── .gitignore ├── .npmignore ├── .releaserc.json ├── .travis.yml ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── MigrationGuide.md ├── README.md ├── dist ├── index.d.ts ├── index.es.js ├── index.es.js.map ├── index.js ├── index.js.map └── index.test.d.ts ├── example ├── .gitignore ├── README.md ├── index.html ├── package.json ├── public │ ├── OneSignalSDKWorker.js │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── src │ ├── App.css │ ├── App.tsx │ ├── index.css │ ├── index.tsx │ ├── logo.svg │ ├── react-app-env.d.ts │ ├── reportWebVitals.ts │ └── types.d.ts ├── tsconfig.json └── vite.config.ts ├── index.test.ts ├── index.ts ├── package-lock.json ├── package.json ├── rollup.config.js ├── tsconfig.json ├── vite.config.ts └── vitest.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | example/ 3 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | es6: true, 6 | node: true, 7 | }, 8 | settings: { 9 | 'import/resolver': { 10 | node: { 11 | paths: ['src'], 12 | extensions: ['.js', '.ts', '.jsx', '.tsx'], 13 | }, 14 | }, 15 | }, 16 | extends: [ 17 | 'plugin:react/recommended', 18 | 'plugin:@typescript-eslint/recommended', 19 | ], 20 | parser: '@typescript-eslint/parser', 21 | parserOptions: { 22 | ecmaFeatures: { 23 | jsx: true, 24 | }, 25 | ecmaVersion: 2018, 26 | sourceType: 'module', 27 | }, 28 | plugins: ['react', '@typescript-eslint'], 29 | rules: { 30 | 'react/jsx-filename-extension': [1, { extensions: ['.tsx', '.jsx'] }], 31 | 'react/jsx-props-no-spreading': 0, 32 | '@typescript-eslint/no-unused-vars': ['error'], 33 | '@typescript-eslint/no-explicit-any': 'warn', 34 | 'prefer-destructuring': 0, 35 | 'no-param-reassign': 0, 36 | 'import/extensions': 0, 37 | 'dot-notation': 0, 38 | 'no-continue': 0, 39 | 'no-unused-vars': 'off', 40 | 'no-unused-expressions': [ 41 | 'error', 42 | { allowShortCircuit: true, allowTernary: true }, 43 | ], 44 | }, 45 | }; 46 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/ask-question.yml: -------------------------------------------------------------------------------- 1 | name: 🙋‍♂️ Ask a question 2 | description: Tell us what's on your mind 3 | title: '[Question]: ' 4 | labels: ['Question'] 5 | 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: | 10 | Having issues integrating this SDK? 11 | - type: textarea 12 | id: question 13 | attributes: 14 | label: How can we help? 15 | description: Specific question regarding integrating this SDK. 16 | placeholder: How do I...? 17 | validations: 18 | required: true 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: 🪳 Bug report 2 | description: File a bug report 3 | title: '[Bug]: ' 4 | labels: ['Bug'] 5 | 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: | 10 | Thanks for taking the time to fill out this bug report! 11 | - type: textarea 12 | id: what-happened 13 | attributes: 14 | label: What happened? 15 | description: Provide a thorough description of whats going on. 16 | placeholder: The latest version of the SDK causes a runtime error. 17 | validations: 18 | required: true 19 | - type: dropdown 20 | id: browsers 21 | attributes: 22 | label: What browsers are you seeing the problem on? 23 | multiple: true 24 | options: 25 | - Firefox 26 | - Chrome (Chromium) 27 | - Safari 28 | - Microsoft Edge 29 | - Opera 30 | - Brave 31 | - Other 32 | validations: 33 | required: true 34 | - type: input 35 | id: operating-system 36 | attributes: 37 | label: What operating system are you running? 38 | description: Make sure to include the version. 39 | placeholder: macOS Monterey 12.3.1 40 | validations: 41 | required: true 42 | - type: textarea 43 | id: reproduction-steps 44 | attributes: 45 | label: Steps to reproduce? 46 | description: Provide as much detail as posible to reproduce the issue. 47 | placeholder: | 48 | 1. Install dependencies: vX.Y.Z, etc... 49 | 2. Run the app 50 | 3. Click on the notification prompt 51 | 4. Note that this causes a runtime error and a failed subscription. 52 | render: Markdown 53 | validations: 54 | required: true 55 | - type: textarea 56 | id: what-are-expectations 57 | attributes: 58 | label: What did you expect to happen? 59 | description: Also tell us, what did you expect to happen? 60 | placeholder: I expected the notification prompt to cause a native permission change in the browser. 61 | validations: 62 | required: true 63 | - type: textarea 64 | id: logs 65 | attributes: 66 | label: Relevant log output 67 | description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. 68 | render: Shell 69 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/general-feedback.yml: -------------------------------------------------------------------------------- 1 | name: 📣 General feedback 2 | description: Tell us what's on your mind 3 | title: '[Feedback]: ' 4 | labels: ['Feedback'] 5 | 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: | 10 | Thanks for sharing your valuable feedback! 11 | - type: textarea 12 | id: feedback 13 | attributes: 14 | label: What's on your mind? 15 | description: Feedback regarding this SDK. 16 | placeholder: Share your feedback... 17 | validations: 18 | required: true 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/workflows/Zapier.yml: -------------------------------------------------------------------------------- 1 | # This is an action to close asana tasks that were generated by Github issues 2 | 3 | name: Zapier web hook 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the "main" branch 8 | issues: 9 | types: [closed] 10 | 11 | permissions: 12 | issues: read 13 | 14 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 15 | jobs: 16 | # This workflow contains a single job called "build" 17 | build: 18 | # The type of runner that the job will run on 19 | runs-on: ubuntu-latest 20 | 21 | # Steps represent a sequence of tasks that will be executed as part of the job 22 | steps: 23 | # Runs a set of commands using the runners shell 24 | - name: Call Zapier web hook to close Asana task 25 | if: ${{ !github.event.issue.pull_request }} 26 | env: 27 | ISSUE_TITLE: ${{ github.event.issue.title }} 28 | run: | 29 | curl --location --request POST 'https://hooks.zapier.com/hooks/catch/12728683/b7009qc/' \ 30 | --header 'Content-Type: application/json' \ 31 | --header 'Accept: application/json' \ 32 | --data-raw '{ 33 | "task_name" : "$ISSUE_TITLE" 34 | }' 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | # branches to consider in the event; optional, defaults to all 6 | branches: 7 | - main 8 | # pull_request event is required only for autolabeler 9 | pull_request: 10 | # Only following types are handled by the action, but one can default to all as well 11 | types: [opened, reopened, synchronize] 12 | # pull_request_target event is required for autolabeler to support PRs from forks 13 | # pull_request_target: 14 | # types: [opened, reopened, synchronize] 15 | 16 | permissions: 17 | contents: read 18 | 19 | jobs: 20 | update_release_draft: 21 | permissions: 22 | # write permission is required to create a github release 23 | contents: write 24 | # write permission is required for autolabeler 25 | # otherwise, read permission is required at least 26 | pull-requests: write 27 | runs-on: ubuntu-latest 28 | steps: 29 | # (Optional) GitHub Enterprise requires GHE_HOST variable set 30 | #- name: Set GHE_HOST 31 | # run: | 32 | # echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV 33 | 34 | # Drafts your next Release notes as Pull Requests are merged into "master" 35 | - uses: release-drafter/release-drafter@v5 36 | # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml 37 | # with: 38 | # config-name: my-config.yml 39 | # disable-autolabeler: true 40 | env: 41 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 42 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: $RESOLVED_VERSION 2 | tag-template: $RESOLVED_VERSION 3 | categories: 4 | - title: 🚀 Features 5 | label: Enhancement / Feature 6 | - title: 🐛 Bug Fixes 7 | label: Bug 8 | - title: 🧰 Improvements 9 | label: Improvement 10 | - title: down arrow Dependency Updates 11 | label: Dependencies 12 | change-template: '- $TITLE (#$NUMBER)' 13 | version-resolver: 14 | major: 15 | labels: 16 | - 'major' 17 | minor: 18 | labels: 19 | - 'minor' 20 | patch: 21 | labels: 22 | - 'patch' 23 | default: patch 24 | template: | 25 | ## Other Changes 26 | 27 | $CHANGES 28 | -------------------------------------------------------------------------------- /.github/workflows/project.yml: -------------------------------------------------------------------------------- 1 | name: Add issues to project 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | 8 | jobs: 9 | add-to-project: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Add issue to project 13 | uses: actions/add-to-project@v1.0.2 14 | with: 15 | # SDK Web Project 16 | project-url: https://github.com/orgs/OneSignal/projects/9 17 | github-token: ${{ secrets.GH_PROJECTS_TOKEN }} 18 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | release: 9 | name: Release 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write 13 | issues: write 14 | pull-requests: write 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | token: ${{ secrets.GH_WEB_SHIM_PUSH_TOKEN }} 21 | - name: Setup Node.js 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: 'lts/*' 25 | registry-url: 'https://registry.npmjs.org' 26 | - name: Install dependencies 27 | run: npm ci 28 | - name: Release 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GH_WEB_SHIM_PUSH_TOKEN }} 31 | NODE_AUTH_TOKEN: ${{ secrets.NPM_WEB_SHIM_PUSH_TOKEN }} 32 | NPM_TOKEN: ${{ secrets.NPM_WEB_SHIM_PUSH_TOKEN }} 33 | run: | 34 | npx -p semantic-release \ 35 | -p @semantic-release/changelog \ 36 | -p @semantic-release/git \ 37 | -p @semantic-release/github \ 38 | -p @semantic-release/npm \ 39 | -p conventional-changelog-conventionalcommits \ 40 | semantic-release 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # builds 7 | build 8 | dist 9 | .rpt2_cache 10 | 11 | # misc 12 | .DS_Store 13 | .env 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # builds 7 | build 8 | .rpt2_cache 9 | 10 | # misc 11 | .DS_Store 12 | .env 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | .babelrc; 18 | 19 | npm-debug.log* 20 | example 21 | 22 | .github 23 | .releaserc.json 24 | 25 | .eslintignore 26 | .gitignore -------------------------------------------------------------------------------- /.releaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "branches": ["main"], 3 | "tagFormat": "${version}", 4 | "plugins": [ 5 | [ 6 | "@semantic-release/commit-analyzer", 7 | { 8 | "releaseRules": [ 9 | { 10 | "breaking": true, 11 | "release": "minor" 12 | }, 13 | { 14 | "type": "feat", 15 | "release": "minor" 16 | }, 17 | { 18 | "type": "fix", 19 | "release": "patch" 20 | }, 21 | { 22 | "type": "docs", 23 | "release": "patch" 24 | }, 25 | { 26 | "type": "perf", 27 | "release": "patch" 28 | }, 29 | { 30 | "type": "refactor", 31 | "release": "patch" 32 | }, 33 | { 34 | "type": "style", 35 | "release": "patch" 36 | }, 37 | { 38 | "type": "test", 39 | "release": "patch" 40 | }, 41 | { 42 | "type": "build", 43 | "release": "patch" 44 | }, 45 | { 46 | "type": "chore", 47 | "scope": "deps", 48 | "release": "patch" 49 | } 50 | ] 51 | } 52 | ], 53 | [ 54 | "@semantic-release/release-notes-generator", 55 | { 56 | "preset": "conventionalcommits", 57 | "writerOpts": { 58 | "types": [ 59 | { 60 | "type": "feat", 61 | "section": "Features" 62 | }, 63 | { 64 | "type": "fix", 65 | "section": "Bug Fixes" 66 | }, 67 | { 68 | "type": "docs", 69 | "section": "Documentation", 70 | "hidden": false 71 | }, 72 | { 73 | "type": "deps", 74 | "section": "Dependency Updates", 75 | "hidden": false 76 | }, 77 | { 78 | "type": "chore", 79 | "hidden": true 80 | }, 81 | { 82 | "type": "style", 83 | "hidden": true 84 | }, 85 | { 86 | "type": "refactor", 87 | "hidden": true 88 | }, 89 | { 90 | "type": "perf", 91 | "hidden": true 92 | }, 93 | { 94 | "type": "test", 95 | "hidden": true 96 | } 97 | ] 98 | } 99 | } 100 | ], 101 | [ 102 | "@semantic-release/changelog", 103 | { 104 | "changelogFile": "CHANGELOG.md", 105 | "changelogTitle": "# Changelog" 106 | } 107 | ], 108 | [ 109 | "@semantic-release/npm", 110 | { 111 | "pkgRoot": "." 112 | } 113 | ], 114 | [ 115 | "@semantic-release/git", 116 | { 117 | "assets": ["dist/**", "package.json", "CHANGELOG.md"], 118 | "message": "chore(release): ${nextRelease.version}\n\n${nextRelease.notes} [skip ci]" 119 | } 120 | ], 121 | "@semantic-release/github" 122 | ] 123 | } 124 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 16 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.workingDirectories": ["./package/", "./example/"] 3 | } 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [3.2.3](https://github.com/OneSignal/react-onesignal/compare/3.2.2...3.2.3) (2025-06-06) 4 | 5 | ### Bug Fixes 6 | 7 | * sync with web-shim-codegen v3.0.5 ([2d2b0e7](https://github.com/OneSignal/react-onesignal/commit/2d2b0e718a6dd51efe142fd1f416029ce113fd42)) 8 | 9 | ## [3.2.2](https://github.com/OneSignal/react-onesignal/compare/3.2.1...3.2.2) (2025-03-28) 10 | 11 | ### Bug Fixes 12 | 13 | * add promise reject for init call ([daadfa8](https://github.com/OneSignal/react-onesignal/commit/daadfa8de3ba98a2b9bd81a497187c4ef07cbc30)) 14 | * add promise reject for init call ([f951175](https://github.com/OneSignal/react-onesignal/commit/f9511751b930cc65ec78e355f07056c54ac997be)) 15 | 16 | ## [3.2.1](https://github.com/OneSignal/react-onesignal/compare/3.2.0...3.2.1) (2025-03-27) 17 | 18 | ### Bug Fixes 19 | 20 | * lower node engines range ([216c428](https://github.com/OneSignal/react-onesignal/commit/216c4280ecf1aea2722676e5f59f5797b75abbed)) 21 | 22 | ## [3.2.0](https://github.com/OneSignal/react-onesignal/compare/3.1.1...3.2.0) (2025-03-24) 23 | 24 | ### Features 25 | 26 | * sync with web-shim-codegen v3.0.2 ([1a23688](https://github.com/OneSignal/react-onesignal/commit/1a23688ba8cb42533ad561ef460eaacf2c9be6d9)) 27 | 28 | ## [3.1.1](https://github.com/OneSignal/react-onesignal/compare/3.1.0...3.1.1) (2025-03-14) 29 | 30 | ## [3.1.0](https://github.com/OneSignal/react-onesignal/compare/3.0.1...3.1.0) (2025-03-14) 31 | 32 | ### Features 33 | 34 | * sync with web-shim-codegen v3.0.1 ([93627ba](https://github.com/OneSignal/react-onesignal/commit/93627ba19f6aac555b68ef726b7d6ae9c4aa2a31)), closes [#143](https://github.com/OneSignal/react-onesignal/issues/143) 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Modified MIT License 2 | 3 | Copyright 2022 OneSignal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | 1. The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | 2. All copies of substantial portions of the Software may only be used in connection 16 | with services provided by OneSignal. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /MigrationGuide.md: -------------------------------------------------------------------------------- 1 | 2 | # Migration Guide 3 | Review the updated documentation in the [README](https://github.com/OneSignal/react-onesignal/blob/master/README.md). 4 | 5 | > Migrating from version 1 to 2 (see [v2 migration guide](#version-2)) 6 | 7 | ## Version 3 8 | ### Intro 9 | In this release, we are making a significant shift from a device-centered model to a user-centered model. This means that instead of identifying devices, we now focus on identifying individual users. This update is part of a larger effort to shift towards a user-oriented omni-channel messaging system. 10 | 11 | To facilitate this change, the externalId approach for identifying users is being replaced by the login and logout methods. In addition, the SDK now makes use of namespaces such as User, Notifications, and Slidedown to better separate code. 12 | 13 | This guide will walk you through these and other important changes in the version 16 update. 14 | 15 | ### Overview 16 | Under the new model, the concept of a "player" is being updated to include three new concepts: users, subscriptions, and aliases. 17 | 18 | ### Users 19 | Users own subscriptions and are identified by aliases which are used to point to users using different alias schemes. 20 | 21 | ### Subscriptions 22 | 23 | Subscriptions refer to the way in which a user can receive various communication methods offered by OneSignal, including push notifications, SMS, and email. 24 | 25 | ### Aliases 26 | Aliases are identifiers that point to users and are made up of an alias label and id. Users can have multiple aliases. Consider the need to identify a user with your own application's unique identifier as well as identifiers from other integrated applications. 27 | 28 | The SDK will use `external_id` as the default alias label for the public `OneSignal.login("1234")` method. 29 | 30 | **Alias Example:** 31 | ``` 32 | "aliases": [ 33 | { 34 | "label": "external_id", 35 | "id": "1234" 36 | }, 37 | { 38 | "label": "my_alias", 39 | "id": "5678" 40 | } 41 | ] 42 | ``` 43 | 44 | ```js 45 | // WebSDK-specific example 46 | { 47 | external_id: "1234", 48 | my_alias: "5678" 49 | } 50 | ``` 51 | 52 | # Guide 53 | ## 1. Setup Changes 54 | ### Service Worker File 55 | 56 | From: 57 | ```js 58 | importScripts("https://onesignal.com/sdks/OneSignalSDKWorker.js"); 59 | ``` 60 | 61 | To: 62 | ```js 63 | importScripts("https://onesignal.com/sdks/web/v16/OneSignalSDK.sw.js"); 64 | ``` 65 | 66 | ## 2. External User ID 67 | Update any usages of `OneSignal.setExternalId` to `OneSignal.login` or `OneSignal.logout` 68 | From: 69 | ```js 70 | OneSignal.setExternalId("myId"); 71 | ``` 72 | 73 | To: 74 | ```js 75 | OneSignal.login("myId"); 76 | ``` 77 | 78 | Use `OneSignal.logout();` instead anywhere you have `OneSignal.setExternalId("");` or are setting it to `null`. 79 | 80 | ## 3. API Changes 81 | Update your code to use the new API. The following namespaces are on the `OneSignal` object. 82 | 83 | ### User Namespace 84 | 85 | Example: 86 | ```js 87 | OneSignal.User.addAlias("my_alias", "1234"); 88 | ``` 89 | 90 | All user functions are synchronous. 91 | 92 | | Function Name | Description | Argument List | 93 | | --------------- | ---------------------------------------------- | ------------------------------------ | 94 | | `addAlias` | Adds a new alias for the current user. | `label: string, id: string` | 95 | | `addAliases` | Adds multiple aliases for the current user. | `aliases: { [key: string]: string }` | 96 | | `removeAlias` | Removes an alias for the current user. | `label: string` | 97 | | `removeAliases` | Removes multiple aliases for the current user. | `labels: string[]` | 98 | | `addEmail` | Adds an email address for the current user. | `email: string` | 99 | | `removeEmail` | Removes an email address for the current user. | `email: string` | 100 | | `addSms` | Adds an SMS number for the current user. | `smsNumber: string` | 101 | | `removeSms` | Removes an SMS number for the current user. | `smsNumber: string` | 102 | | `addTag` | Adds a tag for the current user. | `key: string, value: string` | 103 | | `addTags` | Adds multiple tags for the current user. | `tags: { [key: string]: string }` | 104 | | `removeTag` | Removes a tag for the current user. | `key: string` | 105 | | `removeTags` | Removes multiple tags for the current user. | `keys: string[]` | 106 | 107 | ### Notifications Namespace 108 | 109 | Example: 110 | ```js 111 | await OneSignal.Notifications.requestPermission(); 112 | ``` 113 | 114 | 115 | | Sync/Async | Property/Function | Description | Argument List | 116 | | ---------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | 117 | | `async` | `setDefaultUrl()` | Sets the default URL for notifications. | `url` (string) | 118 | | `async` | `setDefaultTitle()` | Sets the default title for notifications. | `title` (string) | 119 | | `sync` | `isPushSupported()` | Returns true if the current browser supports web push. | | 120 | | `async` | `requestPermission()` | Requests push notifications permission via the native browser prompt. | | 121 | | | `permission` | Returns true if your site has permission to display notifications. | | 122 | | | `permissionNative` | Returns browser's native notification permission status; `"default"`(end-user has not accept or decided yet), `"granted"`, or `"denied"`. | | 123 | | `sync` | `addEventListener()` | Adds an event listener for the following events:

- `click`
- `foregroundWillDisplay`
- `dismiss`
- `permissionPromptDisplay`
- `permissionChange`*
* argument type: bool | - `` (string)
- `(arg: ) => {}` (callback) | 124 | | `sync` | `removeEventListener()` | Removes the event listener. | `() => {}` (the event listener you want to remove) | 125 | 126 | 127 | 128 | ### Slidedown Namespace 129 | 130 | Example: 131 | ```js 132 | await OneSignal.Slidedown.promptPush(); 133 | ``` 134 | 135 | | Sync/Async | Function Name | Description | Argument List | 136 | | ---------- | ---------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------- | 137 | | `async` | `promptPush` | Displays the notification permission prompt. | `options` (AutoPromptOptions) | 138 | | `async` | `promptPushCategories` | Displays the notification permission prompt for notification categories. | `options` (AutoPromptOptions) | 139 | | `async` | `promptSms` | Displays the SMS subscription prompt. | `options` (AutoPromptOptions) | 140 | | `async` | `promptEmail` | Displays the email subscription prompt. | `options` (AutoPromptOptions) | 141 | | `async` | `promptSmsAndEmail` | Displays the SMS and email subscription prompts. | `options` (AutoPromptOptions) | 142 | | `sync` | `addEventListener` | Adds an event listener for the `slidedownShown` event. | - `event` ("slidedownShown"),
- `listener` ((wasShown: boolean) => void) | 143 | | `sync` | `removeEventListener` | Removes an event listener for the `slidedownShown` event. | - `event` ("slidedownShown")
- `listener` ((wasShown: boolean) => void) | 144 | 145 | 146 | 147 | ### Push Subscription Namespace 148 | 149 | Example: 150 | ```js 151 | OneSignal.User.PushSubscription.optIn(); 152 | ``` 153 | 154 | | Sync/Async | Property/Function | Description | Argument List | 155 | | ---------- | ----------------------- | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | 156 | | | `id` | Gets the current user's ID. | | 157 | | | `token` | Gets the current user's push notification token. | | 158 | | | `optedIn` | Gets a boolean value indicating whether the current user is subscribed to push notifications. | | 159 | | `async` | `optIn()` | Subscribes the current user to push notifications. | | 160 | | `async` | `optOut()` | Unsubscribes the current user from push notifications. | | 161 | | `sync` | `addEventListener()` | Adds an event listener for the `change` event. | - `event` ("change")
- `listener` ((change: SubscriptionChangeEvent) => void) | 162 | | `sync` | `removeEventListener()` | Removes an event listener for the `change` event. | - `event` ("change")
- `listener` ((change: SubscriptionChangeEvent) => void) | 163 | 164 | ### Debug Namespace 165 | 166 | Example: 167 | ```js 168 | OneSignal.Debug.setLogLevel(“trace”); 169 | ``` 170 | 171 | | Function Name | Description | Argument List | 172 | | --------------- | ---------------------------------------------- | ------------------------------------ | 173 | | `setLogLevel` | Turns on logging with the given log level. | `setLogLevel: string`
- `"trace"`
- `"debug"`
- `"info"`
- `"warn"`
- `"error"` | 174 | 175 | # Limitations 176 | * HTTP environments are no longer supported. 177 | * AMP environments are not supported. 178 | * Identity verification not available yet, coming soon. 179 | 180 | # Glossary 181 | 182 | **OneSignal user** 183 | 184 |       *(noun) lowercase* 185 | 186 |       A user of the OneSignal service. 187 | 188 | **user** 189 | 190 |       *(noun) lowercase* 191 | 192 |       An end-user of an application using the OneSignal service. They may or may not have a subscription. 193 | 194 | **user ID** 195 | 196 |       *(noun) lowercase* 197 | 198 |       A OneSignal-provisioned unique identifier for Users (User.onesignal_id). 199 | 200 | 201 | **user external ID** 202 | 203 |       *(noun) lowercase* 204 | 205 |       A customer-provisioned unique identifier for Users (User.external_id). 206 | 207 | 208 | **user alias** 209 | 210 |       *(noun) lowercase* 211 | 212 |       A customer provisioned key-value pair used to uniquely identify a User. 213 | 214 | 215 | **subscription** 216 | 217 |       *(noun) lowercase* 218 | 219 |       An established communication channel between an App and its User, such as a push-subscribed device, email address, or SMS-subscribed phone number. 220 | 221 | 222 | **subscription ID** 223 | 224 |       *(noun) lowercase* 225 | 226 |       A OneSignal-provisioned unique identifier for a single subscription. 227 | 228 | 229 | **notification** 230 | 231 |       *(noun) lowercase* 232 | 233 |       A unidirectional outbound communication message from an App to one or more Users via their Subscriptions. 234 | 235 | 236 | **notification ID** 237 | 238 |       *(noun) lowercase* 239 | 240 |       A OneSignal-provisioned unique identifier for Notifications (Notification.id). 241 | 242 | 243 | **notification external ID** 244 | 245 |       *(noun) lowercase* 246 | 247 |       A customer-provisioned unique identifier for Notifications (Notification.external_id). 248 | 249 | 250 | ## Version 2 251 |
252 | Click to expand 253 | 254 | Version 2.0 includes breaking changes. Make sure to follow this migration guide carefully, review the updated documentation, and test your application thoroughly. 255 | 256 | ## Key Changes 257 | - Update your OneSignal initialization function (see below) 258 | - Remove the initialization hook (now handled for you automagically) 259 | - Event listeners are now set up using the `on` function 260 | - New functions supporting newer OneSignal features 261 | 262 | ### OneSignal Initialization 263 | The initialization function has been changed to match 1:1 with the underlying OneSignal WebSDK. The function has been renamed `init`. The `appId` is now set via the single config options argument passed to the `init` function: 264 | 265 | ```js 266 | import OneSignal from 'react-onesignal'; 267 | 268 | OneSignal.init({ appId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' }); 269 | ``` 270 | 271 | Furthermore, there is no longer a need to wrap the initialization in the `useOneSignalSetup` hook. The order of functions relative to the OneSignal initialization no longer matters (although we still recommend initializing OneSignal in a top-level component). 272 | 273 | ### Event Listeners 274 | Event listeners can now be added directly via the `on` function. This function takes an event string and a callback. 275 | 276 | ### New Features 277 | We have added new functions to support the latest OneSignal functions and features. 278 | 279 | ### Typings 280 | Typings are included in the package automatically. See below for a full list of the functions included in this package: 281 | ```ts 282 | interface OneSignal { 283 | init(options?: any): Promise 284 | on(event: string, listener: Function): void 285 | off(event: string, listener: Function): void 286 | once(event: string, listener: Function): void 287 | isPushNotificationsEnabled(callback?: Action): Promise 288 | showHttpPrompt(options?: AutoPromptOptions): void 289 | registerForPushNotifications(options?: RegisterOptions): Promise 290 | setDefaultNotificationUrl(url: string): void 291 | setDefaultTitle(title: string): void 292 | getTags(callback?: Action): void 293 | sendTag(key: string, value: any, callback?: Action): Promise 294 | sendTags(tags: TagsObject, callback?: Action): Promise 295 | deleteTag(tag: string): Promise> 296 | deleteTags(tags: Array, callback?: Action>): Promise> 297 | addListenerForNotificationOpened(callback?: Action): void 298 | setSubscription(newSubscription: boolean): Promise 299 | showHttpPermissionRequest(options?: AutoPromptOptions): Promise 300 | showNativePrompt(): Promise 301 | showSlidedownPrompt(options?: AutoPromptOptions): Promise 302 | showCategorySlidedown(options?: AutoPromptOptions): Promise 303 | showSmsSlidedown(options?: AutoPromptOptions): Promise 304 | showEmailSlidedown(options?: AutoPromptOptions): Promise 305 | showSmsAndEmailSlidedown(options?: AutoPromptOptions): Promise 306 | getNotificationPermission(onComplete?: Function): Promise 307 | getUserId(callback?: Action): Promise 308 | getSubscription(callback?: Action): Promise 309 | setEmail(email: string, options?: SetEmailOptions): Promise 310 | setSMSNumber(smsNumber: string, options?: SetSMSOptions): Promise 311 | logoutEmail(): void 312 | logoutSMS(): void 313 | setExternalUserId(externalUserId: string | undefined | null, authHash?: string): Promise 314 | removeExternalUserId(): Promise 315 | getExternalUserId(): Promise 316 | provideUserConsent(consent: boolean): Promise 317 | getEmailId(callback?: Action): Promise 318 | getSMSId(callback?: Action): Promise 319 | sendOutcome(outcomeName: string, outcomeWeight?: number | undefined): Promise 320 | } 321 | ``` 322 | 323 | ## Summary 324 | Consider the above changes when migrating to version 2 and make sure to thoroughly test your application. 325 | 326 | Enjoy! 327 | 328 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Welcome to react-onesignal 👋

2 |

3 | 4 | Version 5 | 6 | 7 | Documentation 8 | 9 | 10 | Maintenance 11 | 12 | 13 | Twitter: onesignal 14 | 15 |

16 | 17 | > This is a JavaScript module that can be used to easily include [OneSignal](https://onesignal.com/) code in a website or app in practically any JS front-end codebase (not limited to React). 18 | 19 | - 🏠 [Homepage](https://github.com/OneSignal/react-onesignal#readme) 20 | - 🖤 [npm](https://www.npmjs.com/package/react-onesignal) 21 | 22 | OneSignal is the world's leader for Mobile Push Notifications, Web Push, and In-App Messaging. It is trusted by 2 million+ developers to send 12 billion Push Notifications per day. 23 | 24 | You can find more information on OneSignal [here](https://onesignal.com/). 25 | 26 | ### Migration Guides 27 | 28 | Version 3.0 was recently released and includes breaking changes. See the [Migration Guide](https://github.com/OneSignal/react-onesignal/blob/main/MigrationGuide.md) to update your implementation. 29 | 30 | ## Contents 31 | 32 | - [Install](#install) 33 | - [Usage](#usage) 34 | - [API](#onesignal-api) 35 | - [Advanced Usage](#advanced-usage) 36 | 37 | --- 38 | 39 | ## Install 40 | 41 | ### npm 42 | 43 | ```bash 44 | npm install --save react-onesignal 45 | ``` 46 | 47 | ### yarn 48 | 49 | ```bash 50 | yarn add react-onesignal 51 | ``` 52 | 53 | --- 54 | 55 | ## Usage 56 | 57 | Initialize OneSignal with your `appId` via the `options` parameter: 58 | 59 | ```js 60 | import OneSignal from 'react-onesignal'; 61 | 62 | OneSignal.init({ appId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' }); 63 | ``` 64 | 65 | The `init` function returns a promise that resolves when OneSignal is loaded. 66 | 67 | **Examples** 68 | 69 | ```js 70 | await OneSignal.init({ appId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' }); 71 | // do other stuff 72 | ``` 73 | 74 | --- 75 | 76 | ```js 77 | const [initialized, setInitialized] = useState(false); 78 | OneSignal.init({ appId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' }).then(() => { 79 | setInitialized(true); 80 | OneSignal.Slidedown.promptPush(); 81 | // do other stuff 82 | }); 83 | ``` 84 | 85 | ### Init Options 86 | You can pass other [options](https://documentation.onesignal.com/docs/web-sdk-reference#init) to the `init` function. Use these options to configure personalized prompt options, auto-resubscribe, and more. 87 | 88 |
89 | Expand to see more options 90 | 91 | | Property Name | Type | Description | 92 | | -------------------------------- | -------------------- | -------------------------------------------------------- | 93 | | `appId` | `string` | The ID of your OneSignal app. | 94 | | `autoRegister` | `boolean` (optional) | Whether or not to automatically register the user. | 95 | | `autoResubscribe` | `boolean` (optional) | Whether or not to automatically resubscribe the user. | 96 | | `path` | `string` (optional) | The path to the OneSignal service worker file. | 97 | | `serviceWorkerPath` | `string` (optional) | The path to the OneSignal service worker script. | 98 | | `serviceWorkerUpdaterPath` | `string` (optional) | The path to the OneSignal service worker updater script. | 99 | | `subdomainName` | `string` (optional) | The subdomain of your OneSignal app. | 100 | | `allowLocalhostAsSecureOrigin` | `boolean` (optional) | Whether or not to allow localhost as a secure origin. | 101 | | `requiresUserPrivacyConsent` | `boolean` (optional) | Whether or not the user's consent is required. | 102 | | `persistNotification` | `boolean` (optional) | Whether or not notifications should persist. | 103 | | `notificationClickHandlerMatch` | `string` (optional) | The URL match pattern for notification clicks. | 104 | | `notificationClickHandlerAction` | `string` (optional) | The action to perform when a notification is clicked. | 105 | | `welcomeNotification` | `object` (optional) | The welcome notification configuration. | 106 | | `notifyButton` | `object` (optional) | The notify button configuration. | 107 | | `promptOptions` | `object` (optional) | Additional options for the subscription prompt. | 108 | | `webhooks` | `object` (optional) | The webhook configuration. | 109 | | `[key: string]` | `any` | Additional properties can be added as needed. | 110 | 111 | **Service Worker Params** 112 | You can customize the location and filenames of service worker assets. You are also able to specify the specific scope that your service worker should control. You can read more [here](https://documentation.onesignal.com/docs/onesignal-service-worker-faq#sdk-parameter-reference-for-service-workers). 113 | 114 | In this distribution, you can specify the parameters via the following: 115 | 116 | | Field | Details | 117 | | -------------------- | -------------------------------------------------------------------------------------------------------------------- | 118 | | `serviceWorkerParam` | Use to specify the scope, or the path the service worker has control of. Example: `{ scope: "/js/push/onesignal/" }` | 119 | | `serviceWorkerPath` | The path to the service worker file. | 120 | 121 |
122 | 123 | --- 124 | 125 | ### Service Worker File 126 | 127 | If you haven't done so already, you will need to add the [OneSignal Service Worker file](https://github.com/OneSignal/OneSignal-Website-SDK/files/11480764/OneSignalSDK-v16-ServiceWorker.zip) to your site ([learn more](https://documentation.onesignal.com/docs/web-push-quickstart#step-6-upload-files)). 128 | 129 | The OneSignal SDK file must be publicly accessible. You can put them in your top-level root or a subdirectory. However, if you are placing the file not on top-level root make sure to specify the path via the service worker params in the init options (see section above). 130 | 131 | **Tip:** 132 | Visit `https://yoursite.com/OneSignalSDKWorker.js` in the address bar to make sure the files are being served successfully. 133 | 134 | --- 135 | 136 | ### Typescript 137 | 138 | This package includes Typescript support. 139 | 140 | ```ts 141 | interface IOneSignalOneSignal { 142 | Slidedown: IOneSignalSlidedown; 143 | Notifications: IOneSignalNotifications; 144 | Session: IOneSignalSession; 145 | User: IOneSignalUser; 146 | Debug: IOneSignalDebug; 147 | login(externalId: string, jwtToken?: string): Promise; 148 | logout(): Promise; 149 | init(options: IInitObject): Promise; 150 | setConsentGiven(consent: boolean): Promise; 151 | setConsentRequired(requiresConsent: boolean): Promise; 152 | } 153 | ``` 154 | 155 | ### OneSignal API 156 | 157 | See the official [OneSignal WebSDK reference](https://documentation.onesignal.com/docs/web-sdk-reference) for information on all available SDK functions. 158 | 159 | --- 160 | 161 | ## Advanced Usage 162 | 163 | ### Events and Event Listeners 164 | 165 | Use listeners to react to OneSignal-related events: 166 | 167 | ### Notifications Namespace 168 | 169 | | Event Name | Callback Argument Type | 170 | | ------------------------- | -------------------------------------- | 171 | | 'click' | NotificationClickEvent | 172 | | 'foregroundWillDisplay' | NotificationForegroundWillDisplayEvent | 173 | | 'dismiss' | NotificationDismissEvent | 174 | | 'permissionChange' | boolean | 175 | | 'permissionPromptDisplay' | void | 176 | 177 | ### Slidedown Namespace 178 | 179 | | Event Name | Callback Argument Type | 180 | | ---------------- | ---------------------- | 181 | | 'slidedownShown' | boolean | 182 | 183 | ### Push Subscription Namespace 184 | 185 | | Event Name | Callback Argument Type | 186 | | ---------- | ---------------------- | 187 | | 'change' | boolean | 188 | 189 | **Example** 190 | 191 | ```js 192 | OneSignal.Notifications.addEventListener('click', (event) => { 193 | console.log('The notification was clicked!', event); 194 | }); 195 | ``` 196 | 197 | 198 | 199 | See the [OneSignal WebSDK Reference](https://documentation.onesignal.com/docs/web-sdk-reference#addeventlistener-push-notification) for all available event listeners. 200 | 201 | ## Troubleshooting 202 | 203 | ### `window.OneSignal already defined as 'object'!` 204 | 205 | You will get this error if you initialize twice. Make sure you are only initializing one time. When wrapped with `React.StrictMode`, your app might be rendering twice. 206 | 207 | ## Example App 208 | 209 | This repo includes an `example` React application implementing OneSignal. It was created using `create-react-app`. The app uses this repository's root level directory as the `react-onesignal` package and will bundle any changes on every run. 210 | 211 | --- 212 | 213 | ## 🤝 Contributing 214 | 215 | Contributions, issues and feature requests are welcome!
Feel free to check [issues page](https://github.com/OneSignal/react-onesignal/issues). 216 | 217 | ## Show your support 218 | 219 | Give a ⭐️ if this project helped you! 220 | 221 | ## OneSignal 222 | 223 | - [Website](https://onesignal.com) 224 | - Twitter: [@onesignal](https://twitter.com/onesignal) 225 | - Github: [@OneSignal](https://github.com/OneSignal) 226 | - LinkedIn: [@onesignal](https://linkedin.com/company/onesignal) 227 | 228 | ## Discord 229 | 230 | Reach out to us via our [Discord server](https://discord.com/invite/EP7gf6Uz7G)! 231 | 232 | ## 📝 License 233 | 234 | Copyright © 2023 [OneSignal](https://github.com/OneSignal).
235 | This project is [Modified MIT](https://github.com/OneSignal/react-onesignal/blob/master/LICENSE) licensed. 236 | 237 | ## Thanks 238 | 239 | Special thanks to [pedro-lb](https://github.com/pedro-lb) and others for work on the project this package is [based on](https://github.com/pedro-lb/react-onesignal). 240 | 241 | 242 | 243 | 244 | Enjoy! 245 | -------------------------------------------------------------------------------- /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Window { 3 | OneSignalDeferred?: OneSignalDeferredLoadedCallback[]; 4 | OneSignal?: IOneSignalOneSignal; 5 | safari?: { 6 | pushNotification: any; 7 | }; 8 | } 9 | } 10 | export interface AutoPromptOptions { 11 | force?: boolean; 12 | forceSlidedownOverNative?: boolean; 13 | slidedownPromptOptions?: IOneSignalAutoPromptOptions; 14 | } 15 | export interface IOneSignalAutoPromptOptions { 16 | force?: boolean; 17 | forceSlidedownOverNative?: boolean; 18 | isInUpdateMode?: boolean; 19 | categoryOptions?: IOneSignalCategories; 20 | } 21 | export interface IOneSignalCategories { 22 | positiveUpdateButton: string; 23 | negativeUpdateButton: string; 24 | savingButtonText: string; 25 | errorButtonText: string; 26 | updateMessage: string; 27 | tags: IOneSignalTagCategory[]; 28 | } 29 | export interface IOneSignalTagCategory { 30 | tag: string; 31 | label: string; 32 | checked?: boolean; 33 | } 34 | export type PushSubscriptionNamespaceProperties = { 35 | id: string | null | undefined; 36 | token: string | null | undefined; 37 | optedIn: boolean; 38 | }; 39 | export type SubscriptionChangeEvent = { 40 | previous: PushSubscriptionNamespaceProperties; 41 | current: PushSubscriptionNamespaceProperties; 42 | }; 43 | export type NotificationEventName = 'click' | 'foregroundWillDisplay' | 'dismiss' | 'permissionChange' | 'permissionPromptDisplay'; 44 | export type SlidedownEventName = 'slidedownAllowClick' | 'slidedownCancelClick' | 'slidedownClosed' | 'slidedownQueued' | 'slidedownShown'; 45 | export type OneSignalDeferredLoadedCallback = (onesignal: IOneSignalOneSignal) => void; 46 | export interface IOSNotification { 47 | /** 48 | * The OneSignal notification id; 49 | * - Primary id on OneSignal's REST API and dashboard 50 | */ 51 | readonly notificationId: string; 52 | /** 53 | * Visible title text on the notification 54 | */ 55 | readonly title?: string; 56 | /** 57 | * Visible body text on the notification 58 | */ 59 | readonly body: string; 60 | /** 61 | * Visible icon the notification; URL format 62 | */ 63 | readonly icon?: string; 64 | /** 65 | * Visible small badgeIcon that displays on some devices; URL format 66 | * Example: On Android's status bar 67 | */ 68 | readonly badgeIcon?: string; 69 | /** 70 | * Visible image on the notification; URL format 71 | */ 72 | readonly image?: string; 73 | /** 74 | * Visible buttons on the notification 75 | */ 76 | readonly actionButtons?: IOSNotificationActionButton[]; 77 | /** 78 | * If this value is the same as existing notification, it will replace it 79 | * Can be set when creating the notification with "Web Push Topic" on the dashboard 80 | * or web_push_topic from the REST API. 81 | */ 82 | readonly topic?: string; 83 | /** 84 | * Custom object that was sent with the notification; 85 | * definable when creating the notification from the OneSignal REST API or dashboard 86 | */ 87 | readonly additionalData?: object; 88 | /** 89 | * URL to open when clicking or tapping on the notification 90 | */ 91 | readonly launchURL?: string; 92 | /** 93 | * Confirm the push was received by reporting back to OneSignal 94 | */ 95 | readonly confirmDelivery: boolean; 96 | } 97 | export interface IOSNotificationActionButton { 98 | /** 99 | * Any unique identifier to represent which button was clicked. This is typically passed back to the service worker 100 | * and host page through events to identify which button was clicked. 101 | * e.g. 'like-button' 102 | */ 103 | readonly actionId: string; 104 | /** 105 | * The notification action button's text. 106 | */ 107 | readonly text: string; 108 | /** 109 | * A valid publicly reachable HTTPS URL to an image. 110 | */ 111 | readonly icon?: string; 112 | /** 113 | * The URL to open the web browser to when this action button is clicked. 114 | */ 115 | readonly launchURL?: string; 116 | } 117 | export interface NotificationClickResult { 118 | readonly actionId?: string; 119 | readonly url?: string; 120 | } 121 | export type NotificationEventTypeMap = { 122 | 'click': NotificationClickEvent; 123 | 'foregroundWillDisplay': NotificationForegroundWillDisplayEvent; 124 | 'dismiss': NotificationDismissEvent; 125 | 'permissionChange': boolean; 126 | 'permissionPromptDisplay': void; 127 | }; 128 | export interface NotificationForegroundWillDisplayEvent { 129 | readonly notification: IOSNotification; 130 | preventDefault(): void; 131 | } 132 | export interface NotificationDismissEvent { 133 | notification: IOSNotification; 134 | } 135 | export interface NotificationClickEvent { 136 | readonly notification: IOSNotification; 137 | readonly result: NotificationClickResult; 138 | } 139 | export type UserChangeEvent = { 140 | current: UserNamespaceProperties; 141 | }; 142 | export type UserNamespaceProperties = { 143 | onesignalId: string | undefined; 144 | externalId: string | undefined; 145 | }; 146 | export interface IInitObject { 147 | appId: string; 148 | subdomainName?: string; 149 | requiresUserPrivacyConsent?: boolean; 150 | promptOptions?: { 151 | slidedown: { 152 | prompts: { 153 | /** 154 | * Whether to automatically display the prompt. 155 | * `true` will display the prompt based on the delay options. 156 | * `false` will prevent the prompt from displaying until the Slidedowns methods are used. 157 | */ 158 | autoPrompt: boolean; 159 | /** 160 | * Only available for type: category. Up to 10 categories. 161 | * @example 162 | * categories: [{ tag: 'local_news', label: 'Local News' }] // The user will be tagged with local_news but will see "Local News" in the prompt. 163 | */ 164 | categories: { 165 | /** Should identify the action. */ 166 | tag: string; 167 | /** What the user will see. */ 168 | label: string; 169 | }[]; 170 | /** 171 | * The delay options for the prompt. 172 | * @example delay: { pageViews: 3, timeDelay: 20 } // The user will not be shown the prompt until 20 seconds after the 3rd page view. 173 | */ 174 | delay: { 175 | /** The number of pages a user needs to visit before the prompt is displayed. */ 176 | pageViews?: number; 177 | /** The number of seconds a user needs to wait before the prompt is displayed.Both options must be satisfied for the prompt to display */ 178 | timeDelay?: number; 179 | }; 180 | /** 181 | * The text to display in the prompt. 182 | */ 183 | text?: { 184 | /** The callout asking the user to opt-in. Up to 90 characters. */ 185 | actionMessage?: string; 186 | /** Triggers the opt-in. Up to 15 characters. */ 187 | acceptButton?: string; 188 | /** Cancels opt-in. Up to 15 characters. */ 189 | cancelMessage?: string; 190 | /** The message of the confirmation prompt displayed after the email and/or phone number is provided. Up to 90 characters. */ 191 | confirmMessage?: string; 192 | /** Identifies the email text field. Up to 15 characters. */ 193 | emailLabel?: string; 194 | /** Cancels the category update. Up to 15 characters. */ 195 | negativeUpdateButton?: string; 196 | /** Saves the updated category tags. Up to 15 characters. */ 197 | positiveUpdateButton?: string; 198 | /** Identifies the phone number text field. Up to 15 characters. */ 199 | smsLabel?: string; 200 | /** A different message shown to subscribers presented the prompt again to update categories. Up to 90 characters. */ 201 | updateMessage?: string; 202 | }; 203 | /** 204 | * The type of prompt to display. 205 | * `push` which is the Slide Prompt without categories. 206 | * `category` which is the Slide Prompt with categories. 207 | * `sms` only asks for phone number. 208 | * `email` only asks for email address. 209 | * `smsAndEmail` asks for both phone number and email address. 210 | */ 211 | type: 'push' | 'category' | 'sms' | 'email' | 'smsAndEmail'; 212 | }[]; 213 | }; 214 | }; 215 | welcomeNotification?: { 216 | /** 217 | * Disables sending a welcome notification to new site visitors. If you want to disable welcome notifications, this is the only option you need. 218 | * @deprecated Use 'disable' instead. This will be removed in a future version. 219 | */ 220 | disabled?: boolean; 221 | /** 222 | * Disables sending a welcome notification to new site visitors. If you want to disable welcome notifications, this is the only option you need. 223 | */ 224 | disable?: boolean; 225 | /** 226 | * The welcome notification's message. You can localize this to your own language. 227 | * If left blank or set to blank, the default of 'Thanks for subscribing!' will be used. 228 | */ 229 | message: string; 230 | /** 231 | * The welcome notification's title. You can localize this to your own language. If not set, or left blank, the site's title will be used. 232 | * Set to one space ' ' to clear the title, although this is not recommended. 233 | */ 234 | title?: string; 235 | /** 236 | * By default, clicking the welcome notification does not open any link. 237 | * This is recommended because the user has just visited your site and subscribed. 238 | */ 239 | url?: string; 240 | }; 241 | /** 242 | * Will enable customization of the notify/subscription bell button. 243 | */ 244 | notifyButton?: { 245 | /** 246 | * A function you define that returns true to show the Subscription Bell, or false to hide it. 247 | * Typically used the hide the Subscription Bell after the user is subscribed. 248 | * This function is not re-evaluated on every state change; this function is only evaluated once when the Subscription Bell begins to show. 249 | */ 250 | displayPredicate?: () => boolean | Promise; 251 | /** 252 | * Enable the Subscription Bell. The Subscription Bell is otherwise disabled by default. 253 | */ 254 | enable?: boolean; 255 | /** Specify CSS-valid pixel offsets using bottom, left, and right. */ 256 | offset?: { 257 | bottom: string; 258 | left: string; 259 | right: string; 260 | }; 261 | /** 262 | * If `true`, the Subscription Bell will display an icon that there is 1 unread message. 263 | * When hovering over the Subscription Bell, the user will see custom text set by message.prenotify. 264 | */ 265 | prenotify: boolean; 266 | /** Either `bottom-left` or `bottom-right`. The Subscription Bell will be fixed at this location on your page. */ 267 | position?: 'bottom-left' | 'bottom-right'; 268 | /** Set `false` to hide the 'Powered by OneSignal' text in the Subscription Bell dialog popup. */ 269 | showCredit: boolean; 270 | /** 271 | * The Subscription Bell will initially appear at one of these sizes, and then shrink down to size `small` after the user subscribes. 272 | */ 273 | size?: 'small' | 'medium' | 'large'; 274 | /** Customize the Subscription Bell text. */ 275 | text: { 276 | 'dialog.blocked.message': string; 277 | 'dialog.blocked.title': string; 278 | 'dialog.main.button.subscribe': string; 279 | 'dialog.main.button.unsubscribe': string; 280 | 'dialog.main.title': string; 281 | 'message.action.resubscribed': string; 282 | 'message.action.subscribed': string; 283 | 'message.action.subscribing': string; 284 | 'message.action.unsubscribed': string; 285 | 'message.prenotify': string; 286 | 'tip.state.blocked': string; 287 | 'tip.state.subscribed': string; 288 | 'tip.state.unsubscribed': string; 289 | }; 290 | }; 291 | persistNotification?: boolean; 292 | webhooks?: { 293 | /** 294 | * Enable this setting only if your server has CORS enabled and supports non-simple CORS requests. 295 | * If this setting is disabled, your webhook will not need CORS to receive data, but it will not receive the custom headers. 296 | * The simplest option is to leave it disabled. 297 | * @default false 298 | */ 299 | cors: boolean; 300 | /** 301 | * This event occurs after a notification is clicked. 302 | * @example https://site.com/hook 303 | */ 304 | 'notification.clicked'?: string; 305 | /** 306 | * This event occurs after a notification is intentionally dismissed by the user (clicking the notification body or one of the notification action buttons does not trigger the dismissed webhook), 307 | * after a group of notifications are all dismissed (with this notification as part of that group), or after a notification expires on its own time and disappears. This event is supported on Chrome only. 308 | * @example https://site.com/hook 309 | */ 310 | 'notification.dismissed'?: string; 311 | /** 312 | * This event occurs after a notification is displayed. 313 | * @example https://site.com/hook 314 | */ 315 | 'notification.willDisplay'?: string; 316 | }; 317 | autoResubscribe?: boolean; 318 | autoRegister?: boolean; 319 | notificationClickHandlerMatch?: string; 320 | notificationClickHandlerAction?: string; 321 | path?: string; 322 | serviceWorkerParam?: { 323 | scope: string; 324 | }; 325 | serviceWorkerPath?: string; 326 | serviceWorkerOverrideForTypical?: boolean; 327 | serviceWorkerUpdaterPath?: string; 328 | allowLocalhostAsSecureOrigin?: boolean; 329 | [key: string]: any; 330 | } 331 | export interface IOneSignalOneSignal { 332 | Slidedown: IOneSignalSlidedown; 333 | Notifications: IOneSignalNotifications; 334 | Session: IOneSignalSession; 335 | User: IOneSignalUser; 336 | Debug: IOneSignalDebug; 337 | login(externalId: string, jwtToken?: string): Promise; 338 | logout(): Promise; 339 | init(options: IInitObject): Promise; 340 | setConsentGiven(consent: boolean): Promise; 341 | setConsentRequired(requiresConsent: boolean): Promise; 342 | } 343 | export interface IOneSignalNotifications { 344 | permissionNative: NotificationPermission; 345 | permission: boolean; 346 | setDefaultUrl(url: string): Promise; 347 | setDefaultTitle(title: string): Promise; 348 | isPushSupported(): boolean; 349 | requestPermission(): Promise; 350 | addEventListener(event: K, listener: (obj: NotificationEventTypeMap[K]) => void): void; 351 | removeEventListener(event: K, listener: (obj: NotificationEventTypeMap[K]) => void): void; 352 | } 353 | export interface IOneSignalSlidedown { 354 | promptPush(options?: AutoPromptOptions): Promise; 355 | promptPushCategories(options?: AutoPromptOptions): Promise; 356 | promptSms(options?: AutoPromptOptions): Promise; 357 | promptEmail(options?: AutoPromptOptions): Promise; 358 | promptSmsAndEmail(options?: AutoPromptOptions): Promise; 359 | addEventListener(event: SlidedownEventName, listener: (wasShown: boolean) => void): void; 360 | removeEventListener(event: SlidedownEventName, listener: (wasShown: boolean) => void): void; 361 | } 362 | export interface IOneSignalDebug { 363 | setLogLevel(logLevel: 'trace' | 'debug' | 'info' | 'warn' | 'error'): void; 364 | } 365 | export interface IOneSignalSession { 366 | sendOutcome(outcomeName: string, outcomeWeight?: number): Promise; 367 | sendUniqueOutcome(outcomeName: string): Promise; 368 | } 369 | export interface IOneSignalUser { 370 | onesignalId: string | undefined; 371 | externalId: string | undefined; 372 | PushSubscription: IOneSignalPushSubscription; 373 | addAlias(label: string, id: string): void; 374 | addAliases(aliases: { 375 | [key: string]: string; 376 | }): void; 377 | removeAlias(label: string): void; 378 | removeAliases(labels: string[]): void; 379 | addEmail(email: string): void; 380 | removeEmail(email: string): void; 381 | addSms(smsNumber: string): void; 382 | removeSms(smsNumber: string): void; 383 | addTag(key: string, value: string): void; 384 | addTags(tags: { 385 | [key: string]: string; 386 | }): void; 387 | removeTag(key: string): void; 388 | removeTags(keys: string[]): void; 389 | getTags(): { 390 | [key: string]: string; 391 | }; 392 | addEventListener(event: 'change', listener: (change: UserChangeEvent) => void): void; 393 | removeEventListener(event: 'change', listener: (change: UserChangeEvent) => void): void; 394 | setLanguage(language: string): void; 395 | getLanguage(): string; 396 | } 397 | export interface IOneSignalPushSubscription { 398 | id: string | null | undefined; 399 | token: string | null | undefined; 400 | optedIn: boolean | undefined; 401 | optIn(): Promise; 402 | optOut(): Promise; 403 | addEventListener(event: 'change', listener: (change: SubscriptionChangeEvent) => void): void; 404 | removeEventListener(event: 'change', listener: (change: SubscriptionChangeEvent) => void): void; 405 | } 406 | declare const OneSignal: IOneSignalOneSignal; 407 | export default OneSignal; 408 | -------------------------------------------------------------------------------- /dist/index.es.js: -------------------------------------------------------------------------------- 1 | const u = "onesignal-sdk", l = "https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js"; 2 | let d = !1, s = !1; 3 | typeof window < "u" && (window.OneSignalDeferred = window.OneSignalDeferred || [], f()); 4 | function c() { 5 | s = !0; 6 | } 7 | function f() { 8 | const i = document.createElement("script"); 9 | i.id = u, i.defer = !0, i.src = l, i.onerror = () => { 10 | c(); 11 | }, document.head.appendChild(i); 12 | } 13 | function w() { 14 | return g() || S(); 15 | } 16 | function p() { 17 | return window.top !== window && // isContextIframe 18 | navigator.vendor === "Apple Computer, Inc." && // isSafari 19 | navigator.platform === "MacIntel"; 20 | } 21 | function S() { 22 | return window.safari && typeof window.safari.pushNotification < "u" || p(); 23 | } 24 | function g() { 25 | return typeof PushSubscriptionOptions < "u" && PushSubscriptionOptions.prototype.hasOwnProperty("applicationServerKey"); 26 | } 27 | const h = () => w(), m = (i) => { 28 | var e; 29 | return d ? Promise.reject("OneSignal is already initialized.") : !i || !i.appId ? Promise.reject("You need to provide your OneSignal appId.") : document ? (((e = i.welcomeNotification) == null ? void 0 : e.disabled) !== void 0 && (i.welcomeNotification.disable = i.welcomeNotification.disabled), new Promise((n, r) => { 30 | var t; 31 | (t = window.OneSignalDeferred) == null || t.push((o) => { 32 | o.init(i).then(() => { 33 | d = !0, n(); 34 | }).catch(r); 35 | }); 36 | })) : Promise.reject("Document is not defined."); 37 | }; 38 | function O(i, e) { 39 | return new Promise((n, r) => { 40 | var t; 41 | if (s) { 42 | r(new Error("OneSignal script failed to load.")); 43 | return; 44 | } 45 | try { 46 | (t = window.OneSignalDeferred) == null || t.push((o) => { 47 | o.login(i, e).then(() => n()).catch((a) => r(a)); 48 | }); 49 | } catch (o) { 50 | r(o); 51 | } 52 | }); 53 | } 54 | function v() { 55 | return new Promise((i, e) => { 56 | var n; 57 | if (s) { 58 | e(new Error("OneSignal script failed to load.")); 59 | return; 60 | } 61 | try { 62 | (n = window.OneSignalDeferred) == null || n.push((r) => { 63 | r.logout().then(() => i()).catch((t) => e(t)); 64 | }); 65 | } catch (r) { 66 | e(r); 67 | } 68 | }); 69 | } 70 | function D(i) { 71 | return new Promise((e, n) => { 72 | var r; 73 | if (s) { 74 | n(new Error("OneSignal script failed to load.")); 75 | return; 76 | } 77 | try { 78 | (r = window.OneSignalDeferred) == null || r.push((t) => { 79 | t.setConsentGiven(i).then(() => e()).catch((o) => n(o)); 80 | }); 81 | } catch (t) { 82 | n(t); 83 | } 84 | }); 85 | } 86 | function E(i) { 87 | return new Promise((e, n) => { 88 | var r; 89 | if (s) { 90 | n(new Error("OneSignal script failed to load.")); 91 | return; 92 | } 93 | try { 94 | (r = window.OneSignalDeferred) == null || r.push((t) => { 95 | t.setConsentRequired(i).then(() => e()).catch((o) => n(o)); 96 | }); 97 | } catch (t) { 98 | n(t); 99 | } 100 | }); 101 | } 102 | function P(i) { 103 | return new Promise((e, n) => { 104 | var r; 105 | if (s) { 106 | n(new Error("OneSignal script failed to load.")); 107 | return; 108 | } 109 | try { 110 | (r = window.OneSignalDeferred) == null || r.push((t) => { 111 | t.Slidedown.promptPush(i).then(() => e()).catch((o) => n(o)); 112 | }); 113 | } catch (t) { 114 | n(t); 115 | } 116 | }); 117 | } 118 | function L(i) { 119 | return new Promise((e, n) => { 120 | var r; 121 | if (s) { 122 | n(new Error("OneSignal script failed to load.")); 123 | return; 124 | } 125 | try { 126 | (r = window.OneSignalDeferred) == null || r.push((t) => { 127 | t.Slidedown.promptPushCategories(i).then(() => e()).catch((o) => n(o)); 128 | }); 129 | } catch (t) { 130 | n(t); 131 | } 132 | }); 133 | } 134 | function U(i) { 135 | return new Promise((e, n) => { 136 | var r; 137 | if (s) { 138 | n(new Error("OneSignal script failed to load.")); 139 | return; 140 | } 141 | try { 142 | (r = window.OneSignalDeferred) == null || r.push((t) => { 143 | t.Slidedown.promptSms(i).then(() => e()).catch((o) => n(o)); 144 | }); 145 | } catch (t) { 146 | n(t); 147 | } 148 | }); 149 | } 150 | function A(i) { 151 | return new Promise((e, n) => { 152 | var r; 153 | if (s) { 154 | n(new Error("OneSignal script failed to load.")); 155 | return; 156 | } 157 | try { 158 | (r = window.OneSignalDeferred) == null || r.push((t) => { 159 | t.Slidedown.promptEmail(i).then(() => e()).catch((o) => n(o)); 160 | }); 161 | } catch (t) { 162 | n(t); 163 | } 164 | }); 165 | } 166 | function N(i) { 167 | return new Promise((e, n) => { 168 | var r; 169 | if (s) { 170 | n(new Error("OneSignal script failed to load.")); 171 | return; 172 | } 173 | try { 174 | (r = window.OneSignalDeferred) == null || r.push((t) => { 175 | t.Slidedown.promptSmsAndEmail(i).then(() => e()).catch((o) => n(o)); 176 | }); 177 | } catch (t) { 178 | n(t); 179 | } 180 | }); 181 | } 182 | function y(i, e) { 183 | var n; 184 | (n = window.OneSignalDeferred) == null || n.push((r) => { 185 | r.Slidedown.addEventListener(i, e); 186 | }); 187 | } 188 | function b(i, e) { 189 | var n; 190 | (n = window.OneSignalDeferred) == null || n.push((r) => { 191 | r.Slidedown.removeEventListener(i, e); 192 | }); 193 | } 194 | function I(i) { 195 | return new Promise((e, n) => { 196 | var r; 197 | if (s) { 198 | n(new Error("OneSignal script failed to load.")); 199 | return; 200 | } 201 | try { 202 | (r = window.OneSignalDeferred) == null || r.push((t) => { 203 | t.Notifications.setDefaultUrl(i).then(() => e()).catch((o) => n(o)); 204 | }); 205 | } catch (t) { 206 | n(t); 207 | } 208 | }); 209 | } 210 | function T(i) { 211 | return new Promise((e, n) => { 212 | var r; 213 | if (s) { 214 | n(new Error("OneSignal script failed to load.")); 215 | return; 216 | } 217 | try { 218 | (r = window.OneSignalDeferred) == null || r.push((t) => { 219 | t.Notifications.setDefaultTitle(i).then(() => e()).catch((o) => n(o)); 220 | }); 221 | } catch (t) { 222 | n(t); 223 | } 224 | }); 225 | } 226 | function R() { 227 | return new Promise((i, e) => { 228 | var n; 229 | if (s) { 230 | e(new Error("OneSignal script failed to load.")); 231 | return; 232 | } 233 | try { 234 | (n = window.OneSignalDeferred) == null || n.push((r) => { 235 | r.Notifications.requestPermission().then(() => i()).catch((t) => e(t)); 236 | }); 237 | } catch (r) { 238 | e(r); 239 | } 240 | }); 241 | } 242 | function C(i, e) { 243 | var n; 244 | (n = window.OneSignalDeferred) == null || n.push((r) => { 245 | r.Notifications.addEventListener(i, e); 246 | }); 247 | } 248 | function q(i, e) { 249 | var n; 250 | (n = window.OneSignalDeferred) == null || n.push((r) => { 251 | r.Notifications.removeEventListener(i, e); 252 | }); 253 | } 254 | function G(i, e) { 255 | return new Promise((n, r) => { 256 | var t; 257 | if (s) { 258 | r(new Error("OneSignal script failed to load.")); 259 | return; 260 | } 261 | try { 262 | (t = window.OneSignalDeferred) == null || t.push((o) => { 263 | o.Session.sendOutcome(i, e).then(() => n()).catch((a) => r(a)); 264 | }); 265 | } catch (o) { 266 | r(o); 267 | } 268 | }); 269 | } 270 | function _(i) { 271 | return new Promise((e, n) => { 272 | var r; 273 | if (s) { 274 | n(new Error("OneSignal script failed to load.")); 275 | return; 276 | } 277 | try { 278 | (r = window.OneSignalDeferred) == null || r.push((t) => { 279 | t.Session.sendUniqueOutcome(i).then(() => e()).catch((o) => n(o)); 280 | }); 281 | } catch (t) { 282 | n(t); 283 | } 284 | }); 285 | } 286 | function k(i, e) { 287 | var n; 288 | (n = window.OneSignalDeferred) == null || n.push((r) => { 289 | r.User.addAlias(i, e); 290 | }); 291 | } 292 | function K(i) { 293 | var e; 294 | (e = window.OneSignalDeferred) == null || e.push((n) => { 295 | n.User.addAliases(i); 296 | }); 297 | } 298 | function x(i) { 299 | var e; 300 | (e = window.OneSignalDeferred) == null || e.push((n) => { 301 | n.User.removeAlias(i); 302 | }); 303 | } 304 | function V(i) { 305 | var e; 306 | (e = window.OneSignalDeferred) == null || e.push((n) => { 307 | n.User.removeAliases(i); 308 | }); 309 | } 310 | function z(i) { 311 | var e; 312 | (e = window.OneSignalDeferred) == null || e.push((n) => { 313 | n.User.addEmail(i); 314 | }); 315 | } 316 | function M(i) { 317 | var e; 318 | (e = window.OneSignalDeferred) == null || e.push((n) => { 319 | n.User.removeEmail(i); 320 | }); 321 | } 322 | function F(i) { 323 | var e; 324 | (e = window.OneSignalDeferred) == null || e.push((n) => { 325 | n.User.addSms(i); 326 | }); 327 | } 328 | function Y(i) { 329 | var e; 330 | (e = window.OneSignalDeferred) == null || e.push((n) => { 331 | n.User.removeSms(i); 332 | }); 333 | } 334 | function B(i, e) { 335 | var n; 336 | (n = window.OneSignalDeferred) == null || n.push((r) => { 337 | r.User.addTag(i, e); 338 | }); 339 | } 340 | function H(i) { 341 | var e; 342 | (e = window.OneSignalDeferred) == null || e.push((n) => { 343 | n.User.addTags(i); 344 | }); 345 | } 346 | function J(i) { 347 | var e; 348 | (e = window.OneSignalDeferred) == null || e.push((n) => { 349 | n.User.removeTag(i); 350 | }); 351 | } 352 | function Q(i) { 353 | var e; 354 | (e = window.OneSignalDeferred) == null || e.push((n) => { 355 | n.User.removeTags(i); 356 | }); 357 | } 358 | async function W() { 359 | var e; 360 | let i; 361 | return await ((e = window.OneSignalDeferred) == null ? void 0 : e.push((n) => { 362 | i = n.User.getTags(); 363 | })), i; 364 | } 365 | function X(i, e) { 366 | var n; 367 | (n = window.OneSignalDeferred) == null || n.push((r) => { 368 | r.User.addEventListener(i, e); 369 | }); 370 | } 371 | function Z(i, e) { 372 | var n; 373 | (n = window.OneSignalDeferred) == null || n.push((r) => { 374 | r.User.removeEventListener(i, e); 375 | }); 376 | } 377 | function $(i) { 378 | var e; 379 | (e = window.OneSignalDeferred) == null || e.push((n) => { 380 | n.User.setLanguage(i); 381 | }); 382 | } 383 | async function j() { 384 | var e; 385 | let i; 386 | return await ((e = window.OneSignalDeferred) == null ? void 0 : e.push((n) => { 387 | i = n.User.getLanguage(); 388 | })), i; 389 | } 390 | function ee() { 391 | return new Promise((i, e) => { 392 | var n; 393 | if (s) { 394 | e(new Error("OneSignal script failed to load.")); 395 | return; 396 | } 397 | try { 398 | (n = window.OneSignalDeferred) == null || n.push((r) => { 399 | r.User.PushSubscription.optIn().then(() => i()).catch((t) => e(t)); 400 | }); 401 | } catch (r) { 402 | e(r); 403 | } 404 | }); 405 | } 406 | function ne() { 407 | return new Promise((i, e) => { 408 | var n; 409 | if (s) { 410 | e(new Error("OneSignal script failed to load.")); 411 | return; 412 | } 413 | try { 414 | (n = window.OneSignalDeferred) == null || n.push((r) => { 415 | r.User.PushSubscription.optOut().then(() => i()).catch((t) => e(t)); 416 | }); 417 | } catch (r) { 418 | e(r); 419 | } 420 | }); 421 | } 422 | function ie(i, e) { 423 | var n; 424 | (n = window.OneSignalDeferred) == null || n.push((r) => { 425 | r.User.PushSubscription.addEventListener(i, e); 426 | }); 427 | } 428 | function re(i, e) { 429 | var n; 430 | (n = window.OneSignalDeferred) == null || n.push((r) => { 431 | r.User.PushSubscription.removeEventListener(i, e); 432 | }); 433 | } 434 | function te(i) { 435 | var e; 436 | (e = window.OneSignalDeferred) == null || e.push((n) => { 437 | n.Debug.setLogLevel(i); 438 | }); 439 | } 440 | const oe = { 441 | get id() { 442 | var i, e, n; 443 | return (n = (e = (i = window.OneSignal) == null ? void 0 : i.User) == null ? void 0 : e.PushSubscription) == null ? void 0 : n.id; 444 | }, 445 | get token() { 446 | var i, e, n; 447 | return (n = (e = (i = window.OneSignal) == null ? void 0 : i.User) == null ? void 0 : e.PushSubscription) == null ? void 0 : n.token; 448 | }, 449 | get optedIn() { 450 | var i, e, n; 451 | return (n = (e = (i = window.OneSignal) == null ? void 0 : i.User) == null ? void 0 : e.PushSubscription) == null ? void 0 : n.optedIn; 452 | }, 453 | optIn: ee, 454 | optOut: ne, 455 | addEventListener: ie, 456 | removeEventListener: re 457 | }, se = { 458 | get onesignalId() { 459 | var i, e; 460 | return (e = (i = window.OneSignal) == null ? void 0 : i.User) == null ? void 0 : e.onesignalId; 461 | }, 462 | get externalId() { 463 | var i, e; 464 | return (e = (i = window.OneSignal) == null ? void 0 : i.User) == null ? void 0 : e.externalId; 465 | }, 466 | addAlias: k, 467 | addAliases: K, 468 | removeAlias: x, 469 | removeAliases: V, 470 | addEmail: z, 471 | removeEmail: M, 472 | addSms: F, 473 | removeSms: Y, 474 | addTag: B, 475 | addTags: H, 476 | removeTag: J, 477 | removeTags: Q, 478 | getTags: W, 479 | addEventListener: X, 480 | removeEventListener: Z, 481 | setLanguage: $, 482 | getLanguage: j, 483 | PushSubscription: oe 484 | }, ae = { 485 | sendOutcome: G, 486 | sendUniqueOutcome: _ 487 | }, de = { 488 | setLogLevel: te 489 | }, ue = { 490 | promptPush: P, 491 | promptPushCategories: L, 492 | promptSms: U, 493 | promptEmail: A, 494 | promptSmsAndEmail: N, 495 | addEventListener: y, 496 | removeEventListener: b 497 | }, le = { 498 | get permissionNative() { 499 | var i, e; 500 | return ((e = (i = window.OneSignal) == null ? void 0 : i.Notifications) == null ? void 0 : e.permissionNative) ?? "default"; 501 | }, 502 | get permission() { 503 | var i, e; 504 | return ((e = (i = window.OneSignal) == null ? void 0 : i.Notifications) == null ? void 0 : e.permission) ?? !1; 505 | }, 506 | setDefaultUrl: I, 507 | setDefaultTitle: T, 508 | isPushSupported: h, 509 | requestPermission: R, 510 | addEventListener: C, 511 | removeEventListener: q 512 | }, ce = { 513 | login: O, 514 | logout: v, 515 | init: m, 516 | setConsentGiven: D, 517 | setConsentRequired: E, 518 | Slidedown: ue, 519 | Notifications: le, 520 | Session: ae, 521 | User: se, 522 | Debug: de 523 | }, fe = ce; 524 | export { 525 | fe as default 526 | }; 527 | //# sourceMappingURL=index.es.js.map 528 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | "use strict";const u="onesignal-sdk",l="https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js";let d=!1,s=!1;typeof window<"u"&&(window.OneSignalDeferred=window.OneSignalDeferred||[],f());function c(){s=!0}function f(){const i=document.createElement("script");i.id=u,i.defer=!0,i.src=l,i.onerror=()=>{c()},document.head.appendChild(i)}function w(){return g()||S()}function p(){return window.top!==window&&navigator.vendor==="Apple Computer, Inc."&&navigator.platform==="MacIntel"}function S(){return window.safari&&typeof window.safari.pushNotification<"u"||p()}function g(){return typeof PushSubscriptionOptions<"u"&&PushSubscriptionOptions.prototype.hasOwnProperty("applicationServerKey")}const h=()=>w(),m=i=>{var e;return d?Promise.reject("OneSignal is already initialized."):!i||!i.appId?Promise.reject("You need to provide your OneSignal appId."):document?(((e=i.welcomeNotification)==null?void 0:e.disabled)!==void 0&&(i.welcomeNotification.disable=i.welcomeNotification.disabled),new Promise((n,r)=>{var t;(t=window.OneSignalDeferred)==null||t.push(o=>{o.init(i).then(()=>{d=!0,n()}).catch(r)})})):Promise.reject("Document is not defined.")};function O(i,e){return new Promise((n,r)=>{var t;if(s){r(new Error("OneSignal script failed to load."));return}try{(t=window.OneSignalDeferred)==null||t.push(o=>{o.login(i,e).then(()=>n()).catch(a=>r(a))})}catch(o){r(o)}})}function v(){return new Promise((i,e)=>{var n;if(s){e(new Error("OneSignal script failed to load."));return}try{(n=window.OneSignalDeferred)==null||n.push(r=>{r.logout().then(()=>i()).catch(t=>e(t))})}catch(r){e(r)}})}function D(i){return new Promise((e,n)=>{var r;if(s){n(new Error("OneSignal script failed to load."));return}try{(r=window.OneSignalDeferred)==null||r.push(t=>{t.setConsentGiven(i).then(()=>e()).catch(o=>n(o))})}catch(t){n(t)}})}function E(i){return new Promise((e,n)=>{var r;if(s){n(new Error("OneSignal script failed to load."));return}try{(r=window.OneSignalDeferred)==null||r.push(t=>{t.setConsentRequired(i).then(()=>e()).catch(o=>n(o))})}catch(t){n(t)}})}function P(i){return new Promise((e,n)=>{var r;if(s){n(new Error("OneSignal script failed to load."));return}try{(r=window.OneSignalDeferred)==null||r.push(t=>{t.Slidedown.promptPush(i).then(()=>e()).catch(o=>n(o))})}catch(t){n(t)}})}function L(i){return new Promise((e,n)=>{var r;if(s){n(new Error("OneSignal script failed to load."));return}try{(r=window.OneSignalDeferred)==null||r.push(t=>{t.Slidedown.promptPushCategories(i).then(()=>e()).catch(o=>n(o))})}catch(t){n(t)}})}function U(i){return new Promise((e,n)=>{var r;if(s){n(new Error("OneSignal script failed to load."));return}try{(r=window.OneSignalDeferred)==null||r.push(t=>{t.Slidedown.promptSms(i).then(()=>e()).catch(o=>n(o))})}catch(t){n(t)}})}function A(i){return new Promise((e,n)=>{var r;if(s){n(new Error("OneSignal script failed to load."));return}try{(r=window.OneSignalDeferred)==null||r.push(t=>{t.Slidedown.promptEmail(i).then(()=>e()).catch(o=>n(o))})}catch(t){n(t)}})}function N(i){return new Promise((e,n)=>{var r;if(s){n(new Error("OneSignal script failed to load."));return}try{(r=window.OneSignalDeferred)==null||r.push(t=>{t.Slidedown.promptSmsAndEmail(i).then(()=>e()).catch(o=>n(o))})}catch(t){n(t)}})}function y(i,e){var n;(n=window.OneSignalDeferred)==null||n.push(r=>{r.Slidedown.addEventListener(i,e)})}function b(i,e){var n;(n=window.OneSignalDeferred)==null||n.push(r=>{r.Slidedown.removeEventListener(i,e)})}function I(i){return new Promise((e,n)=>{var r;if(s){n(new Error("OneSignal script failed to load."));return}try{(r=window.OneSignalDeferred)==null||r.push(t=>{t.Notifications.setDefaultUrl(i).then(()=>e()).catch(o=>n(o))})}catch(t){n(t)}})}function T(i){return new Promise((e,n)=>{var r;if(s){n(new Error("OneSignal script failed to load."));return}try{(r=window.OneSignalDeferred)==null||r.push(t=>{t.Notifications.setDefaultTitle(i).then(()=>e()).catch(o=>n(o))})}catch(t){n(t)}})}function R(){return new Promise((i,e)=>{var n;if(s){e(new Error("OneSignal script failed to load."));return}try{(n=window.OneSignalDeferred)==null||n.push(r=>{r.Notifications.requestPermission().then(()=>i()).catch(t=>e(t))})}catch(r){e(r)}})}function C(i,e){var n;(n=window.OneSignalDeferred)==null||n.push(r=>{r.Notifications.addEventListener(i,e)})}function q(i,e){var n;(n=window.OneSignalDeferred)==null||n.push(r=>{r.Notifications.removeEventListener(i,e)})}function G(i,e){return new Promise((n,r)=>{var t;if(s){r(new Error("OneSignal script failed to load."));return}try{(t=window.OneSignalDeferred)==null||t.push(o=>{o.Session.sendOutcome(i,e).then(()=>n()).catch(a=>r(a))})}catch(o){r(o)}})}function _(i){return new Promise((e,n)=>{var r;if(s){n(new Error("OneSignal script failed to load."));return}try{(r=window.OneSignalDeferred)==null||r.push(t=>{t.Session.sendUniqueOutcome(i).then(()=>e()).catch(o=>n(o))})}catch(t){n(t)}})}function k(i,e){var n;(n=window.OneSignalDeferred)==null||n.push(r=>{r.User.addAlias(i,e)})}function K(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.addAliases(i)})}function x(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.removeAlias(i)})}function V(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.removeAliases(i)})}function z(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.addEmail(i)})}function M(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.removeEmail(i)})}function F(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.addSms(i)})}function Y(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.removeSms(i)})}function B(i,e){var n;(n=window.OneSignalDeferred)==null||n.push(r=>{r.User.addTag(i,e)})}function H(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.addTags(i)})}function J(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.removeTag(i)})}function Q(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.removeTags(i)})}async function W(){var e;let i;return await((e=window.OneSignalDeferred)==null?void 0:e.push(n=>{i=n.User.getTags()})),i}function X(i,e){var n;(n=window.OneSignalDeferred)==null||n.push(r=>{r.User.addEventListener(i,e)})}function Z(i,e){var n;(n=window.OneSignalDeferred)==null||n.push(r=>{r.User.removeEventListener(i,e)})}function $(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.User.setLanguage(i)})}async function j(){var e;let i;return await((e=window.OneSignalDeferred)==null?void 0:e.push(n=>{i=n.User.getLanguage()})),i}function ee(){return new Promise((i,e)=>{var n;if(s){e(new Error("OneSignal script failed to load."));return}try{(n=window.OneSignalDeferred)==null||n.push(r=>{r.User.PushSubscription.optIn().then(()=>i()).catch(t=>e(t))})}catch(r){e(r)}})}function ne(){return new Promise((i,e)=>{var n;if(s){e(new Error("OneSignal script failed to load."));return}try{(n=window.OneSignalDeferred)==null||n.push(r=>{r.User.PushSubscription.optOut().then(()=>i()).catch(t=>e(t))})}catch(r){e(r)}})}function ie(i,e){var n;(n=window.OneSignalDeferred)==null||n.push(r=>{r.User.PushSubscription.addEventListener(i,e)})}function re(i,e){var n;(n=window.OneSignalDeferred)==null||n.push(r=>{r.User.PushSubscription.removeEventListener(i,e)})}function te(i){var e;(e=window.OneSignalDeferred)==null||e.push(n=>{n.Debug.setLogLevel(i)})}const oe={get id(){var i,e,n;return(n=(e=(i=window.OneSignal)==null?void 0:i.User)==null?void 0:e.PushSubscription)==null?void 0:n.id},get token(){var i,e,n;return(n=(e=(i=window.OneSignal)==null?void 0:i.User)==null?void 0:e.PushSubscription)==null?void 0:n.token},get optedIn(){var i,e,n;return(n=(e=(i=window.OneSignal)==null?void 0:i.User)==null?void 0:e.PushSubscription)==null?void 0:n.optedIn},optIn:ee,optOut:ne,addEventListener:ie,removeEventListener:re},se={get onesignalId(){var i,e;return(e=(i=window.OneSignal)==null?void 0:i.User)==null?void 0:e.onesignalId},get externalId(){var i,e;return(e=(i=window.OneSignal)==null?void 0:i.User)==null?void 0:e.externalId},addAlias:k,addAliases:K,removeAlias:x,removeAliases:V,addEmail:z,removeEmail:M,addSms:F,removeSms:Y,addTag:B,addTags:H,removeTag:J,removeTags:Q,getTags:W,addEventListener:X,removeEventListener:Z,setLanguage:$,getLanguage:j,PushSubscription:oe},ae={sendOutcome:G,sendUniqueOutcome:_},de={setLogLevel:te},ue={promptPush:P,promptPushCategories:L,promptSms:U,promptEmail:A,promptSmsAndEmail:N,addEventListener:y,removeEventListener:b},le={get permissionNative(){var i,e;return((e=(i=window.OneSignal)==null?void 0:i.Notifications)==null?void 0:e.permissionNative)??"default"},get permission(){var i,e;return((e=(i=window.OneSignal)==null?void 0:i.Notifications)==null?void 0:e.permission)??!1},setDefaultUrl:I,setDefaultTitle:T,isPushSupported:h,requestPermission:R,addEventListener:C,removeEventListener:q},ce={login:O,logout:v,init:m,setConsentGiven:D,setConsentRequired:E,Slidedown:ue,Notifications:le,Session:ae,User:se,Debug:de},fe=ce;module.exports=fe; 2 | //# sourceMappingURL=index.js.map 3 | -------------------------------------------------------------------------------- /dist/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sources":["../index.ts"],"sourcesContent":["const ONESIGNAL_SDK_ID = 'onesignal-sdk';\nconst ONE_SIGNAL_SCRIPT_SRC =\n 'https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js';\n\n// true if the script is successfully loaded from CDN.\nlet isOneSignalInitialized = false;\n// true if the script fails to load from CDN. A separate flag is necessary\n// to disambiguate between a CDN load failure and a delayed call to\n// OneSignal#init.\nlet isOneSignalScriptFailed = false;\n\nif (typeof window !== 'undefined') {\n window.OneSignalDeferred = window.OneSignalDeferred || [];\n addSDKScript();\n}\n\ndeclare global {\n interface Window {\n OneSignalDeferred?: OneSignalDeferredLoadedCallback[];\n OneSignal?: IOneSignalOneSignal;\n safari?: {\n pushNotification: any;\n };\n }\n}\n\n/* H E L P E R S */\n\nfunction handleOnError() {\n isOneSignalScriptFailed = true;\n}\n\nfunction addSDKScript() {\n const script = document.createElement('script');\n script.id = ONESIGNAL_SDK_ID;\n script.defer = true;\n script.src = ONE_SIGNAL_SCRIPT_SRC;\n\n // Always resolve whether or not the script is successfully initialized.\n // This is important for users who may block cdn.onesignal.com w/ adblock.\n script.onerror = () => {\n handleOnError();\n };\n\n document.head.appendChild(script);\n}\n\n/**\n * The following code is copied directly from the native SDK source file BrowserSupportsPush.ts\n * S T A R T\n */\n\n// Checks if the browser supports push notifications by checking if specific\n// classes and properties on them exist\nfunction isPushNotificationsSupported() {\n return supportsVapidPush() || supportsSafariPush();\n}\n\nfunction isMacOSSafariInIframe(): boolean {\n // Fallback detection for Safari on macOS in an iframe context\n return (\n window.top !== window && // isContextIframe\n navigator.vendor === 'Apple Computer, Inc.' && // isSafari\n navigator.platform === 'MacIntel'\n ); // isMacOS\n}\n\nfunction supportsSafariPush(): boolean {\n return (\n (window.safari && typeof window.safari.pushNotification !== 'undefined') ||\n isMacOSSafariInIframe()\n );\n}\n\n// Does the browser support the standard Push API\nfunction supportsVapidPush(): boolean {\n return (\n typeof PushSubscriptionOptions !== 'undefined' &&\n PushSubscriptionOptions.prototype.hasOwnProperty('applicationServerKey')\n );\n}\n/* E N D */\n\n/**\n * This is a SPECIAL FUNCTION\n * It is a hardcoded implementation copied from the upstream/native WebSDK since we want to return a boolean immediately\n * Natively, this is done via the shimloading mechanism (i.e. if the SDK loads, push is supported)\n * @PublicApi\n */\nconst isPushSupported = (): boolean => {\n return isPushNotificationsSupported();\n};\n\n/**\n * @PublicApi\n */\nconst init = (options: IInitObject): Promise => {\n if (isOneSignalInitialized) {\n return Promise.reject(`OneSignal is already initialized.`);\n }\n\n if (!options || !options.appId) {\n return Promise.reject('You need to provide your OneSignal appId.');\n }\n\n if (!document) {\n return Promise.reject(`Document is not defined.`);\n }\n\n // Handle both disabled and disable keys for welcome notification\n if (options.welcomeNotification?.disabled !== undefined) {\n options.welcomeNotification.disable = options.welcomeNotification.disabled;\n }\n\n return new Promise((resolve, reject) => {\n window.OneSignalDeferred?.push((OneSignal) => {\n OneSignal.init(options)\n .then(() => {\n isOneSignalInitialized = true;\n resolve();\n })\n .catch(reject);\n });\n });\n};\n\nexport interface AutoPromptOptions { force?: boolean; forceSlidedownOverNative?: boolean; slidedownPromptOptions?: IOneSignalAutoPromptOptions; }\nexport interface IOneSignalAutoPromptOptions { force?: boolean; forceSlidedownOverNative?: boolean; isInUpdateMode?: boolean; categoryOptions?: IOneSignalCategories; }\nexport interface IOneSignalCategories { positiveUpdateButton: string; negativeUpdateButton: string; savingButtonText: string; errorButtonText: string; updateMessage: string; tags: IOneSignalTagCategory[]; }\nexport interface IOneSignalTagCategory { tag: string; label: string; checked?: boolean; }\nexport type PushSubscriptionNamespaceProperties = { id: string | null | undefined; token: string | null | undefined; optedIn: boolean; };\nexport type SubscriptionChangeEvent = { previous: PushSubscriptionNamespaceProperties; current: PushSubscriptionNamespaceProperties; };\nexport type NotificationEventName = 'click' | 'foregroundWillDisplay' | 'dismiss' | 'permissionChange' | 'permissionPromptDisplay';\nexport type SlidedownEventName = 'slidedownAllowClick' | 'slidedownCancelClick' | 'slidedownClosed' | 'slidedownQueued' | 'slidedownShown';\nexport type OneSignalDeferredLoadedCallback = (onesignal: IOneSignalOneSignal) => void;\nexport interface IOSNotification {\n /**\n * The OneSignal notification id;\n * - Primary id on OneSignal's REST API and dashboard\n */\n readonly notificationId: string;\n\n /**\n * Visible title text on the notification\n */\n readonly title?: string;\n\n /**\n * Visible body text on the notification\n */\n readonly body: string;\n\n /**\n * Visible icon the notification; URL format\n */\n readonly icon?: string;\n\n /**\n * Visible small badgeIcon that displays on some devices; URL format\n * Example: On Android's status bar\n */\n readonly badgeIcon?: string;\n\n /**\n * Visible image on the notification; URL format\n */\n readonly image?: string;\n\n /**\n * Visible buttons on the notification\n */\n readonly actionButtons?: IOSNotificationActionButton[];\n\n /**\n * If this value is the same as existing notification, it will replace it\n * Can be set when creating the notification with \"Web Push Topic\" on the dashboard\n * or web_push_topic from the REST API.\n */\n readonly topic?: string;\n\n /**\n * Custom object that was sent with the notification;\n * definable when creating the notification from the OneSignal REST API or dashboard\n */\n readonly additionalData?: object;\n\n /**\n * URL to open when clicking or tapping on the notification\n */\n readonly launchURL?: string;\n\n /**\n * Confirm the push was received by reporting back to OneSignal\n */\n readonly confirmDelivery: boolean;\n}\n\nexport interface IOSNotificationActionButton {\n /**\n * Any unique identifier to represent which button was clicked. This is typically passed back to the service worker\n * and host page through events to identify which button was clicked.\n * e.g. 'like-button'\n */\n readonly actionId: string;\n /**\n * The notification action button's text.\n */\n readonly text: string;\n /**\n * A valid publicly reachable HTTPS URL to an image.\n */\n readonly icon?: string;\n /**\n * The URL to open the web browser to when this action button is clicked.\n */\n readonly launchURL?: string;\n}\n\nexport interface NotificationClickResult {\n readonly actionId?: string;\n readonly url?: string;\n}\n\nexport type NotificationEventTypeMap = {\n 'click': NotificationClickEvent;\n 'foregroundWillDisplay': NotificationForegroundWillDisplayEvent;\n 'dismiss': NotificationDismissEvent;\n 'permissionChange': boolean;\n 'permissionPromptDisplay': void;\n};\n\nexport interface NotificationForegroundWillDisplayEvent {\n readonly notification: IOSNotification;\n preventDefault(): void;\n}\n\nexport interface NotificationDismissEvent {\n notification: IOSNotification;\n}\n\nexport interface NotificationClickEvent {\n readonly notification: IOSNotification;\n readonly result: NotificationClickResult;\n}\n\nexport type UserChangeEvent = {\n current: UserNamespaceProperties;\n};\nexport type UserNamespaceProperties = {\n onesignalId: string | undefined;\n externalId: string | undefined;\n};\n\nexport interface IInitObject {\n appId: string;\n subdomainName?: string;\n requiresUserPrivacyConsent?: boolean;\n promptOptions?: {\n slidedown: {\n prompts: {\n /**\n * Whether to automatically display the prompt.\n * `true` will display the prompt based on the delay options.\n * `false` will prevent the prompt from displaying until the Slidedowns methods are used.\n */\n autoPrompt: boolean;\n\n /**\n * Only available for type: category. Up to 10 categories.\n * @example\n * categories: [{ tag: 'local_news', label: 'Local News' }] // The user will be tagged with local_news but will see \"Local News\" in the prompt.\n */\n categories: {\n /** Should identify the action. */\n tag: string;\n\n /** What the user will see. */\n label: string;\n }[];\n\n /**\n * The delay options for the prompt.\n * @example delay: { pageViews: 3, timeDelay: 20 } // The user will not be shown the prompt until 20 seconds after the 3rd page view.\n */\n delay: {\n /** The number of pages a user needs to visit before the prompt is displayed. */\n pageViews?: number;\n\n /** The number of seconds a user needs to wait before the prompt is displayed.Both options must be satisfied for the prompt to display */\n timeDelay?: number;\n };\n\n /**\n * The text to display in the prompt.\n */\n text?: {\n /** The callout asking the user to opt-in. Up to 90 characters. */\n actionMessage?: string;\n\n /** Triggers the opt-in. Up to 15 characters. */\n acceptButton?: string;\n\n /** Cancels opt-in. Up to 15 characters. */\n cancelMessage?: string;\n\n /** The message of the confirmation prompt displayed after the email and/or phone number is provided. Up to 90 characters. */\n confirmMessage?: string;\n\n /** Identifies the email text field. Up to 15 characters. */\n emailLabel?: string;\n\n /** Cancels the category update. Up to 15 characters. */\n negativeUpdateButton?: string;\n\n /** Saves the updated category tags. Up to 15 characters. */\n positiveUpdateButton?: string;\n\n /** Identifies the phone number text field. Up to 15 characters. */\n smsLabel?: string;\n\n /** A different message shown to subscribers presented the prompt again to update categories. Up to 90 characters. */\n updateMessage?: string;\n };\n\n /**\n * The type of prompt to display.\n * `push` which is the Slide Prompt without categories.\n * `category` which is the Slide Prompt with categories.\n * `sms` only asks for phone number.\n * `email` only asks for email address.\n * `smsAndEmail` asks for both phone number and email address.\n */\n type: 'push' | 'category' | 'sms' | 'email' | 'smsAndEmail';\n }[];\n };\n };\n welcomeNotification?: {\n /**\n * Disables sending a welcome notification to new site visitors. If you want to disable welcome notifications, this is the only option you need.\n * @deprecated Use 'disable' instead. This will be removed in a future version.\n */\n disabled?: boolean;\n\n /**\n * Disables sending a welcome notification to new site visitors. If you want to disable welcome notifications, this is the only option you need.\n */\n disable?: boolean;\n\n /**\n * The welcome notification's message. You can localize this to your own language.\n * If left blank or set to blank, the default of 'Thanks for subscribing!' will be used.\n */\n message: string;\n\n /**\n * The welcome notification's title. You can localize this to your own language. If not set, or left blank, the site's title will be used.\n * Set to one space ' ' to clear the title, although this is not recommended.\n */\n title?: string;\n\n /**\n * By default, clicking the welcome notification does not open any link.\n * This is recommended because the user has just visited your site and subscribed.\n */\n url?: string;\n };\n\n /**\n * Will enable customization of the notify/subscription bell button.\n */\n notifyButton?: {\n /**\n * A function you define that returns true to show the Subscription Bell, or false to hide it.\n * Typically used the hide the Subscription Bell after the user is subscribed.\n * This function is not re-evaluated on every state change; this function is only evaluated once when the Subscription Bell begins to show.\n */\n displayPredicate?: () => boolean | Promise;\n\n /**\n * Enable the Subscription Bell. The Subscription Bell is otherwise disabled by default.\n */\n enable?: boolean;\n\n /** Specify CSS-valid pixel offsets using bottom, left, and right. */\n offset?: { bottom: string; left: string; right: string };\n\n /**\n * If `true`, the Subscription Bell will display an icon that there is 1 unread message.\n * When hovering over the Subscription Bell, the user will see custom text set by message.prenotify.\n */\n prenotify: boolean;\n\n /** Either `bottom-left` or `bottom-right`. The Subscription Bell will be fixed at this location on your page. */\n position?: 'bottom-left' | 'bottom-right';\n\n /** Set `false` to hide the 'Powered by OneSignal' text in the Subscription Bell dialog popup. */\n showCredit: boolean;\n\n /**\n * The Subscription Bell will initially appear at one of these sizes, and then shrink down to size `small` after the user subscribes.\n */\n size?: 'small' | 'medium' | 'large';\n\n /** Customize the Subscription Bell text. */\n text: {\n 'dialog.blocked.message': string;\n 'dialog.blocked.title': string;\n 'dialog.main.button.subscribe': string;\n 'dialog.main.button.unsubscribe': string;\n 'dialog.main.title': string;\n 'message.action.resubscribed': string;\n 'message.action.subscribed': string;\n 'message.action.subscribing': string;\n 'message.action.unsubscribed': string;\n 'message.prenotify': string;\n 'tip.state.blocked': string;\n 'tip.state.subscribed': string;\n 'tip.state.unsubscribed': string;\n };\n };\n\n persistNotification?: boolean;\n webhooks?: {\n /**\n * Enable this setting only if your server has CORS enabled and supports non-simple CORS requests.\n * If this setting is disabled, your webhook will not need CORS to receive data, but it will not receive the custom headers.\n * The simplest option is to leave it disabled.\n * @default false\n */\n cors: boolean;\n\n /**\n * This event occurs after a notification is clicked.\n * @example https://site.com/hook\n */\n 'notification.clicked'?: string;\n\n /**\n * This event occurs after a notification is intentionally dismissed by the user (clicking the notification body or one of the notification action buttons does not trigger the dismissed webhook),\n * after a group of notifications are all dismissed (with this notification as part of that group), or after a notification expires on its own time and disappears. This event is supported on Chrome only.\n * @example https://site.com/hook\n */\n 'notification.dismissed'?: string;\n\n /**\n * This event occurs after a notification is displayed.\n * @example https://site.com/hook\n */\n 'notification.willDisplay'?: string;\n };\n autoResubscribe?: boolean;\n autoRegister?: boolean;\n notificationClickHandlerMatch?: string;\n notificationClickHandlerAction?: string;\n path?: string;\n serviceWorkerParam?: { scope: string };\n serviceWorkerPath?: string;\n serviceWorkerOverrideForTypical?: boolean;\n serviceWorkerUpdaterPath?: string;\n allowLocalhostAsSecureOrigin?: boolean;\n [key: string]: any;\n}\n\nexport interface IOneSignalOneSignal {\n\tSlidedown: IOneSignalSlidedown;\n\tNotifications: IOneSignalNotifications;\n\tSession: IOneSignalSession;\n\tUser: IOneSignalUser;\n\tDebug: IOneSignalDebug;\n\tlogin(externalId: string, jwtToken?: string): Promise;\n\tlogout(): Promise;\n\tinit(options: IInitObject): Promise;\n\tsetConsentGiven(consent: boolean): Promise;\n\tsetConsentRequired(requiresConsent: boolean): Promise;\n}\nexport interface IOneSignalNotifications {\n\tpermissionNative: NotificationPermission;\n\tpermission: boolean;\n\tsetDefaultUrl(url: string): Promise;\n\tsetDefaultTitle(title: string): Promise;\n\tisPushSupported(): boolean;\n\trequestPermission(): Promise;\n\taddEventListener(event: K, listener: (obj: NotificationEventTypeMap[K]) => void): void;\n\tremoveEventListener(event: K, listener: (obj: NotificationEventTypeMap[K]) => void): void;\n}\nexport interface IOneSignalSlidedown {\n\tpromptPush(options?: AutoPromptOptions): Promise;\n\tpromptPushCategories(options?: AutoPromptOptions): Promise;\n\tpromptSms(options?: AutoPromptOptions): Promise;\n\tpromptEmail(options?: AutoPromptOptions): Promise;\n\tpromptSmsAndEmail(options?: AutoPromptOptions): Promise;\n\taddEventListener(event: SlidedownEventName, listener: (wasShown: boolean) => void): void;\n\tremoveEventListener(event: SlidedownEventName, listener: (wasShown: boolean) => void): void;\n}\nexport interface IOneSignalDebug {\n\tsetLogLevel(logLevel: 'trace' | 'debug' | 'info' | 'warn' | 'error'): void;\n}\nexport interface IOneSignalSession {\n\tsendOutcome(outcomeName: string, outcomeWeight?: number): Promise;\n\tsendUniqueOutcome(outcomeName: string): Promise;\n}\nexport interface IOneSignalUser {\n\tonesignalId: string | undefined;\n\texternalId: string | undefined;\n\tPushSubscription: IOneSignalPushSubscription;\n\taddAlias(label: string, id: string): void;\n\taddAliases(aliases: { [key: string]: string }): void;\n\tremoveAlias(label: string): void;\n\tremoveAliases(labels: string[]): void;\n\taddEmail(email: string): void;\n\tremoveEmail(email: string): void;\n\taddSms(smsNumber: string): void;\n\tremoveSms(smsNumber: string): void;\n\taddTag(key: string, value: string): void;\n\taddTags(tags: { [key: string]: string }): void;\n\tremoveTag(key: string): void;\n\tremoveTags(keys: string[]): void;\n\tgetTags(): { [key: string]: string };\n\taddEventListener(event: 'change', listener: (change: UserChangeEvent) => void): void;\n\tremoveEventListener(event: 'change', listener: (change: UserChangeEvent) => void): void;\n\tsetLanguage(language: string): void;\n\tgetLanguage(): string;\n}\nexport interface IOneSignalPushSubscription {\n\tid: string | null | undefined;\n\ttoken: string | null | undefined;\n\toptedIn: boolean | undefined;\n\toptIn(): Promise;\n\toptOut(): Promise;\n\taddEventListener(event: 'change', listener: (change: SubscriptionChangeEvent) => void): void;\n\tremoveEventListener(event: 'change', listener: (change: SubscriptionChangeEvent) => void): void;\n}\nfunction oneSignalLogin(externalId: string, jwtToken?: string): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.login(externalId, jwtToken).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction oneSignalLogout(): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.logout().then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction oneSignalSetConsentGiven(consent: boolean): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.setConsentGiven(consent).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction oneSignalSetConsentRequired(requiresConsent: boolean): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.setConsentRequired(requiresConsent).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction slidedownPromptPush(options?: AutoPromptOptions): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Slidedown.promptPush(options).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction slidedownPromptPushCategories(options?: AutoPromptOptions): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Slidedown.promptPushCategories(options).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction slidedownPromptSms(options?: AutoPromptOptions): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Slidedown.promptSms(options).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction slidedownPromptEmail(options?: AutoPromptOptions): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Slidedown.promptEmail(options).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction slidedownPromptSmsAndEmail(options?: AutoPromptOptions): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Slidedown.promptSmsAndEmail(options).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction slidedownAddEventListener(event: SlidedownEventName, listener: (wasShown: boolean) => void): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Slidedown.addEventListener(event, listener);\n });\n \n}\nfunction slidedownRemoveEventListener(event: SlidedownEventName, listener: (wasShown: boolean) => void): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Slidedown.removeEventListener(event, listener);\n });\n \n}\nfunction notificationsSetDefaultUrl(url: string): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Notifications.setDefaultUrl(url).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction notificationsSetDefaultTitle(title: string): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Notifications.setDefaultTitle(title).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction notificationsRequestPermission(): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Notifications.requestPermission().then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction notificationsAddEventListener(event: K, listener: (obj: NotificationEventTypeMap[K]) => void): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Notifications.addEventListener(event, listener);\n });\n \n}\nfunction notificationsRemoveEventListener(event: K, listener: (obj: NotificationEventTypeMap[K]) => void): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Notifications.removeEventListener(event, listener);\n });\n \n}\nfunction sessionSendOutcome(outcomeName: string, outcomeWeight?: number): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Session.sendOutcome(outcomeName, outcomeWeight).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction sessionSendUniqueOutcome(outcomeName: string): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Session.sendUniqueOutcome(outcomeName).then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction userAddAlias(label: string, id: string): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.addAlias(label, id);\n });\n \n}\nfunction userAddAliases(aliases: { [key: string]: string }): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.addAliases(aliases);\n });\n \n}\nfunction userRemoveAlias(label: string): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.removeAlias(label);\n });\n \n}\nfunction userRemoveAliases(labels: string[]): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.removeAliases(labels);\n });\n \n}\nfunction userAddEmail(email: string): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.addEmail(email);\n });\n \n}\nfunction userRemoveEmail(email: string): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.removeEmail(email);\n });\n \n}\nfunction userAddSms(smsNumber: string): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.addSms(smsNumber);\n });\n \n}\nfunction userRemoveSms(smsNumber: string): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.removeSms(smsNumber);\n });\n \n}\nfunction userAddTag(key: string, value: string): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.addTag(key, value);\n });\n \n}\nfunction userAddTags(tags: { [key: string]: string }): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.addTags(tags);\n });\n \n}\nfunction userRemoveTag(key: string): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.removeTag(key);\n });\n \n}\nfunction userRemoveTags(keys: string[]): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.removeTags(keys);\n });\n \n}\n// @ts-expect-error - return non-Promise type despite needing to await OneSignalDeferred\nasync function userGetTags(): { [key: string]: string } {\n let retVal: { [key: string]: string };\n await window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n retVal = OneSignal.User.getTags();\n });\n return retVal;\n}\nfunction userAddEventListener(event: 'change', listener: (change: UserChangeEvent) => void): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.addEventListener(event, listener);\n });\n \n}\nfunction userRemoveEventListener(event: 'change', listener: (change: UserChangeEvent) => void): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.removeEventListener(event, listener);\n });\n \n}\nfunction userSetLanguage(language: string): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.setLanguage(language);\n });\n \n}\n// @ts-expect-error - return non-Promise type despite needing to await OneSignalDeferred\nasync function userGetLanguage(): string {\n let retVal: string;\n await window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n retVal = OneSignal.User.getLanguage();\n });\n return retVal;\n}\nfunction pushSubscriptionOptIn(): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.PushSubscription.optIn().then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction pushSubscriptionOptOut(): Promise {\n return new Promise((resolve, reject) => {\n if (isOneSignalScriptFailed) {\n reject(new Error('OneSignal script failed to load.'));\n return;\n }\n\n try {\n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.PushSubscription.optOut().then(() => resolve())\n .catch((error: any) => reject(error));\n });\n } catch (error) {\n reject(error);\n }\n });\n}\nfunction pushSubscriptionAddEventListener(event: 'change', listener: (change: SubscriptionChangeEvent) => void): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.PushSubscription.addEventListener(event, listener);\n });\n \n}\nfunction pushSubscriptionRemoveEventListener(event: 'change', listener: (change: SubscriptionChangeEvent) => void): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.User.PushSubscription.removeEventListener(event, listener);\n });\n \n}\nfunction debugSetLogLevel(logLevel: 'trace' | 'debug' | 'info' | 'warn' | 'error'): void {\n \n window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => {\n OneSignal.Debug.setLogLevel(logLevel);\n });\n \n}\nconst PushSubscriptionNamespace: IOneSignalPushSubscription = {\n\tget id(): string | null | undefined { return window.OneSignal?.User?.PushSubscription?.id; },\n\tget token(): string | null | undefined { return window.OneSignal?.User?.PushSubscription?.token; },\n\tget optedIn(): boolean | undefined { return window.OneSignal?.User?.PushSubscription?.optedIn; },\n\toptIn: pushSubscriptionOptIn,\n\toptOut: pushSubscriptionOptOut,\n\taddEventListener: pushSubscriptionAddEventListener,\n\tremoveEventListener: pushSubscriptionRemoveEventListener,\n};\n\nconst UserNamespace: IOneSignalUser = {\n\tget onesignalId(): string | undefined { return window.OneSignal?.User?.onesignalId; },\n\tget externalId(): string | undefined { return window.OneSignal?.User?.externalId; },\n\taddAlias: userAddAlias,\n\taddAliases: userAddAliases,\n\tremoveAlias: userRemoveAlias,\n\tremoveAliases: userRemoveAliases,\n\taddEmail: userAddEmail,\n\tremoveEmail: userRemoveEmail,\n\taddSms: userAddSms,\n\tremoveSms: userRemoveSms,\n\taddTag: userAddTag,\n\taddTags: userAddTags,\n\tremoveTag: userRemoveTag,\n\tremoveTags: userRemoveTags,\n\tgetTags: userGetTags,\n\taddEventListener: userAddEventListener,\n\tremoveEventListener: userRemoveEventListener,\n\tsetLanguage: userSetLanguage,\n\tgetLanguage: userGetLanguage,\n\tPushSubscription: PushSubscriptionNamespace,\n};\n\nconst SessionNamespace: IOneSignalSession = {\n\tsendOutcome: sessionSendOutcome,\n\tsendUniqueOutcome: sessionSendUniqueOutcome,\n};\n\nconst DebugNamespace: IOneSignalDebug = {\n\tsetLogLevel: debugSetLogLevel,\n};\n\nconst SlidedownNamespace: IOneSignalSlidedown = {\n\tpromptPush: slidedownPromptPush,\n\tpromptPushCategories: slidedownPromptPushCategories,\n\tpromptSms: slidedownPromptSms,\n\tpromptEmail: slidedownPromptEmail,\n\tpromptSmsAndEmail: slidedownPromptSmsAndEmail,\n\taddEventListener: slidedownAddEventListener,\n\tremoveEventListener: slidedownRemoveEventListener,\n};\n\nconst NotificationsNamespace: IOneSignalNotifications = {\n\tget permissionNative(): NotificationPermission { return window.OneSignal?.Notifications?.permissionNative ?? 'default'; },\n\tget permission(): boolean { return window.OneSignal?.Notifications?.permission ?? false; },\n\tsetDefaultUrl: notificationsSetDefaultUrl,\n\tsetDefaultTitle: notificationsSetDefaultTitle,\n\tisPushSupported,\n\trequestPermission: notificationsRequestPermission,\n\taddEventListener: notificationsAddEventListener,\n\tremoveEventListener: notificationsRemoveEventListener,\n};\n\nconst OneSignalNamespace: IOneSignalOneSignal = {\n\tlogin: oneSignalLogin,\n\tlogout: oneSignalLogout,\n\tinit,\n\tsetConsentGiven: oneSignalSetConsentGiven,\n\tsetConsentRequired: oneSignalSetConsentRequired,\n\tSlidedown: SlidedownNamespace,\n\tNotifications: NotificationsNamespace,\n\tSession: SessionNamespace,\n\tUser: UserNamespace,\n\tDebug: DebugNamespace,\n};\n\nconst OneSignal = OneSignalNamespace;\nexport default OneSignal;\n"],"names":["ONESIGNAL_SDK_ID","ONE_SIGNAL_SCRIPT_SRC","isOneSignalInitialized","isOneSignalScriptFailed","addSDKScript","handleOnError","script","isPushNotificationsSupported","supportsVapidPush","supportsSafariPush","isMacOSSafariInIframe","isPushSupported","init","options","_a","resolve","reject","OneSignal","oneSignalLogin","externalId","jwtToken","error","oneSignalLogout","oneSignalSetConsentGiven","consent","oneSignalSetConsentRequired","requiresConsent","slidedownPromptPush","slidedownPromptPushCategories","slidedownPromptSms","slidedownPromptEmail","slidedownPromptSmsAndEmail","slidedownAddEventListener","event","listener","slidedownRemoveEventListener","notificationsSetDefaultUrl","url","notificationsSetDefaultTitle","title","notificationsRequestPermission","notificationsAddEventListener","notificationsRemoveEventListener","sessionSendOutcome","outcomeName","outcomeWeight","sessionSendUniqueOutcome","userAddAlias","label","id","userAddAliases","aliases","userRemoveAlias","userRemoveAliases","labels","userAddEmail","email","userRemoveEmail","userAddSms","smsNumber","userRemoveSms","userAddTag","key","value","userAddTags","tags","userRemoveTag","userRemoveTags","keys","userGetTags","retVal","userAddEventListener","userRemoveEventListener","userSetLanguage","language","userGetLanguage","pushSubscriptionOptIn","pushSubscriptionOptOut","pushSubscriptionAddEventListener","pushSubscriptionRemoveEventListener","debugSetLogLevel","logLevel","PushSubscriptionNamespace","_c","_b","UserNamespace","SessionNamespace","DebugNamespace","SlidedownNamespace","NotificationsNamespace","OneSignalNamespace"],"mappings":"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"} -------------------------------------------------------------------------------- /dist/index.test.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | 23 | dev-ssl.crt 24 | dev-ssl.key 25 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | 3 | Run `npm install` then replace the string `` with your actual app id from the OneSignal dashboard project. 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-react-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@types/node": "^22.13.10", 7 | "@types/react": "^19.0.10", 8 | "@types/react-dom": "^19.0.4", 9 | "react": "^19.0.0", 10 | "react-dom": "^19.0.0", 11 | "react-onesignal": "file:../", 12 | "typescript": "^5.8.2", 13 | "web-vitals": "^4.2.4" 14 | }, 15 | "scripts": { 16 | "start": "vite" 17 | }, 18 | "browserslist": { 19 | "production": [ 20 | ">0.2%", 21 | "not dead", 22 | "not op_mini all" 23 | ], 24 | "development": [ 25 | "last 1 chrome version", 26 | "last 1 firefox version", 27 | "last 1 safari version" 28 | ] 29 | }, 30 | "devDependencies": { 31 | "@vitejs/plugin-react": "^4.3.4", 32 | "vite": "^6.2.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /example/public/OneSignalSDKWorker.js: -------------------------------------------------------------------------------- 1 | importScripts("https://onesignal.com/sdks/web/v16/OneSignalSDK.sw.js"); 2 | -------------------------------------------------------------------------------- /example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OneSignal/react-onesignal/32008024b237e1b6675d343f3fbf01ab7388aed2/example/public/favicon.ico -------------------------------------------------------------------------------- /example/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OneSignal/react-onesignal/32008024b237e1b6675d343f3fbf01ab7388aed2/example/public/logo192.png -------------------------------------------------------------------------------- /example/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OneSignal/react-onesignal/32008024b237e1b6675d343f3fbf01ab7388aed2/example/public/logo512.png -------------------------------------------------------------------------------- /example/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /example/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /example/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import OneSignal from "react-onesignal"; 3 | import "./App.css"; 4 | import logo from "./logo.svg"; 5 | 6 | function App() { 7 | useEffect(() => { 8 | OneSignal.init({ 9 | appId: "", 10 | }).then(() => { 11 | OneSignal.Debug.setLogLevel("trace"); 12 | }); 13 | }, []); 14 | 15 | return ( 16 |
17 |
18 | logo 19 |

20 | Edit src/App.tsx and save to reload. 21 |

22 | 28 | Learn React 29 | 30 |
31 |
32 | ); 33 | } 34 | 35 | export default App; 36 | -------------------------------------------------------------------------------- /example/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /example/src/index.tsx: -------------------------------------------------------------------------------- 1 | import ReactDOM from 'react-dom/client'; 2 | import App from './App'; 3 | import './index.css'; 4 | import reportWebVitals from './reportWebVitals'; 5 | 6 | const root = ReactDOM.createRoot( 7 | document.getElementById('root') as HTMLElement, 8 | ); 9 | root.render(); 10 | 11 | // If you want to start measuring performance in your app, pass a function 12 | // to log results (for example: reportWebVitals(console.log)) 13 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 14 | reportWebVitals(); 15 | -------------------------------------------------------------------------------- /example/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /example/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /example/src/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.svg" { 2 | const content: string; 3 | export default content; 4 | } 5 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /example/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from '@vitejs/plugin-react'; 2 | 3 | import { defineConfig } from 'vite'; 4 | 5 | export default defineConfig({ 6 | plugins: [react()], 7 | server: { 8 | port: 3000, 9 | open: true, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /index.test.ts: -------------------------------------------------------------------------------- 1 | import OneSignal from './index'; 2 | 3 | const originalDocument = window.document; 4 | const documentSpy = vi.spyOn(window, 'document', 'get'); 5 | 6 | const APP_ID = '123456'; 7 | 8 | const init = vi.fn(); 9 | // @ts-expect-error - mocking OneSignal class that comes from the cdn 10 | window.OneSignal = { 11 | init, 12 | }; 13 | window.OneSignalDeferred = []; 14 | Object.defineProperty(window.OneSignalDeferred, 'push', { 15 | value: (cb: (OneSignal: typeof window.OneSignal) => void) => { 16 | cb(window.OneSignal); 17 | }, 18 | }); 19 | 20 | describe('React OneSignal', () => { 21 | test('init method', async () => { 22 | // no document error 23 | documentSpy.mockReturnValue(undefined); 24 | await expect(OneSignal.init({ appId: APP_ID })).rejects.toThrow( 25 | 'Document is not defined.', 26 | ); 27 | documentSpy.mockImplementation(() => originalDocument); 28 | 29 | // no appId error 30 | // @ts-expect-error - appId is required but purposely not provided for this test 31 | await expect(OneSignal.init({})).rejects.toThrow( 32 | 'You need to provide your OneSignal appId.', 33 | ); 34 | 35 | // init error 36 | init.mockRejectedValue(new Error('init error')); 37 | await expect(OneSignal.init({ appId: APP_ID })).rejects.toThrow( 38 | 'init error', 39 | ); 40 | 41 | // init success 42 | init.mockResolvedValue(undefined); 43 | await expect(OneSignal.init({ appId: APP_ID })).resolves.not.toThrow(); 44 | 45 | // already initialized error 46 | await expect(OneSignal.init({ appId: APP_ID })).rejects.toThrow( 47 | 'OneSignal is already initialized.', 48 | ); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | const ONESIGNAL_SDK_ID = 'onesignal-sdk'; 2 | const ONE_SIGNAL_SCRIPT_SRC = 3 | 'https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js'; 4 | 5 | // true if the script is successfully loaded from CDN. 6 | let isOneSignalInitialized = false; 7 | // true if the script fails to load from CDN. A separate flag is necessary 8 | // to disambiguate between a CDN load failure and a delayed call to 9 | // OneSignal#init. 10 | let isOneSignalScriptFailed = false; 11 | 12 | if (typeof window !== 'undefined') { 13 | window.OneSignalDeferred = window.OneSignalDeferred || []; 14 | addSDKScript(); 15 | } 16 | 17 | declare global { 18 | interface Window { 19 | OneSignalDeferred?: OneSignalDeferredLoadedCallback[]; 20 | OneSignal?: IOneSignalOneSignal; 21 | safari?: { 22 | pushNotification: any; 23 | }; 24 | } 25 | } 26 | 27 | /* H E L P E R S */ 28 | 29 | function handleOnError() { 30 | isOneSignalScriptFailed = true; 31 | } 32 | 33 | function addSDKScript() { 34 | const script = document.createElement('script'); 35 | script.id = ONESIGNAL_SDK_ID; 36 | script.defer = true; 37 | script.src = ONE_SIGNAL_SCRIPT_SRC; 38 | 39 | // Always resolve whether or not the script is successfully initialized. 40 | // This is important for users who may block cdn.onesignal.com w/ adblock. 41 | script.onerror = () => { 42 | handleOnError(); 43 | }; 44 | 45 | document.head.appendChild(script); 46 | } 47 | 48 | /** 49 | * The following code is copied directly from the native SDK source file BrowserSupportsPush.ts 50 | * S T A R T 51 | */ 52 | 53 | // Checks if the browser supports push notifications by checking if specific 54 | // classes and properties on them exist 55 | function isPushNotificationsSupported() { 56 | return supportsVapidPush() || supportsSafariPush(); 57 | } 58 | 59 | function isMacOSSafariInIframe(): boolean { 60 | // Fallback detection for Safari on macOS in an iframe context 61 | return ( 62 | window.top !== window && // isContextIframe 63 | navigator.vendor === 'Apple Computer, Inc.' && // isSafari 64 | navigator.platform === 'MacIntel' 65 | ); // isMacOS 66 | } 67 | 68 | function supportsSafariPush(): boolean { 69 | return ( 70 | (window.safari && typeof window.safari.pushNotification !== 'undefined') || 71 | isMacOSSafariInIframe() 72 | ); 73 | } 74 | 75 | // Does the browser support the standard Push API 76 | function supportsVapidPush(): boolean { 77 | return ( 78 | typeof PushSubscriptionOptions !== 'undefined' && 79 | PushSubscriptionOptions.prototype.hasOwnProperty('applicationServerKey') 80 | ); 81 | } 82 | /* E N D */ 83 | 84 | /** 85 | * This is a SPECIAL FUNCTION 86 | * It is a hardcoded implementation copied from the upstream/native WebSDK since we want to return a boolean immediately 87 | * Natively, this is done via the shimloading mechanism (i.e. if the SDK loads, push is supported) 88 | * @PublicApi 89 | */ 90 | const isPushSupported = (): boolean => { 91 | return isPushNotificationsSupported(); 92 | }; 93 | 94 | /** 95 | * @PublicApi 96 | */ 97 | const init = (options: IInitObject): Promise => { 98 | if (isOneSignalInitialized) { 99 | return Promise.reject(`OneSignal is already initialized.`); 100 | } 101 | 102 | if (!options || !options.appId) { 103 | return Promise.reject('You need to provide your OneSignal appId.'); 104 | } 105 | 106 | if (!document) { 107 | return Promise.reject(`Document is not defined.`); 108 | } 109 | 110 | // Handle both disabled and disable keys for welcome notification 111 | if (options.welcomeNotification?.disabled !== undefined) { 112 | options.welcomeNotification.disable = options.welcomeNotification.disabled; 113 | } 114 | 115 | return new Promise((resolve, reject) => { 116 | window.OneSignalDeferred?.push((OneSignal) => { 117 | OneSignal.init(options) 118 | .then(() => { 119 | isOneSignalInitialized = true; 120 | resolve(); 121 | }) 122 | .catch(reject); 123 | }); 124 | }); 125 | }; 126 | 127 | export interface AutoPromptOptions { force?: boolean; forceSlidedownOverNative?: boolean; slidedownPromptOptions?: IOneSignalAutoPromptOptions; } 128 | export interface IOneSignalAutoPromptOptions { force?: boolean; forceSlidedownOverNative?: boolean; isInUpdateMode?: boolean; categoryOptions?: IOneSignalCategories; } 129 | export interface IOneSignalCategories { positiveUpdateButton: string; negativeUpdateButton: string; savingButtonText: string; errorButtonText: string; updateMessage: string; tags: IOneSignalTagCategory[]; } 130 | export interface IOneSignalTagCategory { tag: string; label: string; checked?: boolean; } 131 | export type PushSubscriptionNamespaceProperties = { id: string | null | undefined; token: string | null | undefined; optedIn: boolean; }; 132 | export type SubscriptionChangeEvent = { previous: PushSubscriptionNamespaceProperties; current: PushSubscriptionNamespaceProperties; }; 133 | export type NotificationEventName = 'click' | 'foregroundWillDisplay' | 'dismiss' | 'permissionChange' | 'permissionPromptDisplay'; 134 | export type SlidedownEventName = 'slidedownAllowClick' | 'slidedownCancelClick' | 'slidedownClosed' | 'slidedownQueued' | 'slidedownShown'; 135 | export type OneSignalDeferredLoadedCallback = (onesignal: IOneSignalOneSignal) => void; 136 | export interface IOSNotification { 137 | /** 138 | * The OneSignal notification id; 139 | * - Primary id on OneSignal's REST API and dashboard 140 | */ 141 | readonly notificationId: string; 142 | 143 | /** 144 | * Visible title text on the notification 145 | */ 146 | readonly title?: string; 147 | 148 | /** 149 | * Visible body text on the notification 150 | */ 151 | readonly body: string; 152 | 153 | /** 154 | * Visible icon the notification; URL format 155 | */ 156 | readonly icon?: string; 157 | 158 | /** 159 | * Visible small badgeIcon that displays on some devices; URL format 160 | * Example: On Android's status bar 161 | */ 162 | readonly badgeIcon?: string; 163 | 164 | /** 165 | * Visible image on the notification; URL format 166 | */ 167 | readonly image?: string; 168 | 169 | /** 170 | * Visible buttons on the notification 171 | */ 172 | readonly actionButtons?: IOSNotificationActionButton[]; 173 | 174 | /** 175 | * If this value is the same as existing notification, it will replace it 176 | * Can be set when creating the notification with "Web Push Topic" on the dashboard 177 | * or web_push_topic from the REST API. 178 | */ 179 | readonly topic?: string; 180 | 181 | /** 182 | * Custom object that was sent with the notification; 183 | * definable when creating the notification from the OneSignal REST API or dashboard 184 | */ 185 | readonly additionalData?: object; 186 | 187 | /** 188 | * URL to open when clicking or tapping on the notification 189 | */ 190 | readonly launchURL?: string; 191 | 192 | /** 193 | * Confirm the push was received by reporting back to OneSignal 194 | */ 195 | readonly confirmDelivery: boolean; 196 | } 197 | 198 | export interface IOSNotificationActionButton { 199 | /** 200 | * Any unique identifier to represent which button was clicked. This is typically passed back to the service worker 201 | * and host page through events to identify which button was clicked. 202 | * e.g. 'like-button' 203 | */ 204 | readonly actionId: string; 205 | /** 206 | * The notification action button's text. 207 | */ 208 | readonly text: string; 209 | /** 210 | * A valid publicly reachable HTTPS URL to an image. 211 | */ 212 | readonly icon?: string; 213 | /** 214 | * The URL to open the web browser to when this action button is clicked. 215 | */ 216 | readonly launchURL?: string; 217 | } 218 | 219 | export interface NotificationClickResult { 220 | readonly actionId?: string; 221 | readonly url?: string; 222 | } 223 | 224 | export type NotificationEventTypeMap = { 225 | 'click': NotificationClickEvent; 226 | 'foregroundWillDisplay': NotificationForegroundWillDisplayEvent; 227 | 'dismiss': NotificationDismissEvent; 228 | 'permissionChange': boolean; 229 | 'permissionPromptDisplay': void; 230 | }; 231 | 232 | export interface NotificationForegroundWillDisplayEvent { 233 | readonly notification: IOSNotification; 234 | preventDefault(): void; 235 | } 236 | 237 | export interface NotificationDismissEvent { 238 | notification: IOSNotification; 239 | } 240 | 241 | export interface NotificationClickEvent { 242 | readonly notification: IOSNotification; 243 | readonly result: NotificationClickResult; 244 | } 245 | 246 | export type UserChangeEvent = { 247 | current: UserNamespaceProperties; 248 | }; 249 | export type UserNamespaceProperties = { 250 | onesignalId: string | undefined; 251 | externalId: string | undefined; 252 | }; 253 | 254 | export interface IInitObject { 255 | appId: string; 256 | subdomainName?: string; 257 | requiresUserPrivacyConsent?: boolean; 258 | promptOptions?: { 259 | slidedown: { 260 | prompts: { 261 | /** 262 | * Whether to automatically display the prompt. 263 | * `true` will display the prompt based on the delay options. 264 | * `false` will prevent the prompt from displaying until the Slidedowns methods are used. 265 | */ 266 | autoPrompt: boolean; 267 | 268 | /** 269 | * Only available for type: category. Up to 10 categories. 270 | * @example 271 | * categories: [{ tag: 'local_news', label: 'Local News' }] // The user will be tagged with local_news but will see "Local News" in the prompt. 272 | */ 273 | categories: { 274 | /** Should identify the action. */ 275 | tag: string; 276 | 277 | /** What the user will see. */ 278 | label: string; 279 | }[]; 280 | 281 | /** 282 | * The delay options for the prompt. 283 | * @example delay: { pageViews: 3, timeDelay: 20 } // The user will not be shown the prompt until 20 seconds after the 3rd page view. 284 | */ 285 | delay: { 286 | /** The number of pages a user needs to visit before the prompt is displayed. */ 287 | pageViews?: number; 288 | 289 | /** The number of seconds a user needs to wait before the prompt is displayed.Both options must be satisfied for the prompt to display */ 290 | timeDelay?: number; 291 | }; 292 | 293 | /** 294 | * The text to display in the prompt. 295 | */ 296 | text?: { 297 | /** The callout asking the user to opt-in. Up to 90 characters. */ 298 | actionMessage?: string; 299 | 300 | /** Triggers the opt-in. Up to 15 characters. */ 301 | acceptButton?: string; 302 | 303 | /** Cancels opt-in. Up to 15 characters. */ 304 | cancelMessage?: string; 305 | 306 | /** The message of the confirmation prompt displayed after the email and/or phone number is provided. Up to 90 characters. */ 307 | confirmMessage?: string; 308 | 309 | /** Identifies the email text field. Up to 15 characters. */ 310 | emailLabel?: string; 311 | 312 | /** Cancels the category update. Up to 15 characters. */ 313 | negativeUpdateButton?: string; 314 | 315 | /** Saves the updated category tags. Up to 15 characters. */ 316 | positiveUpdateButton?: string; 317 | 318 | /** Identifies the phone number text field. Up to 15 characters. */ 319 | smsLabel?: string; 320 | 321 | /** A different message shown to subscribers presented the prompt again to update categories. Up to 90 characters. */ 322 | updateMessage?: string; 323 | }; 324 | 325 | /** 326 | * The type of prompt to display. 327 | * `push` which is the Slide Prompt without categories. 328 | * `category` which is the Slide Prompt with categories. 329 | * `sms` only asks for phone number. 330 | * `email` only asks for email address. 331 | * `smsAndEmail` asks for both phone number and email address. 332 | */ 333 | type: 'push' | 'category' | 'sms' | 'email' | 'smsAndEmail'; 334 | }[]; 335 | }; 336 | }; 337 | welcomeNotification?: { 338 | /** 339 | * Disables sending a welcome notification to new site visitors. If you want to disable welcome notifications, this is the only option you need. 340 | * @deprecated Use 'disable' instead. This will be removed in a future version. 341 | */ 342 | disabled?: boolean; 343 | 344 | /** 345 | * Disables sending a welcome notification to new site visitors. If you want to disable welcome notifications, this is the only option you need. 346 | */ 347 | disable?: boolean; 348 | 349 | /** 350 | * The welcome notification's message. You can localize this to your own language. 351 | * If left blank or set to blank, the default of 'Thanks for subscribing!' will be used. 352 | */ 353 | message: string; 354 | 355 | /** 356 | * The welcome notification's title. You can localize this to your own language. If not set, or left blank, the site's title will be used. 357 | * Set to one space ' ' to clear the title, although this is not recommended. 358 | */ 359 | title?: string; 360 | 361 | /** 362 | * By default, clicking the welcome notification does not open any link. 363 | * This is recommended because the user has just visited your site and subscribed. 364 | */ 365 | url?: string; 366 | }; 367 | 368 | /** 369 | * Will enable customization of the notify/subscription bell button. 370 | */ 371 | notifyButton?: { 372 | /** 373 | * A function you define that returns true to show the Subscription Bell, or false to hide it. 374 | * Typically used the hide the Subscription Bell after the user is subscribed. 375 | * This function is not re-evaluated on every state change; this function is only evaluated once when the Subscription Bell begins to show. 376 | */ 377 | displayPredicate?: () => boolean | Promise; 378 | 379 | /** 380 | * Enable the Subscription Bell. The Subscription Bell is otherwise disabled by default. 381 | */ 382 | enable?: boolean; 383 | 384 | /** Specify CSS-valid pixel offsets using bottom, left, and right. */ 385 | offset?: { bottom: string; left: string; right: string }; 386 | 387 | /** 388 | * If `true`, the Subscription Bell will display an icon that there is 1 unread message. 389 | * When hovering over the Subscription Bell, the user will see custom text set by message.prenotify. 390 | */ 391 | prenotify: boolean; 392 | 393 | /** Either `bottom-left` or `bottom-right`. The Subscription Bell will be fixed at this location on your page. */ 394 | position?: 'bottom-left' | 'bottom-right'; 395 | 396 | /** Set `false` to hide the 'Powered by OneSignal' text in the Subscription Bell dialog popup. */ 397 | showCredit: boolean; 398 | 399 | /** 400 | * The Subscription Bell will initially appear at one of these sizes, and then shrink down to size `small` after the user subscribes. 401 | */ 402 | size?: 'small' | 'medium' | 'large'; 403 | 404 | /** Customize the Subscription Bell text. */ 405 | text: { 406 | 'dialog.blocked.message': string; 407 | 'dialog.blocked.title': string; 408 | 'dialog.main.button.subscribe': string; 409 | 'dialog.main.button.unsubscribe': string; 410 | 'dialog.main.title': string; 411 | 'message.action.resubscribed': string; 412 | 'message.action.subscribed': string; 413 | 'message.action.subscribing': string; 414 | 'message.action.unsubscribed': string; 415 | 'message.prenotify': string; 416 | 'tip.state.blocked': string; 417 | 'tip.state.subscribed': string; 418 | 'tip.state.unsubscribed': string; 419 | }; 420 | }; 421 | 422 | persistNotification?: boolean; 423 | webhooks?: { 424 | /** 425 | * Enable this setting only if your server has CORS enabled and supports non-simple CORS requests. 426 | * If this setting is disabled, your webhook will not need CORS to receive data, but it will not receive the custom headers. 427 | * The simplest option is to leave it disabled. 428 | * @default false 429 | */ 430 | cors: boolean; 431 | 432 | /** 433 | * This event occurs after a notification is clicked. 434 | * @example https://site.com/hook 435 | */ 436 | 'notification.clicked'?: string; 437 | 438 | /** 439 | * This event occurs after a notification is intentionally dismissed by the user (clicking the notification body or one of the notification action buttons does not trigger the dismissed webhook), 440 | * after a group of notifications are all dismissed (with this notification as part of that group), or after a notification expires on its own time and disappears. This event is supported on Chrome only. 441 | * @example https://site.com/hook 442 | */ 443 | 'notification.dismissed'?: string; 444 | 445 | /** 446 | * This event occurs after a notification is displayed. 447 | * @example https://site.com/hook 448 | */ 449 | 'notification.willDisplay'?: string; 450 | }; 451 | autoResubscribe?: boolean; 452 | autoRegister?: boolean; 453 | notificationClickHandlerMatch?: string; 454 | notificationClickHandlerAction?: string; 455 | path?: string; 456 | serviceWorkerParam?: { scope: string }; 457 | serviceWorkerPath?: string; 458 | serviceWorkerOverrideForTypical?: boolean; 459 | serviceWorkerUpdaterPath?: string; 460 | allowLocalhostAsSecureOrigin?: boolean; 461 | [key: string]: any; 462 | } 463 | 464 | export interface IOneSignalOneSignal { 465 | Slidedown: IOneSignalSlidedown; 466 | Notifications: IOneSignalNotifications; 467 | Session: IOneSignalSession; 468 | User: IOneSignalUser; 469 | Debug: IOneSignalDebug; 470 | login(externalId: string, jwtToken?: string): Promise; 471 | logout(): Promise; 472 | init(options: IInitObject): Promise; 473 | setConsentGiven(consent: boolean): Promise; 474 | setConsentRequired(requiresConsent: boolean): Promise; 475 | } 476 | export interface IOneSignalNotifications { 477 | permissionNative: NotificationPermission; 478 | permission: boolean; 479 | setDefaultUrl(url: string): Promise; 480 | setDefaultTitle(title: string): Promise; 481 | isPushSupported(): boolean; 482 | requestPermission(): Promise; 483 | addEventListener(event: K, listener: (obj: NotificationEventTypeMap[K]) => void): void; 484 | removeEventListener(event: K, listener: (obj: NotificationEventTypeMap[K]) => void): void; 485 | } 486 | export interface IOneSignalSlidedown { 487 | promptPush(options?: AutoPromptOptions): Promise; 488 | promptPushCategories(options?: AutoPromptOptions): Promise; 489 | promptSms(options?: AutoPromptOptions): Promise; 490 | promptEmail(options?: AutoPromptOptions): Promise; 491 | promptSmsAndEmail(options?: AutoPromptOptions): Promise; 492 | addEventListener(event: SlidedownEventName, listener: (wasShown: boolean) => void): void; 493 | removeEventListener(event: SlidedownEventName, listener: (wasShown: boolean) => void): void; 494 | } 495 | export interface IOneSignalDebug { 496 | setLogLevel(logLevel: 'trace' | 'debug' | 'info' | 'warn' | 'error'): void; 497 | } 498 | export interface IOneSignalSession { 499 | sendOutcome(outcomeName: string, outcomeWeight?: number): Promise; 500 | sendUniqueOutcome(outcomeName: string): Promise; 501 | } 502 | export interface IOneSignalUser { 503 | onesignalId: string | undefined; 504 | externalId: string | undefined; 505 | PushSubscription: IOneSignalPushSubscription; 506 | addAlias(label: string, id: string): void; 507 | addAliases(aliases: { [key: string]: string }): void; 508 | removeAlias(label: string): void; 509 | removeAliases(labels: string[]): void; 510 | addEmail(email: string): void; 511 | removeEmail(email: string): void; 512 | addSms(smsNumber: string): void; 513 | removeSms(smsNumber: string): void; 514 | addTag(key: string, value: string): void; 515 | addTags(tags: { [key: string]: string }): void; 516 | removeTag(key: string): void; 517 | removeTags(keys: string[]): void; 518 | getTags(): { [key: string]: string }; 519 | addEventListener(event: 'change', listener: (change: UserChangeEvent) => void): void; 520 | removeEventListener(event: 'change', listener: (change: UserChangeEvent) => void): void; 521 | setLanguage(language: string): void; 522 | getLanguage(): string; 523 | } 524 | export interface IOneSignalPushSubscription { 525 | id: string | null | undefined; 526 | token: string | null | undefined; 527 | optedIn: boolean | undefined; 528 | optIn(): Promise; 529 | optOut(): Promise; 530 | addEventListener(event: 'change', listener: (change: SubscriptionChangeEvent) => void): void; 531 | removeEventListener(event: 'change', listener: (change: SubscriptionChangeEvent) => void): void; 532 | } 533 | function oneSignalLogin(externalId: string, jwtToken?: string): Promise { 534 | return new Promise((resolve, reject) => { 535 | if (isOneSignalScriptFailed) { 536 | reject(new Error('OneSignal script failed to load.')); 537 | return; 538 | } 539 | 540 | try { 541 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 542 | OneSignal.login(externalId, jwtToken).then(() => resolve()) 543 | .catch((error: any) => reject(error)); 544 | }); 545 | } catch (error) { 546 | reject(error); 547 | } 548 | }); 549 | } 550 | function oneSignalLogout(): Promise { 551 | return new Promise((resolve, reject) => { 552 | if (isOneSignalScriptFailed) { 553 | reject(new Error('OneSignal script failed to load.')); 554 | return; 555 | } 556 | 557 | try { 558 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 559 | OneSignal.logout().then(() => resolve()) 560 | .catch((error: any) => reject(error)); 561 | }); 562 | } catch (error) { 563 | reject(error); 564 | } 565 | }); 566 | } 567 | function oneSignalSetConsentGiven(consent: boolean): Promise { 568 | return new Promise((resolve, reject) => { 569 | if (isOneSignalScriptFailed) { 570 | reject(new Error('OneSignal script failed to load.')); 571 | return; 572 | } 573 | 574 | try { 575 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 576 | OneSignal.setConsentGiven(consent).then(() => resolve()) 577 | .catch((error: any) => reject(error)); 578 | }); 579 | } catch (error) { 580 | reject(error); 581 | } 582 | }); 583 | } 584 | function oneSignalSetConsentRequired(requiresConsent: boolean): Promise { 585 | return new Promise((resolve, reject) => { 586 | if (isOneSignalScriptFailed) { 587 | reject(new Error('OneSignal script failed to load.')); 588 | return; 589 | } 590 | 591 | try { 592 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 593 | OneSignal.setConsentRequired(requiresConsent).then(() => resolve()) 594 | .catch((error: any) => reject(error)); 595 | }); 596 | } catch (error) { 597 | reject(error); 598 | } 599 | }); 600 | } 601 | function slidedownPromptPush(options?: AutoPromptOptions): Promise { 602 | return new Promise((resolve, reject) => { 603 | if (isOneSignalScriptFailed) { 604 | reject(new Error('OneSignal script failed to load.')); 605 | return; 606 | } 607 | 608 | try { 609 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 610 | OneSignal.Slidedown.promptPush(options).then(() => resolve()) 611 | .catch((error: any) => reject(error)); 612 | }); 613 | } catch (error) { 614 | reject(error); 615 | } 616 | }); 617 | } 618 | function slidedownPromptPushCategories(options?: AutoPromptOptions): Promise { 619 | return new Promise((resolve, reject) => { 620 | if (isOneSignalScriptFailed) { 621 | reject(new Error('OneSignal script failed to load.')); 622 | return; 623 | } 624 | 625 | try { 626 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 627 | OneSignal.Slidedown.promptPushCategories(options).then(() => resolve()) 628 | .catch((error: any) => reject(error)); 629 | }); 630 | } catch (error) { 631 | reject(error); 632 | } 633 | }); 634 | } 635 | function slidedownPromptSms(options?: AutoPromptOptions): Promise { 636 | return new Promise((resolve, reject) => { 637 | if (isOneSignalScriptFailed) { 638 | reject(new Error('OneSignal script failed to load.')); 639 | return; 640 | } 641 | 642 | try { 643 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 644 | OneSignal.Slidedown.promptSms(options).then(() => resolve()) 645 | .catch((error: any) => reject(error)); 646 | }); 647 | } catch (error) { 648 | reject(error); 649 | } 650 | }); 651 | } 652 | function slidedownPromptEmail(options?: AutoPromptOptions): Promise { 653 | return new Promise((resolve, reject) => { 654 | if (isOneSignalScriptFailed) { 655 | reject(new Error('OneSignal script failed to load.')); 656 | return; 657 | } 658 | 659 | try { 660 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 661 | OneSignal.Slidedown.promptEmail(options).then(() => resolve()) 662 | .catch((error: any) => reject(error)); 663 | }); 664 | } catch (error) { 665 | reject(error); 666 | } 667 | }); 668 | } 669 | function slidedownPromptSmsAndEmail(options?: AutoPromptOptions): Promise { 670 | return new Promise((resolve, reject) => { 671 | if (isOneSignalScriptFailed) { 672 | reject(new Error('OneSignal script failed to load.')); 673 | return; 674 | } 675 | 676 | try { 677 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 678 | OneSignal.Slidedown.promptSmsAndEmail(options).then(() => resolve()) 679 | .catch((error: any) => reject(error)); 680 | }); 681 | } catch (error) { 682 | reject(error); 683 | } 684 | }); 685 | } 686 | function slidedownAddEventListener(event: SlidedownEventName, listener: (wasShown: boolean) => void): void { 687 | 688 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 689 | OneSignal.Slidedown.addEventListener(event, listener); 690 | }); 691 | 692 | } 693 | function slidedownRemoveEventListener(event: SlidedownEventName, listener: (wasShown: boolean) => void): void { 694 | 695 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 696 | OneSignal.Slidedown.removeEventListener(event, listener); 697 | }); 698 | 699 | } 700 | function notificationsSetDefaultUrl(url: string): Promise { 701 | return new Promise((resolve, reject) => { 702 | if (isOneSignalScriptFailed) { 703 | reject(new Error('OneSignal script failed to load.')); 704 | return; 705 | } 706 | 707 | try { 708 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 709 | OneSignal.Notifications.setDefaultUrl(url).then(() => resolve()) 710 | .catch((error: any) => reject(error)); 711 | }); 712 | } catch (error) { 713 | reject(error); 714 | } 715 | }); 716 | } 717 | function notificationsSetDefaultTitle(title: string): Promise { 718 | return new Promise((resolve, reject) => { 719 | if (isOneSignalScriptFailed) { 720 | reject(new Error('OneSignal script failed to load.')); 721 | return; 722 | } 723 | 724 | try { 725 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 726 | OneSignal.Notifications.setDefaultTitle(title).then(() => resolve()) 727 | .catch((error: any) => reject(error)); 728 | }); 729 | } catch (error) { 730 | reject(error); 731 | } 732 | }); 733 | } 734 | function notificationsRequestPermission(): Promise { 735 | return new Promise((resolve, reject) => { 736 | if (isOneSignalScriptFailed) { 737 | reject(new Error('OneSignal script failed to load.')); 738 | return; 739 | } 740 | 741 | try { 742 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 743 | OneSignal.Notifications.requestPermission().then(() => resolve()) 744 | .catch((error: any) => reject(error)); 745 | }); 746 | } catch (error) { 747 | reject(error); 748 | } 749 | }); 750 | } 751 | function notificationsAddEventListener(event: K, listener: (obj: NotificationEventTypeMap[K]) => void): void { 752 | 753 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 754 | OneSignal.Notifications.addEventListener(event, listener); 755 | }); 756 | 757 | } 758 | function notificationsRemoveEventListener(event: K, listener: (obj: NotificationEventTypeMap[K]) => void): void { 759 | 760 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 761 | OneSignal.Notifications.removeEventListener(event, listener); 762 | }); 763 | 764 | } 765 | function sessionSendOutcome(outcomeName: string, outcomeWeight?: number): Promise { 766 | return new Promise((resolve, reject) => { 767 | if (isOneSignalScriptFailed) { 768 | reject(new Error('OneSignal script failed to load.')); 769 | return; 770 | } 771 | 772 | try { 773 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 774 | OneSignal.Session.sendOutcome(outcomeName, outcomeWeight).then(() => resolve()) 775 | .catch((error: any) => reject(error)); 776 | }); 777 | } catch (error) { 778 | reject(error); 779 | } 780 | }); 781 | } 782 | function sessionSendUniqueOutcome(outcomeName: string): Promise { 783 | return new Promise((resolve, reject) => { 784 | if (isOneSignalScriptFailed) { 785 | reject(new Error('OneSignal script failed to load.')); 786 | return; 787 | } 788 | 789 | try { 790 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 791 | OneSignal.Session.sendUniqueOutcome(outcomeName).then(() => resolve()) 792 | .catch((error: any) => reject(error)); 793 | }); 794 | } catch (error) { 795 | reject(error); 796 | } 797 | }); 798 | } 799 | function userAddAlias(label: string, id: string): void { 800 | 801 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 802 | OneSignal.User.addAlias(label, id); 803 | }); 804 | 805 | } 806 | function userAddAliases(aliases: { [key: string]: string }): void { 807 | 808 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 809 | OneSignal.User.addAliases(aliases); 810 | }); 811 | 812 | } 813 | function userRemoveAlias(label: string): void { 814 | 815 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 816 | OneSignal.User.removeAlias(label); 817 | }); 818 | 819 | } 820 | function userRemoveAliases(labels: string[]): void { 821 | 822 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 823 | OneSignal.User.removeAliases(labels); 824 | }); 825 | 826 | } 827 | function userAddEmail(email: string): void { 828 | 829 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 830 | OneSignal.User.addEmail(email); 831 | }); 832 | 833 | } 834 | function userRemoveEmail(email: string): void { 835 | 836 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 837 | OneSignal.User.removeEmail(email); 838 | }); 839 | 840 | } 841 | function userAddSms(smsNumber: string): void { 842 | 843 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 844 | OneSignal.User.addSms(smsNumber); 845 | }); 846 | 847 | } 848 | function userRemoveSms(smsNumber: string): void { 849 | 850 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 851 | OneSignal.User.removeSms(smsNumber); 852 | }); 853 | 854 | } 855 | function userAddTag(key: string, value: string): void { 856 | 857 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 858 | OneSignal.User.addTag(key, value); 859 | }); 860 | 861 | } 862 | function userAddTags(tags: { [key: string]: string }): void { 863 | 864 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 865 | OneSignal.User.addTags(tags); 866 | }); 867 | 868 | } 869 | function userRemoveTag(key: string): void { 870 | 871 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 872 | OneSignal.User.removeTag(key); 873 | }); 874 | 875 | } 876 | function userRemoveTags(keys: string[]): void { 877 | 878 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 879 | OneSignal.User.removeTags(keys); 880 | }); 881 | 882 | } 883 | // @ts-expect-error - return non-Promise type despite needing to await OneSignalDeferred 884 | async function userGetTags(): { [key: string]: string } { 885 | let retVal: { [key: string]: string }; 886 | await window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 887 | retVal = OneSignal.User.getTags(); 888 | }); 889 | return retVal; 890 | } 891 | function userAddEventListener(event: 'change', listener: (change: UserChangeEvent) => void): void { 892 | 893 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 894 | OneSignal.User.addEventListener(event, listener); 895 | }); 896 | 897 | } 898 | function userRemoveEventListener(event: 'change', listener: (change: UserChangeEvent) => void): void { 899 | 900 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 901 | OneSignal.User.removeEventListener(event, listener); 902 | }); 903 | 904 | } 905 | function userSetLanguage(language: string): void { 906 | 907 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 908 | OneSignal.User.setLanguage(language); 909 | }); 910 | 911 | } 912 | // @ts-expect-error - return non-Promise type despite needing to await OneSignalDeferred 913 | async function userGetLanguage(): string { 914 | let retVal: string; 915 | await window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 916 | retVal = OneSignal.User.getLanguage(); 917 | }); 918 | return retVal; 919 | } 920 | function pushSubscriptionOptIn(): Promise { 921 | return new Promise((resolve, reject) => { 922 | if (isOneSignalScriptFailed) { 923 | reject(new Error('OneSignal script failed to load.')); 924 | return; 925 | } 926 | 927 | try { 928 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 929 | OneSignal.User.PushSubscription.optIn().then(() => resolve()) 930 | .catch((error: any) => reject(error)); 931 | }); 932 | } catch (error) { 933 | reject(error); 934 | } 935 | }); 936 | } 937 | function pushSubscriptionOptOut(): Promise { 938 | return new Promise((resolve, reject) => { 939 | if (isOneSignalScriptFailed) { 940 | reject(new Error('OneSignal script failed to load.')); 941 | return; 942 | } 943 | 944 | try { 945 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 946 | OneSignal.User.PushSubscription.optOut().then(() => resolve()) 947 | .catch((error: any) => reject(error)); 948 | }); 949 | } catch (error) { 950 | reject(error); 951 | } 952 | }); 953 | } 954 | function pushSubscriptionAddEventListener(event: 'change', listener: (change: SubscriptionChangeEvent) => void): void { 955 | 956 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 957 | OneSignal.User.PushSubscription.addEventListener(event, listener); 958 | }); 959 | 960 | } 961 | function pushSubscriptionRemoveEventListener(event: 'change', listener: (change: SubscriptionChangeEvent) => void): void { 962 | 963 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 964 | OneSignal.User.PushSubscription.removeEventListener(event, listener); 965 | }); 966 | 967 | } 968 | function debugSetLogLevel(logLevel: 'trace' | 'debug' | 'info' | 'warn' | 'error'): void { 969 | 970 | window.OneSignalDeferred?.push((OneSignal: IOneSignalOneSignal) => { 971 | OneSignal.Debug.setLogLevel(logLevel); 972 | }); 973 | 974 | } 975 | const PushSubscriptionNamespace: IOneSignalPushSubscription = { 976 | get id(): string | null | undefined { return window.OneSignal?.User?.PushSubscription?.id; }, 977 | get token(): string | null | undefined { return window.OneSignal?.User?.PushSubscription?.token; }, 978 | get optedIn(): boolean | undefined { return window.OneSignal?.User?.PushSubscription?.optedIn; }, 979 | optIn: pushSubscriptionOptIn, 980 | optOut: pushSubscriptionOptOut, 981 | addEventListener: pushSubscriptionAddEventListener, 982 | removeEventListener: pushSubscriptionRemoveEventListener, 983 | }; 984 | 985 | const UserNamespace: IOneSignalUser = { 986 | get onesignalId(): string | undefined { return window.OneSignal?.User?.onesignalId; }, 987 | get externalId(): string | undefined { return window.OneSignal?.User?.externalId; }, 988 | addAlias: userAddAlias, 989 | addAliases: userAddAliases, 990 | removeAlias: userRemoveAlias, 991 | removeAliases: userRemoveAliases, 992 | addEmail: userAddEmail, 993 | removeEmail: userRemoveEmail, 994 | addSms: userAddSms, 995 | removeSms: userRemoveSms, 996 | addTag: userAddTag, 997 | addTags: userAddTags, 998 | removeTag: userRemoveTag, 999 | removeTags: userRemoveTags, 1000 | getTags: userGetTags, 1001 | addEventListener: userAddEventListener, 1002 | removeEventListener: userRemoveEventListener, 1003 | setLanguage: userSetLanguage, 1004 | getLanguage: userGetLanguage, 1005 | PushSubscription: PushSubscriptionNamespace, 1006 | }; 1007 | 1008 | const SessionNamespace: IOneSignalSession = { 1009 | sendOutcome: sessionSendOutcome, 1010 | sendUniqueOutcome: sessionSendUniqueOutcome, 1011 | }; 1012 | 1013 | const DebugNamespace: IOneSignalDebug = { 1014 | setLogLevel: debugSetLogLevel, 1015 | }; 1016 | 1017 | const SlidedownNamespace: IOneSignalSlidedown = { 1018 | promptPush: slidedownPromptPush, 1019 | promptPushCategories: slidedownPromptPushCategories, 1020 | promptSms: slidedownPromptSms, 1021 | promptEmail: slidedownPromptEmail, 1022 | promptSmsAndEmail: slidedownPromptSmsAndEmail, 1023 | addEventListener: slidedownAddEventListener, 1024 | removeEventListener: slidedownRemoveEventListener, 1025 | }; 1026 | 1027 | const NotificationsNamespace: IOneSignalNotifications = { 1028 | get permissionNative(): NotificationPermission { return window.OneSignal?.Notifications?.permissionNative ?? 'default'; }, 1029 | get permission(): boolean { return window.OneSignal?.Notifications?.permission ?? false; }, 1030 | setDefaultUrl: notificationsSetDefaultUrl, 1031 | setDefaultTitle: notificationsSetDefaultTitle, 1032 | isPushSupported, 1033 | requestPermission: notificationsRequestPermission, 1034 | addEventListener: notificationsAddEventListener, 1035 | removeEventListener: notificationsRemoveEventListener, 1036 | }; 1037 | 1038 | const OneSignalNamespace: IOneSignalOneSignal = { 1039 | login: oneSignalLogin, 1040 | logout: oneSignalLogout, 1041 | init, 1042 | setConsentGiven: oneSignalSetConsentGiven, 1043 | setConsentRequired: oneSignalSetConsentRequired, 1044 | Slidedown: SlidedownNamespace, 1045 | Notifications: NotificationsNamespace, 1046 | Session: SessionNamespace, 1047 | User: UserNamespace, 1048 | Debug: DebugNamespace, 1049 | }; 1050 | 1051 | const OneSignal = OneSignalNamespace; 1052 | export default OneSignal; 1053 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-onesignal", 3 | "version": "3.2.3", 4 | "description": "React OneSignal Module: Make it easy to integrate OneSignal with your React App!", 5 | "type": "module", 6 | "contributors": [ 7 | { 8 | "name": "Rodrigo Gomez-Palacio" 9 | }, 10 | { 11 | "name": "Pedro Bini" 12 | }, 13 | { 14 | "name": "Graham Marlow" 15 | }, 16 | { 17 | "name": "Fadi George" 18 | } 19 | ], 20 | "homepage": "https://onesignal.com", 21 | "repository": "https://github.com/OneSignal/react-onesignal.git", 22 | "license": "MIT", 23 | "main": "dist/index.js", 24 | "module": "dist/index.es.js", 25 | "types": "dist/index.d.ts", 26 | "engines": { 27 | "node": ">=14", 28 | "npm": ">=6" 29 | }, 30 | "scripts": { 31 | "lint": "eslint . --ext .js,.jsx,.ts,.tsx", 32 | "build": "vite build", 33 | "test": "vitest run", 34 | "prepare": "npm run lint && npm run test && npm run build" 35 | }, 36 | "devDependencies": { 37 | "@typescript-eslint/eslint-plugin": "^8.28.0", 38 | "@typescript-eslint/parser": "^8.28.0", 39 | "eslint": "^8.57.1", 40 | "eslint-plugin-import": "^2.31.0", 41 | "eslint-plugin-jsx-a11y": "^6.10.2", 42 | "eslint-plugin-react": "7.37.4", 43 | "jsdom": "^26.0.0", 44 | "typescript": "^5.8.2", 45 | "vite": "^6.2.1", 46 | "vite-plugin-dts": "^4.5.3", 47 | "vitest": "^3.0.9" 48 | }, 49 | "files": [ 50 | "dist", 51 | "README.md", 52 | "LICENSE", 53 | "CHANGELOG.md", 54 | "MigrationGuide.md" 55 | ], 56 | "keywords": [ 57 | "onesignal", 58 | "push", 59 | "notification", 60 | "push notification", 61 | "react" 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from 'rollup-plugin-typescript2'; 2 | import babel from 'rollup-plugin-babel'; 3 | import commonjs from 'rollup-plugin-commonjs'; 4 | import external from 'rollup-plugin-peer-deps-external'; 5 | import resolve from 'rollup-plugin-node-resolve'; 6 | import url from 'rollup-plugin-url'; 7 | 8 | import pkg from './package.json'; 9 | 10 | export default { 11 | input: './index.ts', 12 | output: [ 13 | { 14 | file: pkg.main, 15 | format: 'cjs', 16 | sourcemap: true, 17 | }, 18 | { 19 | file: pkg.module, 20 | format: 'es', 21 | sourcemap: true, 22 | }, 23 | ], 24 | plugins: [ 25 | external(), 26 | url({ exclude: ['**/*.svg'] }), 27 | babel({ 28 | exclude: 'node_modules/**', 29 | }), 30 | resolve(), 31 | typescript({ 32 | rollupCommonJSResolveHack: true, 33 | clean: true, 34 | }), 35 | commonjs(), 36 | ], 37 | }; 38 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "module": "esnext", 5 | "target": "es2020", 6 | "lib": ["dom", "dom.iterable", "esnext"], 7 | "sourceMap": true, 8 | "allowJs": true, 9 | "declaration": true, 10 | "moduleResolution": "node", 11 | "forceConsistentCasingInFileNames": true, 12 | "noImplicitReturns": true, 13 | "noImplicitThis": true, 14 | "noImplicitAny": false, 15 | "strictNullChecks": false, 16 | "noUnusedLocals": true, 17 | "noUnusedParameters": true, 18 | "allowSyntheticDefaultImports": true, 19 | "downlevelIteration": true, 20 | "skipLibCheck": true, 21 | "types": ["vitest/globals"] 22 | }, 23 | "include": ["index.ts", "index.test.ts"], 24 | "exclude": ["node_modules", "build", "dist", "example", "rollup.config.js"] 25 | } 26 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import dts from 'vite-plugin-dts'; 3 | 4 | export default defineConfig({ 5 | build: { 6 | sourcemap: true, 7 | lib: { 8 | entry: './index.ts', 9 | name: 'react-onesignal', 10 | formats: ['es', 'cjs'], 11 | fileName: (format) => { 12 | if (format === 'es') { 13 | return 'index.es.js'; 14 | } 15 | return 'index.js'; 16 | }, 17 | }, 18 | }, 19 | plugins: [dts()], 20 | }); 21 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | 3 | export default defineConfig({ 4 | test: { 5 | environment: 'jsdom', 6 | globals: true, 7 | }, 8 | }); 9 | --------------------------------------------------------------------------------