]> git.mxchange.org Git - friendica.git/blobdiff - src/Worker/PushSubscription.php
Merge pull request #11503 from annando/bulk-delivery
[friendica.git] / src / Worker / PushSubscription.php
index de385afa1c16d0a497fa72b37c90499526546acb..45ecb62291a08a2e7fcc6e39a2045967d40a5fe3 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @copyright Copyright (C) 2010-2021, the Friendica project
+ * @copyright Copyright (C) 2010-2022, the Friendica project
  *
  * @license GNU AGPL version 3 or any later version
  *
 
 namespace Friendica\Worker;
 
+use Friendica\Content\Text\BBCode;
+use Friendica\Content\Text\Plaintext;
 use Friendica\Core\Logger;
 use Friendica\Database\DBA;
 use Friendica\DI;
+use Friendica\Model\Contact;
+use Friendica\Model\Post;
 use Friendica\Model\Subscription as ModelSubscription;
+use Friendica\Model\User;
+use Friendica\Navigation\Notifications;
+use Friendica\Network\HTTPException\NotFoundException;
 use Minishlink\WebPush\WebPush;
 use Minishlink\WebPush\Subscription;
 
 class PushSubscription
 {
-       public static function execute(int $sid)
+       public static function execute(int $sid, int $nid)
        {
+               Logger::info('Start', ['subscription' => $sid, 'notification' => $nid]);
+
                $subscription = DBA::selectFirst('subscription', [], ['id' => $sid]);
+               if (empty($subscription)) {
+                       Logger::info('Subscription not found', ['subscription' => $sid]);
+                       return;
+               }
+
+               try {
+                       $Notification = DI::notification()->selectOneById($nid);
+               } catch (NotFoundException $e) {
+                       Logger::info('Notification not found', ['notification' => $nid]);
+                       return;
+               }
+
+               $application_token = DBA::selectFirst('application-token', [], ['application-id' => $subscription['application-id'], 'uid' => $subscription['uid']]);
+               if (empty($application_token)) {
+                       Logger::info('Application token not found', ['application' => $subscription['application-id']]);
+                       return;
+               }
+
+               $user = User::getById($Notification->uid);
+               if (empty($user)) {
+                       Logger::info('User not found', ['application' => $subscription['uid']]);
+                       return;
+               }
+
+               $l10n = DI::l10n()->withLang($user['language']);
 
-               $notification = [
-                       'subscription' => Subscription::create([
-                               'endpoint'  => $subscription['endpoint'],
-                               'publicKey' => $subscription['pubkey'],
-                               'authToken' => $subscription['secret'],
-                       ]),
-                       'payload' => null,
+               if ($Notification->actorId) {
+                       $actor = Contact::getById($Notification->actorId);
+               }
+
+               $body = '';
+
+               if ($Notification->targetUriId) {
+                       $post = Post::selectFirst([], ['uri-id' => $Notification->targetUriId, 'uid' => [0, $Notification->uid]]);
+                       if (!empty($post['body'])) {
+                               $body = BBCode::toPlaintext($post['body'], false);
+                               $body = Plaintext::shorten($body, 160, $Notification->uid);
+                       }
+               }
+
+               $message = DI::notificationFactory()->getMessageFromNotification($Notification);
+               $title = $message['plain'] ?: '';
+
+               $push = Subscription::create([
+                       'contentEncoding' => 'aesgcm',
+                       'endpoint'        => $subscription['endpoint'],
+                       'keys'            => [
+                               'p256dh' => $subscription['pubkey'],
+                               'auth'   => $subscription['secret']
+                       ],
+               ]);
+
+               $payload = [
+                       'access_token'      => $application_token['access_token'],
+                       'preferred_locale'  => $user['language'],
+                       'notification_id'   => $nid,
+                       'notification_type' => \Friendica\Factory\Api\Mastodon\Notification::getType($Notification),
+                       'icon'              => $actor['thumb'] ?? '',
+                       'title'             => $title ?: $l10n->t('Notification from Friendica'),
+                       'body'              => $body ?: $l10n->t('Empty Post'),
                ];
 
+               Logger::info('Payload', ['payload' => $payload]);
+
                $auth = [
                        'VAPID' => [
                                'subject'    => DI::baseUrl()->getHostname(),
@@ -51,19 +114,16 @@ class PushSubscription
                        ],
                ];
 
-               $webPush = new WebPush($auth);
+               $webPush = new WebPush($auth, [], DI::config()->get('system', 'xrd_timeout'));
 
-               $report = $webPush->sendOneNotification(
-                       $notification['subscription'],
-                       $notification['payload']
-               );
+               $report = $webPush->sendOneNotification($push, json_encode($payload), ['urgency' => 'normal']);
 
                $endpoint = $report->getRequest()->getUri()->__toString();
 
                if ($report->isSuccess()) {
-                       Logger::info('Message sent successfully for subscription', ['endpoint' => $endpoint]);
+                       Logger::info('Message sent successfully for subscription', ['subscription' => $sid, 'notification' => $nid, 'endpoint' => $endpoint]);
                } else {
-                       Logger::info('Message failed to sent for subscription', ['endpoint' => $endpoint, 'reason' => $report->getReason()]);
+                       Logger::info('Message failed to sent for subscription', ['subscription' => $sid, 'notification' => $nid, 'endpoint' => $endpoint, 'reason' => $report->getReason()]);
                }
        }
 }