ricwein/push-notifications

为 iOS (APNS)、Android (FCM) 提供推送通知

3.0.1 2023-11-12 10:28 UTC

This package is auto-updated.

Last update: 2024-09-12 12:17:10 UTC


README

... 是一个小的 PHP 库,用于将 Apple (APNS) 和 Google (FCM) 推送通知包装成简单的语法。

示例

Android

use ricwein\PushNotification\{PushNotification, Message, Handler};

$message = new Message('message', 'title', ['payload' => 'data']);
$fcm = new Handler\FCM('ExampleGooglePushToken12345678987654321');

$push = new PushNotification(['fcm' => $fcm]);
$push->send($message, ['<device-token>' => 'fcm']);

iOS

注意:APNS 处理器使用新的苹果推送服务器,这些服务器需要 HTTP2。因此,必须安装支持 HTTP2 的 curl。

use ricwein\PushNotification\{PushNotification, Message, Handler, Config};
use Pushok\AuthProvider;

$message = new Message('message', 'title', ['payload' => 'data']);
$apns = new Handler\APNS(AuthProvider\Token::create([
    'key_id' => 'AAAABBBBCC', // The Key ID obtained from Apple developer account
    'team_id' => 'DDDDEEEEFF', // The Team ID obtained from Apple developer account
    'app_bundle_id' => 'com.app.Test', // The bundle ID for app obtained from Apple developer account
    'private_key_path' => __DIR__ . '/private_key.p8', // Path to private key
    'private_key_secret' => null // Private key secret
]), Config::ENV_PRODUCTION);

$push = new PushNotification(['apns' => $apns]);
$push->send($message, ['<device-token>' => 'apns']);

混合

发送不同操作系统的多个设备的消息也非常简单

use ricwein\PushNotification\{PushNotification, Message, Handler, Config};

$message = new Message('message', 'title');
$fcm = new Handler\FCM('ExampleGooglePushToken12345678987654321');
$apns = new Handler\APNS($authToken, Config::ENV_PRODUCTION);

$push = new PushNotification(['apns' => $apns, 'fcm' => $fcm]);
$push->send($message, [
    '<ios-device-token1>' => 'apns',
    '<ios-device-token2>' => 'apns',
    '<android-device-token1>' => 'fcm',
    '<android-device-token2>' => 'fcm',
]);

单条消息/单个处理器

对于单条处理器消息,可以将处理器内联到设备目标数组中。消息发送后,处理器将自动释放。

use ricwein\PushNotification\{PushNotification, Message, Handler};

$result = (new PushNotification)->send(new Message($body,$title), [
    '<device-token>' => new Handler\<APNS/FCM/etc.>(...$config);
]);

用法

该类使用根命名空间 ricwein\PushNotification

初始化

库的主要类名为 PushNotification,它需要一个可用的推送处理器的数组来构造函数。可以设置一个 ID 作为处理器数组的键,以便以后将设备分配给处理器。

可用的推送处理器包括

  • 苹果:PushNotification\Handler\APNS
  • 谷歌:PushNotification\Handler\FCM

它们都扩展了 PushNotification\Handler

配置

由于所有推送设置都是针对推送处理器特定的,因此设置直接应用于处理器构造函数中。

  • APNS
 new APNS(
    \Pushok\AuthProviderInterface $authProvider, /* @see https://github.com/edamov/pushok/blob/master/README.md#getting-started */
    string $environment /* (Config::ENV_PRODUCTION / Config::ENV_DEVELOPMENT / Config::ENV_CUSTOM) */
)
  • FCM
 new FCM(
    string $token,
    ?string $caCertPath = null,
    string $url = self::FCM_ENDPOINT,
    int $timeout = 10
)

还可以有多个配置不同的推送处理器,例如

use ricwein\PushNotification\{PushNotification, Message, Handler, Config};

// @see https://github.com/edamov/pushok
$apnsProd = new Handler\APNS($tokenProd, Config::ENV_PRODUCTION);
$apnsDev = new Handler\APNS($tokenDev, Config::ENV_DEVELOPMENT);

$message = new Message('message', 'title');
$push = new PushNotification(['prod' => $apnsProd, 'dev' => $apnsDev]);

$push->send($message, [
    '<ios-device-token1>' => 'prod',
    '<ios-device-token2>' => 'dev',
]);

发送

发送可以是消息对象或原始有效负载的可用选项。

  • 消息对象在发送之前被转换为带有 FCM 或 APNS 的正文和标题的原生推送通知消息。
  • 原始有效负载(数组)将“原样”发送,这可能 不是 一个好主意,如果您想在单个请求中混合 APNS 和 FCM。
use ricwein\PushNotification\{Message, Config};

$devices = [...];

$message = new Message('body', 'title');
$message->setSound('test.aiff')->setBadge(2)->setPriority(Config::PRIORITY_NORMAL);
$push->send($message, $devices);

/* OR */

$payload = [...];
$push->sendRaw($payload, $devices);

错误处理

方法 PushNotification::send() 返回一个 Result 对象。这通常包含每个设备的错误数组。如果一切成功,条目为 null。您可以使用以下方式检索失败设备消息:

$result = $push->send($message, [...]);
$errors = $result->getFailed(); 

错误被处理为异常,因此可以简单地抛出它们。如果发生了一个错误,只需调用

$push->send($message, [...])->throwOnFirstException();

请注意:有时会发生的失败不仅仅是使用错误。APNS 和 FCM 可以明确地响应原因,这将被处理为 ResponseReasonException最好不要简单地丢弃它们,而是以其他方式处理。例如,您可能想删除或更新已标记为无效的设备令牌。

use \ricwein\PushNotification\Exceptions\ResponseReasonException;

foreach($result->getFailed() as $token => $error) {
    if ($error instanceof ResponseReasonException) {
        if ($error->isInvalidDeviceToken()) {
            // $token was invalid
        } elseif ($error->isRateLimited()) {
            // the $token device got too many notifications and is currently rate-limited => better wait some time before sending again.
        }       

    }
}