2021-08-15 16:52:46 -04:00
< ? php
/**
* @ copyright Copyright ( C ) 2010 - 2021 , the Friendica project
*
* @ 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 18:53:52 -04:00
use Friendica\Content\Text\BBCode ;
use Friendica\Content\Text\Plaintext ;
2021-08-15 16:52:46 -04:00
use Friendica\Core\Logger ;
use Friendica\Database\DBA ;
2021-08-15 17:24:23 -04:00
use Friendica\DI ;
2021-08-16 02:11:26 -04:00
use Friendica\Model\Contact ;
2021-08-17 18:53:52 -04:00
use Friendica\Model\Post ;
2021-08-15 17:24:23 -04:00
use Friendica\Model\Subscription as ModelSubscription ;
2021-08-17 18:53:52 -04:00
use Friendica\Model\User ;
2021-09-18 00:03:32 -04:00
use Friendica\Navigation\Notifications ;
use Friendica\Network\HTTPException\NotFoundException ;
2021-08-15 16:52:46 -04:00
use Minishlink\WebPush\WebPush ;
use Minishlink\WebPush\Subscription ;
2021-08-15 17:03:43 -04:00
class PushSubscription
2021-08-15 16:52:46 -04:00
{
2021-08-16 02:11:26 -04:00
public static function execute ( int $sid , int $nid )
2021-08-15 16:52:46 -04:00
{
2021-08-16 11:23:34 -04:00
Logger :: info ( 'Start' , [ 'subscription' => $sid , 'notification' => $nid ]);
2021-08-15 16:52:46 -04:00
$subscription = DBA :: selectFirst ( 'subscription' , [], [ 'id' => $sid ]);
2021-08-16 11:23:34 -04:00
if ( empty ( $subscription )) {
Logger :: info ( 'Subscription not found' , [ 'subscription' => $sid ]);
return ;
}
2021-09-18 00:03:32 -04:00
try {
$Notification = DI :: notification () -> selectOneById ( $nid );
} catch ( NotFoundException $e ) {
2021-08-16 11:23:34 -04:00
Logger :: info ( 'Notification not found' , [ 'notification' => $nid ]);
return ;
}
2021-08-15 16:52:46 -04:00
2021-08-17 18:53:52 -04: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 ;
}
2021-09-18 00:03:32 -04:00
$user = User :: getById ( $Notification -> uid );
2021-08-17 18:53:52 -04:00
if ( empty ( $user )) {
Logger :: info ( 'User not found' , [ 'application' => $subscription [ 'uid' ]]);
return ;
2021-08-16 02:11:26 -04:00
}
2021-08-17 18:53:52 -04:00
$l10n = DI :: l10n () -> withLang ( $user [ 'language' ]);
2021-09-18 00:03:32 -04:00
if ( $Notification -> actorId ) {
$actor = Contact :: getById ( $Notification -> actorId );
2021-08-16 02:11:26 -04:00
}
2021-08-17 18:53:52 -04:00
$body = '' ;
2021-09-18 00:03:32 -04:00
if ( $Notification -> targetUriId ) {
$post = Post :: selectFirst ([], [ 'uri-id' => $Notification -> targetUriId , 'uid' => [ 0 , $Notification -> uid ]]);
2021-08-17 18:53:52 -04:00
if ( ! empty ( $post [ 'body' ])) {
$body = BBCode :: toPlaintext ( $post [ 'body' ], false );
2021-09-18 00:03:32 -04:00
$body = Plaintext :: shorten ( $body , 160 , $Notification -> uid );
2021-08-17 18:53:52 -04:00
}
}
2021-09-19 12:56:24 -04:00
$message = DI :: notificationFactory () -> getMessageFromNotification ( $Notification , DI :: baseUrl (), $l10n );
2021-08-19 09:58:55 -04:00
$title = $message [ 'plain' ] ? : '' ;
2021-08-18 06:27:45 -04:00
2021-08-17 18:53:52 -04: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 ,
2021-09-18 00:03:32 -04:00
'notification_type' => \Friendica\Factory\Api\Mastodon\Notification :: getType ( $Notification ),
2021-08-17 18:53:52 -04:00
'icon' => $actor [ 'thumb' ] ? ? '' ,
2021-08-18 06:27:45 -04:00
'title' => $title ? : $l10n -> t ( 'Notification from Friendica' ),
2021-08-17 18:53:52 -04:00
'body' => $body ? : $l10n -> t ( 'Empty Post' ),
2021-08-15 16:52:46 -04:00
];
2021-08-17 18:53:52 -04:00
Logger :: info ( 'Payload' , [ 'payload' => $payload ]);
2021-08-15 17:24:23 -04:00
$auth = [
'VAPID' => [
2021-08-15 17:30:27 -04:00
'subject' => DI :: baseUrl () -> getHostname (),
'publicKey' => ModelSubscription :: getPublicVapidKey (),
2021-08-15 17:24:23 -04:00
'privateKey' => ModelSubscription :: getPrivateVapidKey (),
],
];
2021-08-15 17:30:27 -04:00
2021-08-16 11:23:34 -04:00
$webPush = new WebPush ( $auth , [], DI :: config () -> get ( 'system' , 'xrd_timeout' ));
2021-08-15 16:52:46 -04:00
2021-08-17 18:53:52 -04:00
$report = $webPush -> sendOneNotification ( $push , json_encode ( $payload ), [ 'urgency' => 'normal' ]);
2021-08-15 17:01:58 -04:00
2021-08-15 16:52:46 -04:00
$endpoint = $report -> getRequest () -> getUri () -> __toString ();
if ( $report -> isSuccess ()) {
2021-08-16 11:23:34 -04:00
Logger :: info ( 'Message sent successfully for subscription' , [ 'subscription' => $sid , 'notification' => $nid , 'endpoint' => $endpoint ]);
2021-08-15 16:52:46 -04:00
} else {
2021-08-16 11:23:34 -04:00
Logger :: info ( 'Message failed to sent for subscription' , [ 'subscription' => $sid , 'notification' => $nid , 'endpoint' => $endpoint , 'reason' => $report -> getReason ()]);
2021-08-15 16:52:46 -04:00
}
}
}