2021-08-15 20:52:46 +00:00
< ? php
/**
2023-01-01 14:36:24 +00:00
* @ copyright Copyright ( C ) 2010 - 2023 , the Friendica project
2021-08-15 20:52:46 +00:00
*
* @ license GNU AGPL version 3 or any later version
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation , either version 3 of the
* License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*
*/
namespace Friendica\Worker ;
2021-08-17 22:53:52 +00:00
use Friendica\Content\Text\BBCode ;
use Friendica\Content\Text\Plaintext ;
2021-08-15 20:52:46 +00:00
use Friendica\Core\Logger ;
use Friendica\Database\DBA ;
2021-08-15 21:24:23 +00:00
use Friendica\DI ;
2022-06-23 14:03:55 +00:00
use Friendica\Factory\Api\Mastodon\Notification as NotificationFactory ;
2021-08-16 06:11:26 +00:00
use Friendica\Model\Contact ;
2021-08-17 22:53:52 +00:00
use Friendica\Model\Post ;
2021-08-15 21:24:23 +00:00
use Friendica\Model\Subscription as ModelSubscription ;
2021-08-17 22:53:52 +00:00
use Friendica\Model\User ;
2021-09-18 04:03:32 +00:00
use Friendica\Network\HTTPException\NotFoundException ;
2021-08-15 20:52:46 +00:00
use Minishlink\WebPush\WebPush ;
use Minishlink\WebPush\Subscription ;
2021-08-15 21:03:43 +00:00
class PushSubscription
2021-08-15 20:52:46 +00:00
{
2022-06-23 11:56:18 +00:00
/**
* Creates push subscription by subscription and notification ids
*
* @ param int $sid Subscription id
* @ param int $nid Notification id
* @ return void
*/
2021-08-16 06:11:26 +00:00
public static function execute ( int $sid , int $nid )
2021-08-15 20:52:46 +00:00
{
2021-08-16 15:23:34 +00:00
Logger :: info ( 'Start' , [ 'subscription' => $sid , 'notification' => $nid ]);
2021-08-15 20:52:46 +00:00
$subscription = DBA :: selectFirst ( 'subscription' , [], [ 'id' => $sid ]);
2021-08-16 15:23:34 +00:00
if ( empty ( $subscription )) {
Logger :: info ( 'Subscription not found' , [ 'subscription' => $sid ]);
return ;
}
2021-09-18 04:03:32 +00:00
try {
2022-06-23 11:56:18 +00:00
$notification = DI :: notification () -> selectOneById ( $nid );
2021-09-18 04:03:32 +00:00
} catch ( NotFoundException $e ) {
2021-08-16 15:23:34 +00:00
Logger :: info ( 'Notification not found' , [ 'notification' => $nid ]);
return ;
}
2021-08-15 20:52:46 +00:00
2021-08-17 22:53:52 +00:00
$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 ;
}
2022-06-23 11:56:18 +00:00
$user = User :: getById ( $notification -> uid );
2021-08-17 22:53:52 +00:00
if ( empty ( $user )) {
Logger :: info ( 'User not found' , [ 'application' => $subscription [ 'uid' ]]);
return ;
2021-08-16 06:11:26 +00:00
}
2021-08-17 22:53:52 +00:00
$l10n = DI :: l10n () -> withLang ( $user [ 'language' ]);
2022-06-23 11:56:18 +00:00
if ( $notification -> actorId ) {
$actor = Contact :: getById ( $notification -> actorId );
2021-08-16 06:11:26 +00:00
}
2021-08-17 22:53:52 +00:00
$body = '' ;
2022-06-23 11:56:18 +00:00
if ( $notification -> targetUriId ) {
$post = Post :: selectFirst ([], [ 'uri-id' => $notification -> targetUriId , 'uid' => [ 0 , $notification -> uid ]]);
2021-08-17 22:53:52 +00:00
if ( ! empty ( $post [ 'body' ])) {
$body = BBCode :: toPlaintext ( $post [ 'body' ], false );
2022-06-23 11:56:18 +00:00
$body = Plaintext :: shorten ( $body , 160 , $notification -> uid );
2021-08-17 22:53:52 +00:00
}
}
2022-06-23 11:56:18 +00:00
$message = DI :: notificationFactory () -> getMessageFromNotification ( $notification );
2022-09-16 05:00:06 +00:00
$title = $message [ 'plain' ] ? ? '' ;
2021-08-18 10:27:45 +00:00
2021-08-17 22:53:52 +00:00
$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 ,
2022-06-23 14:03:55 +00:00
'notification_type' => NotificationFactory :: getType ( $notification ),
2021-08-17 22:53:52 +00:00
'icon' => $actor [ 'thumb' ] ? ? '' ,
2021-08-18 10:27:45 +00:00
'title' => $title ? : $l10n -> t ( 'Notification from Friendica' ),
2021-08-17 22:53:52 +00:00
'body' => $body ? : $l10n -> t ( 'Empty Post' ),
2021-08-15 20:52:46 +00:00
];
2021-08-17 22:53:52 +00:00
Logger :: info ( 'Payload' , [ 'payload' => $payload ]);
2021-08-15 21:24:23 +00:00
$auth = [
'VAPID' => [
2023-02-18 19:57:30 +00:00
'subject' => DI :: baseUrl () -> getHost (),
2021-08-15 21:30:27 +00:00
'publicKey' => ModelSubscription :: getPublicVapidKey (),
2021-08-15 21:24:23 +00:00
'privateKey' => ModelSubscription :: getPrivateVapidKey (),
],
];
2021-08-15 21:30:27 +00:00
2021-08-16 15:23:34 +00:00
$webPush = new WebPush ( $auth , [], DI :: config () -> get ( 'system' , 'xrd_timeout' ));
2021-08-15 20:52:46 +00:00
2021-08-17 22:53:52 +00:00
$report = $webPush -> sendOneNotification ( $push , json_encode ( $payload ), [ 'urgency' => 'normal' ]);
2021-08-15 21:01:58 +00:00
2021-08-15 20:52:46 +00:00
$endpoint = $report -> getRequest () -> getUri () -> __toString ();
if ( $report -> isSuccess ()) {
2021-08-16 15:23:34 +00:00
Logger :: info ( 'Message sent successfully for subscription' , [ 'subscription' => $sid , 'notification' => $nid , 'endpoint' => $endpoint ]);
2021-08-15 20:52:46 +00:00
} else {
2021-08-16 15:23:34 +00:00
Logger :: info ( 'Message failed to sent for subscription' , [ 'subscription' => $sid , 'notification' => $nid , 'endpoint' => $endpoint , 'reason' => $report -> getReason ()]);
2021-08-15 20:52:46 +00:00
}
}
}