最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - How to Build Web Push Notifications from Scratch Without MinishlinkWebPush? - Stack Overflow

programmeradmin4浏览0评论

I have a project for setting up news websites, and I’ve decided not to rely on external Composer packages. I’ve already removed all dependencies except for Minishlink\WebPush, which I still need for push notifications.

So far, I’ve successfully:

  • Generated the publicKey and privateKey for my website’s push notifications.
  • Created the endpoint, p256dh, and auth keys for subscribers. Everything works fine, except for the final step — actually sending the notifications. Right now, I’m using Minishlink\WebPush for that, like this:
use Minishlink\WebPush\WebPush;
use Minishlink\WebPush\Subscription;
function sendDeviceNotification($email, $content, $email_subject, $userAvatar, $articlePath) {
 global $pdo;
 $query = "SELECT endpoint, p256dh, authKey FROM users_auth_tokens WHERE email = :email";
 $stmt = $pdo->prepare($query);
 $stmt->execute([':email' => $email]);
 if ($stmt->rowCount() > 0) {
 $auth = [
 'VAPID' => [
 'subject' => main_url,
 'publicKey' => website_push_public_key,
 'privateKey' => website_push_private_key,
 ],
 ];
 $webPush = new WebPush($auth);
 while ($subscriber = $stmt->fetch(PDO::FETCH_ASSOC)) {
 $subscription = Subscription::create([
 'endpoint' => $subscriber['endpoint'],
 'keys' => [
 'p256dh' => $subscriber['p256dh'],
 'auth' => $subscriber['authKey'],
 ],
 ]);
 $payload = json_encode([
 'title' => $content,
 'body' => $email_subject,
 'icon' => $userAvatar,
 'badge' => main_url . '/favicon.ico',
 'extraData' => $articlePath,
 ]);
 $webPush->queueNotification($subscription, $payload);
 }
 foreach ($webPush->flush() as $report) {
 if ($report->isSuccess()) {
 }
 }
 }
}

I’ve tried countless ways to replace Minishlink\WebPush with a custom solution, but nothing works. This is literally the last missing piece—once I solve this, my push notification system will be fully independent.

Has anyone successfully implemented Web Push notifications without Minishlink\WebPush?

Additional Info:

To help others, I’m also sharing how I generate and store the website’s VAPID keys (works perfectly):

if (strpos(main_url, 'https://') === 0 && empty(website_push_public_key) && empty(website_push_private_key)) {
function generateVAPIDKeys() {
$config = [
"private_key_type" => OPENSSL_KEYTYPE_EC,
"curve_name" => "prime256v1",
];
$res = openssl_pkey_new($config);
if (!$res) {
throw new Exception('The key pair cannot be created.');
}
if (!openssl_pkey_export($res, $privateKeyPem)) {
throw new Exception('The private key cannot be extracted.');
}
$keyDetails = openssl_pkey_get_details($res);
if (!$keyDetails || !isset($keyDetails['ec']['x']) || !isset($keyDetails['ec']['y']) || !isset($keyDetails['ec']['d'])) {
throw new Exception('The key details cannot be extracted.');
}
$publicKeyHex = '04' . bin2hex($keyDetails['ec']['x']) . bin2hex($keyDetails['ec']['y']);
$publicKey = hex2bin($publicKeyHex);
$publicKeyBase64 = rtrim(strtr(base64_encode($publicKey), '+/', '-_'), '=');
$privateKeyBase64 = rtrim(strtr(base64_encode($keyDetails['ec']['d']), '+/', '-_'), '=');
return [
'publicKey' => $publicKeyBase64,
'privateKey' => $privateKeyBase64,
];
}
try {
 $vapidKeys = generateVAPIDKeys();
 $updateKeys = [
 'website_push_public_key' => $vapidKeys['publicKey'],
 'website_push_private_key' => $vapidKeys['privateKey']
 ];
 $sql = "UPDATE system_options SET display = :display WHERE setting_name = :setting_name";
 $statement = $pdo->prepare($sql);
 foreach ($updateKeys as $settingName => $keyValue) {
 $statement->bindValue(':display', $keyValue, PDO::PARAM_STR);
 $statement->bindValue(':setting_name', $settingName, PDO::PARAM_STR);
 $statement->execute();
 }
} catch (Exception $e) {
 trigger_error($e->getMessage());
}
}

And this is how I store the user’s subscription keys (also working fine):

if (strpos(main_url, 'https://') === 0 && isset($data['push_subscriber']) && !empty($data['push_subscriber'])) {
$pushData = $data['push_subscriber'];
$endpoint = $pushData['endpoint'];
$p256dh = $pushData['keys']['p256dh'];
$authKey = $pushData['keys']['auth'];
$device_id_decrypted = decrypt($device_id, encryption_key);
$sql = "UPDATE users_auth_tokens SET endpoint = :endpoint, p256dh = :p256dh, authKey = :authKey WHERE email = :email AND device_id = :device_id";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':endpoint', $endpoint, PDO::PARAM_STR);
$stmt->bindParam(':p256dh', $p256dh, PDO::PARAM_STR);
$stmt->bindParam(':authKey', $authKey, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':device_id', $device_id_decrypted, PDO::PARAM_STR);
$stmt->execute();
}

Would really appreciate any help in getting push notifications to work without Minishlink\WebPush! Thanks in advance.

发布评论

评论列表(0)

  1. 暂无评论