{"id":22665159,"url":"https://github.com/br0ken-/web_push_api","last_synced_at":"2025-08-04T23:12:05.644Z","repository":{"id":139226565,"uuid":"234741905","full_name":"BR0kEN-/web_push_api","owner":"BR0kEN-","description":"Mirrors https://git.drupalcode.org/project/web_push_api","archived":false,"fork":false,"pushed_at":"2020-11-08T20:38:34.000Z","size":73,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"8.x-1.x","last_synced_at":"2025-03-29T09:31:20.756Z","etag":null,"topics":["drupal-8","drupal-8-module"],"latest_commit_sha":null,"homepage":"https://drupal.org/project/web_push_api","language":"PHP","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BR0kEN-.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-18T13:52:07.000Z","updated_at":"2020-11-08T20:38:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"0c40d1df-da4e-436c-aca8-1b83f8f1ed22","html_url":"https://github.com/BR0kEN-/web_push_api","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/BR0kEN-/web_push_api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BR0kEN-%2Fweb_push_api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BR0kEN-%2Fweb_push_api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BR0kEN-%2Fweb_push_api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BR0kEN-%2Fweb_push_api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BR0kEN-","download_url":"https://codeload.github.com/BR0kEN-/web_push_api/tar.gz/refs/heads/8.x-1.x","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BR0kEN-%2Fweb_push_api/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268801089,"owners_count":24309503,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-04T02:00:09.867Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["drupal-8","drupal-8-module"],"created_at":"2024-12-09T13:19:51.170Z","updated_at":"2025-08-04T23:12:05.598Z","avatar_url":"https://github.com/BR0kEN-.png","language":"PHP","readme":"# Web Push API\n\nThis project provides an API for sending notifications to [Push API](https://www.w3.org/TR/push-api/) subscriptions. That's it. It only gives an endpoint for creating/updating/deleting Push API subscriptions and the tools for sending notifications to them. Nothing else.\n\nDo not expect this project to have something from this list:\n\n- A client-side implementation for requesting notification permission and/or subscription to push notifications.\n- A UI for creating and/or sending notifications.\n- A UI for managing configurations that might be needed for API.\n- A queue and a worker to handle notifications dispatch.\n\n## Requirements\n\n- PHP 7.2+ and the dependencies of https://github.com/web-push-libs/web-push-php\n\n## Installation\n\n- Download the module and its dependencies.\n\n  ```bash\n  composer require drupal/web_push_api\n  ```\n\n- Install the module (e.g. `drush en web_push_api`).\n\n## Usage\n\n- Generate a key-pair for [Voluntary Application Server Identification (VAPID) for Web Push](https://tools.ietf.org/id/draft-ietf-webpush-vapid-03.html). Store `public.key` and `private.key` outside of your document root.\n\n  ```bash\n  openssl ecparam -genkey -name prime256v1 -out private.pem\n  openssl ec -in private.pem -pubout -outform DER|tail -c 65|base64|tr -d '=' |tr '/+' '_-' \u003e\u003e public.key\n  openssl ec -in private.pem -outform DER|tail -c +8|head -c 32|base64|tr -d '=' |tr '/+' '_-' \u003e\u003e private.key\n  ```\n\n- Do a client-side implementation (like https://github.com/Minishlink/web-push-php-example) and send a created subscription to the `/web-push-api/subscription` (`POST`, `PATCH` or `DELETE`).\n\n  The [subscription on a client should be created with contents from `public.key`](https://developers.google.com/web/fundamentals/push-notifications/subscribing-a-user#subscribe_a_user_with_pushmanager) you've generated before.\n\n  ```javascript\n  /**\n   * @param {ArrayBuffer} buffer\n   *\n   * @return {string}\n   */\n  function encodeKey(buffer) {\n    return btoa(String.fromCharCode(...new Uint8Array(buffer)));\n  }\n\n  /**\n   * @param {('POST'|'PATCH'|'DELETE')} method\n   * @param {PushSubscription} pushSubscription\n   */\n  async function sync(method, pushSubscription) {\n    fetch('https://example.com/web-push-api/subscription', {\n      method,\n      body: {\n        user_agent: navigator.userAgent,\n        // The UTC offset in hours.\n        utc_offset: new Date().getTimezoneOffset() / 60,\n        encoding: (PushManager.supportedContentEncodings || ['aesgcm'])[0],\n        endpoint: pushSubscription.endpoint,\n        p256dh: encodeKey(pushSubscription.getKey('p256dh')),\n        auth: encodeKey(pushSubscription.getKey('p256dh')),\n      },\n    });\n  }\n  ```\n\n  The endpoint returns the `{\"errors\": string[]}` JSON structure. The `errors` will contain violations messages if an action you've undertaken didn't succeed. Otherwise empty.\n\n- Visit `/admin/config/services/web-push-api/subscriptions` and ensure the subscription was stored in Drupal DB.\n\n- Use the module's API to craft and dispatch the notification.\n\n  ```php\n  \u003c?php\n\n  use Drupal\\Core\\Utility\\Error;\n  use Drupal\\web_push_api\\Component\\WebPush;\n  use Drupal\\web_push_api\\Component\\WebPushAuthVapid;\n  use Drupal\\web_push_api\\Component\\WebPushNotification;\n  use Drupal\\web_push_api\\Component\\WebPushNotificationAction;\n\n  $logger = \\Drupal::logger('web-push-notification');\n  $webpush = new WebPush(\\Drupal::entityTypeManager(), new WebPushAuthVapid('/path/to/public.key', '/path/to/private.key'));\n  $storage = $webpush-\u003egetSubscriptionsStorage();\n  $notification = (string) (new WebPushNotification('Hello, buddy!'))\n    -\u003eaddAction(new WebPushNotificationAction('Test action', 'go-go'))\n    -\u003esetBody('This is a test notification.');\n\n  foreach ($storage-\u003eloadMultiple() as $subscription) {\n    $webpush-\u003equeueNotification($subscription, $notification);\n\n    foreach ($webpush-\u003eflush(100) as $report) {\n      if ($report-\u003eisSuccess()) {\n        $logger-\u003einfo('ok');\n      }\n      else {\n        $logger-\u003eerror('fail');\n\n        try {\n          $storage-\u003edelete([$subscription]);\n          $logger-\u003edebug('subscription deleted');\n        }\n        catch (\\Exception $e) {\n          $logger-\u003edebug('unable to delete subscription');\n          $logger-\u003eerror(Error::renderExceptionSafe($e));\n        }\n      }\n    }\n  }\n  ```\n\n## Testing\n\nAt the moment [tests could not run on Drupal.org CI](https://www.drupal.org/pift-ci-job/1547248) due to [missing `gmp` PHP extension](https://www.drupal.org/project/drupalci_environments/issues/2922123). However, there is a [project mirror on Github](https://github.com/BR0kEN-/web_push_api) to run [tests on Travis CI](https://travis-ci.com/BR0kEN-/web_push_api).\n\n## Similar projects\n\n- https://www.drupal.org/project/browser_push_notification\n- https://www.drupal.org/project/web_push_notification\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbr0ken-%2Fweb_push_api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbr0ken-%2Fweb_push_api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbr0ken-%2Fweb_push_api/lists"}