ricwein / push-notifications
为 iOS (APNS)、Android (FCM) 提供推送通知
3.0.1
2023-11-12 10:28 UTC
Requires
- php: ^8.0
- ext-bcmath: *
- ext-curl: *
- ext-json: *
- edamov/pushok: ^0.15.0
Requires (Dev)
- composer/ca-bundle: ^1.3
- overtrue/phplint: ^9.0
Suggests
- composer/ca-bundle: Provides easy solution for system CA certificates.
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. } } }