Install Pushok via Composer
masterInstall the Pushok library using Composer to start sending push notifications to APNs.
$ composer require edamov/pushokrepository·master·Indexed 19 days ago
https://github.com/edamov/pushokA simple PHP library for sending push notifications to the Apple Push Notification service (APNs) using the HTTP/2 protocol. Pushok supports both JWT-based and Certificate-based authentication, providing a Client for queuing and sending notifications in bulk with configurable concurrency and connection settings. Requires PHP >= 8.2, lib-curl >= 7.46.0 with HTTP/2 support, and lib-openssl >= 1.0.2e.
Install the Pushok library using Composer to start sending push notifications to APNs.
$ composer require edamov/pushokTo send notifications, follow these steps:
AuthProvider (JWT or Certificate).Payload with an Alert.Notification objects for each device token.Client and add the notifications.push() to send them.use Pushok\Client;
use Pushok\Notification;
use Pushok\Payload;
use Pushok\Payload\Alert;
// 1. Setup Auth (Assuming $authProvider is already created)
// 2. Create Payload
$alert = Alert::create()->setTitle('Hello!')->setBody('First push notification');
$payload = Payload::create()->setAlert($alert);
$payload->setSound('default');
$payload->setCustomValue('key', 'value');
// 3. Prepare Notifications
$deviceTokens = ['<token_1>', '<token_2>'];
$notifications = [];
foreach ($deviceTokens as $token) {
$notifications[] = new Notification($payload, $token);
}
// 4. Send
$client = new Client($authProvider, $production = false);
$client->addNotifications($notifications);
$responses = $client->push();use Pushok\Client;
use Pushok\Notification;
use Pushok\Payload;
use Pushok\Payload\Alert;
$alert = Alert::create()->setTitle('Hello!')->setBody('First push notification');
$payload = Payload::create()->setAlert($alert);
$payload->setSound('default');
$payload->setCustomValue('key', 'value');
$deviceTokens = ['<device_token_1>', '<device_token_2>'];
$notifications = [];
foreach ($deviceTokens as $deviceToken) {
$notifications[] = new Notification($payload, $deviceToken);
}
$client = new Client($authProvider, $production = false);
$client->addNotifications($notifications);
$responses = $client->push();To use Pushok, ensure your environment meets the following requirements:
If you are using Docker, you can use the official image edamov/pushok-docker which is pre-configured with these requirements.
The Token provider automatically calculates the apns-topic header based on the apns-push-type provided in the request headers. This ensures compatibility with different Apple push notification types.
Mapping logic:
voip $\rightarrow$ {app_bundle_id}.voipliveactivity $\rightarrow$ {app_bundle_id}.push-type.liveactivitycomplication $\rightarrow$ {app_bundle_id}.complicationfileprovider $\rightarrow$ {app_bundle_id}.pushkit.fileprovider{app_bundle_id}The Certificate provider automatically generates the apns-topic header based on the apns-push-type provided in the request headers and the configured app_bundle_id.
Mapping logic:
apns-push-type is voip: {app_bundle_id}.voipapns-push-type is complication: {app_bundle_id}.complicationapns-push-type is fileprovider: {app_bundle_id}.pushkit.fileprovider{app_bundle_id}You can tune the performance of the Client by adjusting how many requests and connections are handled concurrently.
setNbConcurrentRequests(int $count): Sets the number of concurrent requests sent through multiplexed connections. Default: 20.setMaxConcurrentConnections(int $count): Sets the maximum number of concurrent connections established to APNS servers. Default: 1.$client = new Client($authProvider, $production = false);
$client->setNbConcurrentRequests(40);
$client->setMaxConcurrentConnections(5);
$client->addNotifications($notifications);
$responses = $client->push();Pushok supports JWT-based authentication. You need to provide your Apple Developer credentials to create a Token auth provider.
Required options:
key_id: The Key ID from your Apple developer account.team_id: The Team ID from your Apple developer account.app_bundle_id: The bundle ID for your app.private_key_path: Path to your .p8 private key file.private_key_secret: (Optional) Private key secret.Note: JWT tokens expire after one hour. For long-running tasks, you must regenerate the token.
use Pushok\
AuthProvider\\Token;
$options = [
'key_id' => 'AAAABBBBCC',
'team_id' => 'DDDDEEEEFF',
'app_bundle_id' => 'com.app.Test',
'private_key_path' => __DIR__ . '/private_key.p8',
'private_key_secret' => null
];
$authProvider = AuthProvider\\Token::create($options);use Pushok\AuthProvider\Token;
$options = [
'key_id' => 'AAAABBBBCC',
'team_id' => 'DDDDEEEEFF',
'app_bundle_id' => 'com.app.Test',
'private_key_path' => __DIR__ . '/private_key.p8',
'private_key_secret' => null
];
$authProvider = AuthProvider\Token::create($options);The push() method returns an array of ApnsResponseInterface objects. Use these to inspect the result of each notification attempt.
Available methods on the response object:
getDeviceToken(): The device token used.getApnsId(): A canonical UUID unique to the notification.getStatusCode(): HTTP status code (e.g., 200 for success, 410 for inactive token).getReasonPhrase(): The HTTP reason phrase.getErrorReason(): Error reason (e.g., Unregistered).getErrorDescription(): Detailed error description.get410Timestamp(): Timestamp for 410 errors.foreach ($responses as $response) {
echo $response->getStatusCode();
echo $response->getApnsId();
// ... handle errors based on getStatusCode() or getErrorReason()
}foreach ($responses as $response) {
$response->getDeviceToken();
$response->getApnsId();
$response->getStatusCode();
$response->getReasonPhrase();
$response->getErrorReason();
$response->getErrorDescription();
$response->get410Timestamp();
}You can use certificate-based authentication by providing a .pem or .p12 file.
Required options:
app_bundle_id: The bundle ID for your app.certificate_path: Path to your certificate file.certificate_secret: (Optional) Certificate secret.use Pushok\\AuthProvider\\Certificate;
$options = [
'app_bundle_id' => 'com.app.Test',
'certificate_path' => __DIR__ . '/private_key.pem',
'certificate_secret' => null
];
$authProvider = AuthProvider\\Certificate::create($options);use Pushok\AuthProvider\Certificate;
$options = [
'app_bundle_id' => 'com.app.Test',
'certificate_path' => __DIR__ . '/private_key.pem',
'certificate_secret' => null
];
$authProvider = AuthProvider\Certificate::create($options);The Pushok\AuthProvider\Token class implements JWT-based authentication for APNs. When creating a provider, you must provide a set of options containing your Apple developer credentials.
Required options:
key_id: The Key ID obtained from your Apple developer account.team_id: The Team ID obtained from your Apple developer account.app_bundle_id: The bundle ID for your app.Optional private key options (you must provide exactly one of these):
private_key_path: The file system path to your .p8 private key file.private_key_content: The raw string content of your .p8 private key.private_key_secret: The passphrase/secret for the private key (if applicable).$options = [
'key_id' => 'ABC123DEFG',
'team_id' => 'TEAMID123',
'app_bundle_id' => 'com.example.app',
'private_key_path' => '/path/to/AuthKey_ABC123DEFG.p8',
// or 'private_key_content' => '...',
// or 'private_key_secret' => '...',
];When creating a Certificate auth provider via Certificate::create(), you must provide the following options in the array:
| Key | Type | Description |
|---|---|---|
certificate_path | string | The filesystem path to your certificate file. |
certificate_secret | string | The password/secret for the certificate. |
app_bundle_id | string | (Optional) The bundle ID for your app obtained from your Apple developer account. This is used to generate the apns-topic header. |
When calling toJson(), Pushok validates the size of the generated JSON string against APNs limits. If the payload exceeds these limits, an InvalidPayloadException is thrown.
Limits:
5120 bytes (when setPushType('voip') is used).4096 bytes.Note: These limits apply to the HTTP/2 payload size.