瀏覽代碼

Update NotificationAppGatewayService

Daniel Supernault 9 月之前
父節點
當前提交
92ad62e735
共有 2 個文件被更改,包括 122 次插入4 次删除
  1. 10 4
      app/Console/Commands/PushGatewayRefresh.php
  2. 112 0
      app/Services/NotificationAppGatewayService.php

+ 10 - 4
app/Console/Commands/PushGatewayRefresh.php

@@ -2,8 +2,9 @@
 
 
 namespace App\Console\Commands;
 namespace App\Console\Commands;
 
 
-use Illuminate\Console\Command;
 use App\Services\NotificationAppGatewayService;
 use App\Services\NotificationAppGatewayService;
+use Illuminate\Console\Command;
+
 use function Laravel\Prompts\select;
 use function Laravel\Prompts\select;
 
 
 class PushGatewayRefresh extends Command
 class PushGatewayRefresh extends Command
@@ -32,8 +33,9 @@ class PushGatewayRefresh extends Command
 
 
         $currentState = NotificationAppGatewayService::enabled();
         $currentState = NotificationAppGatewayService::enabled();
 
 
-        if($currentState) {
+        if ($currentState) {
             $this->info('Push Notification support is active!');
             $this->info('Push Notification support is active!');
+
             return;
             return;
         } else {
         } else {
             $this->error('Push notification support is NOT active');
             $this->error('Push notification support is NOT active');
@@ -44,22 +46,26 @@ class PushGatewayRefresh extends Command
                 required: true
                 required: true
             );
             );
 
 
-            if($action === 'Yes') {
+            if ($action === 'Yes') {
                 $recheck = NotificationAppGatewayService::forceSupportRecheck();
                 $recheck = NotificationAppGatewayService::forceSupportRecheck();
-                if($recheck) {
+                if ($recheck) {
                     $this->info('Success! Push Notifications are now active!');
                     $this->info('Success! Push Notifications are now active!');
+
                     return;
                     return;
                 } else {
                 } else {
                     $this->error('Error, please ensure you have a valid API key.');
                     $this->error('Error, please ensure you have a valid API key.');
                     $this->line(' ');
                     $this->line(' ');
                     $this->line('For more info, visit https://docs.pixelfed.org/running-pixelfed/push-notifications.html');
                     $this->line('For more info, visit https://docs.pixelfed.org/running-pixelfed/push-notifications.html');
                     $this->line(' ');
                     $this->line(' ');
+
                     return;
                     return;
                 }
                 }
+
                 return;
                 return;
             } else {
             } else {
                 exit;
                 exit;
             }
             }
+
             return;
             return;
         }
         }
     }
     }

+ 112 - 0
app/Services/NotificationAppGatewayService.php

@@ -2,10 +2,122 @@
 
 
 namespace App\Services;
 namespace App\Services;
 
 
+use Cache;
+use Exception;
+use Illuminate\Http\Client\RequestException;
+use Illuminate\Support\Facades\Http;
+
 class NotificationAppGatewayService
 class NotificationAppGatewayService
 {
 {
+    const GATEWAY_SUPPORT_CHECK = 'px:nags:gateway-support-check';
+
     public static function config()
     public static function config()
     {
     {
         return config('instance.notifications.nag');
         return config('instance.notifications.nag');
     }
     }
+
+    public static function enabled()
+    {
+        if ((bool) config('instance.notifications.nag.enabled') === false) {
+            return false;
+        }
+
+        $apiKey = config('instance.notifications.nag.api_key');
+        if (! $apiKey || empty($apiKey) || strlen($apiKey) !== 45) {
+            return false;
+        }
+
+        return Cache::remember(self::GATEWAY_SUPPORT_CHECK, 43200, function () {
+            return self::checkServerSupport();
+        });
+    }
+
+    public static function checkServerSupport()
+    {
+        $endpoint = 'https://'.config('instance.notifications.nag.endpoint').'/api/v1/instance-check?domain='.config('pixelfed.domain.app');
+        try {
+            $res = Http::withHeaders(['X-PIXELFED-API' => 1])
+                ->retry(3, 500)
+                ->throw()
+                ->get($endpoint);
+
+            $data = $res->json();
+        } catch (RequestException $e) {
+            return false;
+        } catch (Exception $e) {
+            return false;
+        }
+
+        if ($res->successful() && isset($data['active']) && $data['active'] === true) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public static function forceSupportRecheck()
+    {
+        Cache::forget(self::GATEWAY_SUPPORT_CHECK);
+
+        return self::enabled();
+    }
+
+    public static function isValidExpoPushToken($token)
+    {
+        if (! $token || empty($token)) {
+            return false;
+        }
+        $starts = str_starts_with($token, 'Expo');
+        if (! $starts) {
+            return false;
+        }
+        if (! str_contains($token, 'PushToken[') || ! str_contains($token, ']')) {
+            return false;
+        }
+        if (substr($token, -1) !== ']') {
+            return false;
+        }
+
+        return true;
+    }
+
+    public static function send($userToken, $type, $actor = '')
+    {
+        if (! self::enabled()) {
+            return false;
+        }
+
+        if (! $userToken || empty($userToken) || ! self::isValidExpoPushToken($userToken)) {
+            return false;
+        }
+
+        $types = ['new_follower', 'like', 'comment', 'share'];
+
+        if (! $type || empty($type) || ! in_array($type, $types)) {
+            return false;
+        }
+
+        $apiKey = config('instance.notifications.nag.api_key');
+
+        if (! $apiKey || empty($apiKey)) {
+            return false;
+        }
+        $url = 'https://'.config('instance.notifications.nag.endpoint').'/api/v1/relay/deliver';
+
+        try {
+            $response = Http::withToken($apiKey)
+                ->withHeaders(['X-PIXELFED-API' => 1])
+                ->post($url, [
+                    'token' => $userToken,
+                    'type' => $type,
+                    'actor' => $actor,
+                ]);
+
+            $response->throw();
+        } catch (RequestException $e) {
+            return;
+        } catch (Exception $e) {
+            return;
+        }
+    }
 }
 }