### Install Ably Laravel Broadcaster Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Install the package using Composer. ```bash composer require ably/laravel-broadcaster ``` -------------------------------- ### Complete .env Example for Ably Broadcaster Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md A comprehensive .env file example including broadcasting connection, Ably credentials, and broadcaster-specific configurations like time synchronization and token expiry. ```env # Broadcasting BROADCAST_CONNECTION=ably # Ably Credentials ABLY_KEY=your_public_key:your_private_key # Ably Broadcaster Configuration ABLY_SYNC_SERVER_TIME=false ABLY_DISABLE_PUBLIC_CHANNELS=false ABLY_TOKEN_EXPIRY=28800 ``` -------------------------------- ### Install Ably Laravel Echo and ably-js SDK Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md Install the necessary packages for using Ably with Laravel Echo and the ably-js SDK. ```shell npm install @ably/laravel-echo ably@1.x ``` -------------------------------- ### Full Broadcasting Configuration Example Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Includes all available configuration options for the 'ably' driver, such as sync_server_time, disable_public_channels, and token_expiry. ```php 'connections' => [ 'ably' => [ 'driver' => 'ably', 'key' => env('ABLY_KEY'), 'sync_server_time' => env('ABLY_SYNC_SERVER_TIME', false), 'disable_public_channels' => env('ABLY_DISABLE_PUBLIC_CHANNELS', false), 'token_expiry' => env('ABLY_TOKEN_EXPIRY', 28800), ], ], ``` -------------------------------- ### Full Channel Configuration Example Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/endpoints.md Demonstrates various channel types including public, private, private with metadata, presence, and presence with custom capabilities. ```php // routes/channels.php use Illuminate\Broadcasting\Broadcast; use App\Models\User; use App\Models\Document; // Public channel - no auth required Broadcast::channel('public.announcements', function (User $user) { return true; }); // Private channel - auth required Broadcast::private('documents.{documentId}', function (User $user, int $documentId) { $doc = Document::find($documentId); return $user->can('view', $doc); }); // Private with metadata Broadcast::private('conversations.{conversationId}', function (User $user, int $conversationId) { if ($user->conversations->contains($conversationId)) { return [ 'role' => $user->roleIn($conversationId), 'unread_count' => $user->unreadInConversation($conversationId), 'last_seen' => $user->lastSeenAt($conversationId), ]; } return false; }); // Presence channel Broadcast::presence('users.online', function (User $user) { return [ 'id' => $user->id, 'name' => $user->name, 'avatar' => $user->avatar_url, ]; }); // Presence with custom capabilities Broadcast::presence('notifications.{userId}', function (User $user, int $userId) { if ($user->id === $userId) { return [ 'id' => $user->id, 'name' => $user->name, 'ably-capability' => ['subscribe', 'presence'], ]; } return false; }); ``` -------------------------------- ### Complete config/broadcasting.php Example Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md PHP configuration for the Ably broadcaster, mapping environment variables to connection settings for driver, key, time synchronization, public channel disabling, and token expiry. ```php env('BROADCAST_CONNECTION', 'ably'), 'connections' => [ 'ably' => [ 'driver' => 'ably', 'key' => env('ABLY_KEY'), 'sync_server_time' => env('ABLY_SYNC_SERVER_TIME', false), 'disable_public_channels' => env('ABLY_DISABLE_PUBLIC_CHANNELS', false), 'token_expiry' => env('ABLY_TOKEN_EXPIRY', 28800), ], ], ]; ``` -------------------------------- ### Install Ably Laravel Broadcaster Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md Install the package via composer. Ensure your PHP version is >= 7.2.0 and Laravel version is >= 6.0.0. ```bash composer require ably/laravel-broadcaster ``` -------------------------------- ### Ably Channel Pattern Matching Examples Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/types.md Illustrates how to use wildcards in capability definitions to match multiple channel names. These patterns are useful for defining broad access rules. ```php 'public:*' 'private:chat-*' 'presence:user-*' '*:admin:*' ``` -------------------------------- ### Example JSON Capability Object Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/types.md An example of the JSON structure for the `x-ably-capability` claim within a JWT payload, specifying channel patterns and their associated permissions. ```json { "public:*": ["subscribe", "history", "channel-metadata"], "private:chat": ["subscribe", "publish"], "presence:notifications": ["subscribe", "presence"] } ``` -------------------------------- ### Example Ably-Agent Header Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/service-provider.md This header shows the format of version information sent to Ably, including the broadcaster and Laravel versions. ```text Ably-Agent: ably-php/1.2.0 php/8.1 laravel-broadcaster/1.0.8 laravel/10.0 ``` -------------------------------- ### HTTP Request for Token Upgrade Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/endpoints.md Example HTTP POST request to the broadcasting/auth endpoint to upgrade a token for an additional channel. The original token is passed as a parameter. ```http POST /broadcasting/auth channel_name=private:messages.7&socket_id=...&token=eyJhbGc... ``` -------------------------------- ### Access Denied by Channel Callback Error Example Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/errors.md Shows the message format when access is denied by a channel's callback function. This happens when an authenticated user attempts to access a guarded channel, but the callback returns a falsy value, indicating a lack of permissions. ```text Access denied, user-id:42 channel-name:private:room-5 ably-connection-id:abcd:1234 ``` -------------------------------- ### Define Broadcast Channels Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/service-provider.md Register public, private, and presence channels in `routes/channels.php` using the `Broadcast` facade. This example shows how to define channels for announcements, private chat rooms, and user notifications. ```php use Illuminate\Support\Facades\Broadcast; // In routes/channels.php Broadcast::channel('public.announcements', function ($user) { return true; }); Broadcast::private('chat.{roomId}', function ($user, $roomId) { return $user->can('access-room', $roomId); }); Broadcast::presence('notifications.{userId}', function ($user, $userId) { return $user->id === $userId; }); ``` -------------------------------- ### User Not Authenticated Error Example Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/errors.md Illustrates the message format for when a user is not authenticated on a guarded channel. This occurs when a private or presence channel is accessed without an authenticated user, and the channel callback was not invoked. ```text User not authenticated, channel-name:private:chat ably-connection-id:abcd:1234 ``` -------------------------------- ### JavaScript Client-Side Usage with Ably Laravel Echo Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/endpoints.md Demonstrates listening to public, private, and presence channels using Ably Laravel Echo. Ensure Echo and Ably are installed and configured. ```javascript import Echo from '@ably/laravel-echo'; import * as Ably from 'ably'; const echo = new Echo({ broadcaster: 'ably', }); // Listen to public channel echo.channel('public.announcements') .listen('AnnouncementSent', (e) => { console.log('Announcement:', e.message); }); // Listen to private channel (triggers auth endpoint) echo.private('documents.5') .listen('DocumentUpdated', (e) => { console.log('Document updated'); }); // Listen to presence channel echo.join('notifications.42') .here((users) => { console.log('Online users:', users); }) .joining((user) => { console.log('User joined:', user.name); }) .leaving((user) => { console.log('User left:', user.name); }); ``` -------------------------------- ### Enable Server Time Synchronization Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Enable server time synchronization for environments with unreliable clocks, clock skew, or containerized setups. This involves one HTTP request on first token generation, with results cached for 6 hours. ```env ABLY_SYNC_SERVER_TIME=true ``` -------------------------------- ### Check if Channel is Private Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Determines if a given channel name starts with the 'private:' prefix. ```php is_bool($broadcaster->isPrivateChannel('private:channel')) ``` -------------------------------- ### Check if Channel is Presence Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Determines if a given channel name starts with the 'presence:' prefix. ```php is_bool($broadcaster->isPresenceChannel('presence:channel')) ``` -------------------------------- ### HTTP POST Request for Broadcasting Authentication Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/endpoints.md This snippet shows an example HTTP POST request to the broadcasting authentication endpoint. It includes the necessary channel name and socket ID for authenticating client channel subscriptions. ```http POST /broadcasting/auth HTTP/1.1 Content-Type: application/x-www-form-urlencoded channel_name=private:chat-5&socket_id=abcd.1234%3Abase64encoded&token=eyJhbGc... ``` -------------------------------- ### Malformed Token Error Example Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/errors.md Demonstrates the message format for a malformed token error. This error occurs when a client provides an invalid, corrupted, or unparsable JWT token during an authentication request for a guarded channel. ```text malformed token, user-id:42 channel-name:private:chat ably-connection-id:abcd:1234 ``` -------------------------------- ### Documentation Directory Structure Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/MANIFEST.md This tree illustrates the organization of the documentation files for the Ably Laravel Broadcaster project. ```bash output/ ├── INDEX.md # Navigation guide ├── README.md # Main overview & quick start ├── types.md # Type definitions ├── configuration.md # Configuration reference ├── endpoints.md # HTTP endpoints ├── errors.md # Error catalog ├── MANIFEST.md # This file └── api-reference/ ├── ably-broadcaster.md # Main broadcaster ├── utils.md # Utilities └── service-provider.md # Service provider ``` -------------------------------- ### ServiceProvider Method Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/MANIFEST.md The boot method for the LaravelAblyBroadcasterServiceProvider, responsible for registration and initialization. ```APIDOC ## Service Provider Method ### `boot()` Registers and initializes the Ably broadcaster service provider. ``` -------------------------------- ### isPrivateChannel() Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Checks if a channel is a private channel. A channel is considered private if its name starts with the `private:` prefix. ```APIDOC ## isPrivateChannel() ### Description Checks if a channel is a private channel. A channel is considered private if its name starts with the `private:` prefix. ### Method ```php public function isPrivateChannel(string $channel): bool ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **$channel** (string) - Yes - Channel name to check ### Returns `bool` - True if the channel starts with `private:`, false otherwise. ``` -------------------------------- ### isPresenceChannel() Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Checks if a channel is a presence channel. A channel is considered a presence channel if its name starts with the `presence:` prefix. ```APIDOC ## isPresenceChannel() ### Description Checks if a channel is a presence channel. A channel is considered a presence channel if its name starts with the `presence:` prefix. ### Method ```php public function isPresenceChannel(string $channel): bool ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **$channel** (string) - Yes - Channel name to check ### Returns `bool` - True if the channel starts with `presence:`, false otherwise. ``` -------------------------------- ### Instantiate AblyBroadcaster Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Creates a new AblyBroadcaster instance. Ensure the Ably REST SDK and configuration options are correctly provided. The configuration can include settings for server time synchronization, public channel restrictions, and token expiry. ```php use Ably\AblyRest; use Ably\LaravelBroadcaster\AblyBroadcaster; $ably = new AblyRest(['key' => env('ABLY_KEY')]); $config = [ 'sync_server_time' => env('ABLY_SYNC_SERVER_TIME', false), 'disable_public_channels' => env('ABLY_DISABLE_PUBLIC_CHANNELS', false), 'token_expiry' => env('ABLY_TOKEN_EXPIRY', 28800) ]; $broadcaster = new AblyBroadcaster($ably, $config); ``` -------------------------------- ### Configure Broadcasting Connection and Ably Key Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Update your .env file to set the broadcasting connection to 'ably' and provide your Ably API key for migration purposes. ```env BROADCAST_CONNECTION=ably ABLY_KEY=your_ably_key ``` -------------------------------- ### Configure Ably Environment Variables Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Set the broadcast connection and Ably API key in your .env file. ```env BROADCAST_CONNECTION=ably ABLY_KEY=your_public_key:your_private_key ``` -------------------------------- ### Configure Ably Driver in broadcasting.php Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Specify the Ably driver and key in the broadcasting configuration file. ```php 'ably' => [ 'driver' => 'ably', 'key' => env('ABLY_KEY'), ] ``` -------------------------------- ### normalizeChannelName() Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Removes Ably namespace prefix from a channel name. This method is useful for processing channel names received from Ably to get the base channel name. ```APIDOC ## normalizeChannelName() ### Description Removes Ably namespace prefix from a channel name. This method is useful for processing channel names received from Ably to get the base channel name. ### Method ```php public function normalizeChannelName(string $channel): string ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **$channel** (string) - Yes - Channel name with prefix ### Returns `string` - Channel name without prefix, or the original if no recognized prefix is found. ### Example ```php $broadcaster->normalizeChannelName('private:chat-room'); // 'chat-room' $broadcaster->normalizeChannelName('presence:notifications'); // 'notifications' $broadcaster->normalizeChannelName('public:announcements'); // 'announcements' ``` ``` -------------------------------- ### Running Composer Tests Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md Execute the project's tests using the Composer command. ```bash composer test ``` -------------------------------- ### Basic Broadcasting Configuration Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Configure the 'ably' driver in Laravel's broadcasting connections array. Requires the 'driver' and 'key' options. ```php 'connections' => [ 'ably' => [ 'driver' => 'ably', 'key' => env('ABLY_KEY'), ], ], ``` -------------------------------- ### Authentication Flow Diagram Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Illustrates the sequence of communication between the client, server, and Ably for event broadcasting and authentication. ```text Client Server Ably | | | |--subscribe req--->| | | |--/broadcasting/auth | | (validate user) | | |--auth token----->| |<--token-----------| | |--authenticate---->|--publish msg---->| |<--event----------|<--broadcast-------| ``` -------------------------------- ### Compile Application Assets Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md After configuring Echo, compile your application's assets to apply the changes. ```shell npm run dev ``` -------------------------------- ### Tag and Push Release Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md Creates a new Git tag for the release and pushes it to the origin repository. ```bash git tag v1.0.6 && git push origin v1.0.6 ``` -------------------------------- ### Ably Error Handling in Laravel Echo Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md Adapt your error handling to use Ably's specific error codes and ErrorInfo objects, which are more descriptive than Pusher's. This example shows how to catch an Ably token expiration error. ```javascript channel.error(error => { if (error && error.code === 40142) { // ably token expired console.error(error); // take corrective action on UI } }) ``` -------------------------------- ### Enable Debug Mode Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Set APP_DEBUG to true and LOG_LEVEL to debug in your .env file to enable debug mode for the application. ```env APP_DEBUG=true LOG_LEVEL=debug ``` -------------------------------- ### Verify Channel Configuration Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Display all configured channels in the application. Useful for debugging channel registration and access. ```php // In routes/channels.php dd(Broadcast::channels()); ``` -------------------------------- ### Configure Ably Broadcasting Driver Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/service-provider.md Set the default broadcasting connection to 'ably' and configure Ably-specific settings in `config/broadcasting.php`. Ensure your Ably API key is set in the environment. ```php return [ 'default' => env('BROADCAST_CONNECTION', 'ably'), 'connections' => [ 'ably' => [ 'driver' => 'ably', 'key' => env('ABLY_KEY'), 'sync_server_time' => env('ABLY_SYNC_SERVER_TIME', false), 'disable_public_channels' => env('ABLY_DISABLE_PUBLIC_CHANNELS', false), 'token_expiry' => env('ABLY_TOKEN_EXPIRY', 28800), ], ], ]; ``` -------------------------------- ### Configuration Array Type Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/types.md Configuration options passed from Laravel's config/broadcasting.php to initialize the broadcaster. ```php array { 'key' => string, // Ably API key (required) 'sync_server_time'? => bool, // Enable server time sync (default: false) 'disable_public_channels'? => bool, // Restrict public channels (default: false) 'token_expiry'? => int, // Token TTL in seconds (default: 28800) } ``` -------------------------------- ### Create Ably Echo Instance in bootstrap.js Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md Configure and create a new Echo instance using the Ably broadcaster in your application's bootstrap.js file. This sets up the connection to Ably services. ```javascript import Echo from '@ably/laravel-echo'; import * as Ably from 'ably'; window.Ably = Ably; window.Echo = new Echo({ broadcaster: 'ably', }); window.Echo.connector.ably.connection.on(stateChange => { if (stateChange.current === 'connected') { console.log('connected to ably server'); } }); ``` -------------------------------- ### Implement Broadcastable Event Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/service-provider.md Create an event class that implements the `ShouldBroadcast` interface to send data over Ably channels. Define the `broadcastOn` method to specify the channel and `broadcastWith` to provide the event payload. ```php use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\ShouldBroadcast; class MessageSent implements ShouldBroadcast { public function broadcastOn() { return new Channel('public.announcements'); } public function broadcastWith() { return ['message' => 'Hello World']; } } ``` -------------------------------- ### Configure Presence Channel with Custom Capabilities Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/endpoints.md Allows specifying custom Ably capabilities for a presence channel. This restricts the operations users can perform on the channel. ```php Broadcast::presence('notifications.{userId}', function ($user, $userId) { if ($user->id === $userId) { return [ 'id' => $user->id, 'name' => $user->name, 'ably-capability' => ['subscribe', 'presence'], ]; } return false; }); ``` -------------------------------- ### Environment Variable: Broadcast Driver Selection (Laravel 11+) Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Select the broadcast driver to use. Set to 'ably' to enable this broadcaster. ```env BROADCAST_CONNECTION=ably ``` -------------------------------- ### Utils Static Methods Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/MANIFEST.md Static utility methods for JWT parsing, generation, validation, socket ID decoding, and base64url encoding/decoding. ```APIDOC ## Utils Static Methods ### `parseJwt()` Parses a JSON Web Token (JWT). ### `generateJwt()` Generates a JSON Web Token (JWT). ### `isJwtValid()` Validates a JSON Web Token (JWT). ### `decodeSocketId()` Decodes a socket ID. ### `base64urlEncode()` Performs base64url encoding. ### `base64urlDecode()` Performs base64url decoding. ``` -------------------------------- ### Client-Side JavaScript Configuration with Laravel Echo Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Configure Ably Laravel Echo in your JavaScript to connect to the broadcasting service. Authentication tokens are automatically obtained from your /broadcasting/auth endpoint. ```javascript import Echo from '@ably/laravel-echo'; import * as Ably from 'ably'; window.Echo = new Echo({ broadcaster: 'ably', // Additional Ably-specific options here }); ``` -------------------------------- ### Configure Ably Key Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/errors.md Set the `ABLY_KEY` environment variable with your public and private keys separated by a colon. This is essential for all broadcast operations. ```env ABLY_KEY=public_key:private_key ``` -------------------------------- ### Environment Variable: Synchronize Server Time Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Set to 'true' to synchronize the server clock with Ably. Useful for servers with clock skew. Defaults to 'false'. ```env ABLY_SYNC_SERVER_TIME=false ``` -------------------------------- ### Configure Broadcasting Connections Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md For Laravel 8 or older, edit `config/broadcasting.php` and add the 'ably' section to the `connections` array. This defines the driver and key for Ably broadcasting. ```php 'ably' => [ 'driver' => 'ably', 'key' => env('ABLY_KEY') ], ``` -------------------------------- ### Configure Private/Presence Channel Capabilities Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md Define specific access control rights for private and presence channels using 'ably-capability' in routes/channels.php. This allows granular control over user permissions. ```php // file - routes/channels.php // User authentication is allowed for private/presence channel returning truthy values and denied for falsy values. // for private channel Broadcast::channel('channel1', function ($user) { return ['ably-capability' => ["subscribe", "history"]]; }); // for presence channel Broadcast::channel('channel2', function ($user) { return ['id' => $user->id, 'name' => $user->name, 'ably-capability' => ["subscribe", "presence"]]; }); ``` -------------------------------- ### Manually Register Service Provider Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md If manual registration is needed, add the `LaravelAblyBroadcasterServiceProvider` to the providers list in `config/app.php`. ```php // In config/app.php 'providers' => [ // ... Ably\LaravelBroadcaster\LaravelAblyBroadcasterServiceProvider::class, // ... ] ``` -------------------------------- ### Configure .env for Ably Broadcaster Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md Update your .env file to set the broadcast connection to 'ably' and provide your Ably API key. For Laravel versions 10 and older, use `BROADCAST_DRIVER` instead of `BROADCAST_CONNECTION`. Never expose your ABLY_KEY to client code. ```dotenv BROADCAST_CONNECTION=ably # For laravel <= 10, set `BROADCAST_DRIVER` instead ABLY_KEY=ROOT_API_KEY_COPIED_FROM_ABLY_WEB_DASHBOARD ``` -------------------------------- ### Environment Variable: Ably API Key Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Set your Ably API key in the .env file. Format is public:private. Never expose this in client-side code. ```env ABLY_KEY=your_api_key:your_private_key ``` -------------------------------- ### Configure Ably Broadcasting Driver Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Configure the Ably broadcasting driver in Laravel's `config/broadcasting.php` file. This includes setting the driver type and API key. ```php 'ably' => [ 'driver' => 'ably', 'key' => env('ABLY_KEY'), 'sync_server_time' => env('ABLY_SYNC_SERVER_TIME', false), 'disable_public_channels' => env('ABLY_DISABLE_PUBLIC_CHANNELS', false), 'token_expiry' => env('ABLY_TOKEN_EXPIRY', 28800), ], ``` -------------------------------- ### Configure Private Channel with Metadata Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/endpoints.md Allows returning custom metadata along with channel access. The metadata is sent in the 'info' field of the authorization response. ```php Broadcast::private('messages.{conversationId}', function ($user, $conversationId) { if ($user->conversations->contains($conversationId)) { return [ 'last_seen' => $user->lastSeenAt($conversationId), 'unread_count' => $user->unreadCount($conversationId), ]; } return false; }); ``` -------------------------------- ### Dispatch Event with ShouldBroadcast Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Implement the ShouldBroadcast interface in your event class to enable broadcasting. Define the broadcastOn and broadcastWith methods. ```php use Illuminate\Broadcasting\ShouldBroadcast; class MessageSent implements ShouldBroadcast { public function broadcastOn() { return new Channel('public.announcements'); } public function broadcastWith() { return ['message' => 'Hello World']; } } event(new MessageSent()); ``` -------------------------------- ### Channel Pattern Matching Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/types.md Channel names in capability definitions support wildcards for flexible access control. ```APIDOC ## Channel Patterns - `'public:*'`: Matches all public channels. - `'private:chat-*'`: Matches private channels starting with 'chat-'. - `'presence:user-*'`: Matches presence channels starting with 'user-'. - `'*:admin:*'`: Matches any channel with 'admin' in the path. ``` -------------------------------- ### Environment Variable: Broadcast Driver Selection (Laravel 10 and older) Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md For older Laravel versions, use BROADCAST_DRIVER to select the 'ably' broadcaster. ```env BROADCAST_DRIVER=ably ``` -------------------------------- ### Define Public Channel Access Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Configure public channels in `routes/channels.php`. No authentication is required, allowing anyone to subscribe. Be aware of the `ABLY_DISABLE_PUBLIC_CHANNELS` environment variable. ```php Broadcast::channel('public.announcements', function ($user) { return true; }); ``` -------------------------------- ### Implement Ably Authentication Endpoint Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Define a POST route for broadcasting authentication using the Ably driver. This is typically placed in routes/api.php or routes/channels.php. ```php // In routes/api.php or routes/channels.php Route::post('/broadcasting/auth', function (Request $request) { return app('Illuminate\Broadcasting\BroadcastManager') ->driver('ably') ->auth($request); }); ``` -------------------------------- ### Enable Server Time Synchronization Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Enable server time synchronization and set token expiry to 8 hours (28800 seconds) for servers with unreliable system clocks. ```env ABLY_SYNC_SERVER_TIME=true ABLY_TOKEN_EXPIRY=28800 ``` -------------------------------- ### Define Presence Channel Access Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Implement presence channels in `routes/channels.php` to track user presence. Requires user authentication and returns user metadata upon successful authorization. ```php Broadcast::presence('notifications.{userId}', function ($user, $userId) { if ($user->id === $userId) { return [ 'id' => $user->id, 'name' => $user->name, 'avatar' => $user->avatar_url, ]; } return false; }); ``` -------------------------------- ### Client-side Subscribe and Listen to Events Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Use the Ably Laravel Echo client library to subscribe to channels and listen for specific events. Ensure the broadcaster is set to 'ably'. ```javascript import Echo from '@ably/laravel-echo'; const echo = new Echo({ broadcaster: 'ably' }); echo.channel('public.announcements') .listen('MessageSent', (e) => { console.log(e.message); }); ``` -------------------------------- ### AblyBroadcaster Methods Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/MANIFEST.md Public methods available on the AblyBroadcaster class for channel authentication, event broadcasting, token generation, and response formatting. ```APIDOC ## AblyBroadcaster Methods ### `__construct()` Constructor for the AblyBroadcaster class. ### `auth()` Handles channel authentication requests. ### `broadcast()` Broadcasts events to channels. ### `getSignedToken()` Generates a signed token for channel access. ### `validAuthenticationResponse()` Formats a valid authentication response. ### `formatChannels()` Normalizes channel names. ### `normalizeChannelName()` Removes channel name prefixes. ### `isPrivateChannel()` Detects if a channel is private. ### `isPresenceChannel()` Detects if a channel is a presence channel. ### `isGuardedChannel()` Checks if a channel requires authentication. ### `getPublicToken()` Extracts the public token. ### `getPrivateToken()` Extracts the private token. ``` -------------------------------- ### Debug Missing HTTP Request Fields Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/errors.md In your authentication endpoint, use `dd()` to inspect the incoming request parameters for `channel_name`, `token`, and `socket_id` to debug missing required fields. ```php // In auth endpoint dd([ 'channel_name' => request('channel_name'), 'token' => request('token'), 'socket_id' => request('socket_id'), ]); ``` -------------------------------- ### Configure Presence Channel Access Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/endpoints.md Use for channels where users can join and leave, broadcasting their presence. Returns user metadata or false to deny access. ```php Broadcast::presence('online.{userId}', function ($user, $userId) { if ($user->id === $userId) { return [ 'id' => $user->id, 'name' => $user->name, 'status' => 'online', ]; } return false; }); ``` -------------------------------- ### auth() Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Authenticates an incoming request for a private or presence channel and returns a signed token. ```APIDOC ## auth() ### Description Authenticates an incoming request for a private or presence channel and returns a signed token. ### Method POST ### Endpoint `/broadcasting/auth` (Assumed, not explicitly stated in source) ### Parameters #### Request Body - **channel_name** (string) - Required - The target channel with prefix (e.g., `private:chat`, `presence:room`) - **token** (string, nullable) - Optional - An existing JWT token to reuse/upgrade - **socket_id** (string) - Required - Base64-URL-encoded JSON with `connectionKey` and `clientId` ### Response #### Success Response (200) - **token** (string) - Signed JWT token for the channel - **info** (array, optional) - User metadata if the channel callback returned array with additional data #### Error Response (403) - `Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException`: If user is not authenticated for a guarded channel, channel access is denied, or token is malformed ``` -------------------------------- ### Typical JWT Header Structure Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/utils.md Shows the common structure of a JWT header, including the token type, algorithm used, and key ID. ```php [ 'typ' => 'JWT', 'alg' => 'HS256', 'kid' => 'public-key-portion' // From API key before colon ] ``` -------------------------------- ### Define Library Version Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Defines the current version of the laravel-broadcaster library. ```php const LIB_VERSION = '1.0.8'; ``` -------------------------------- ### Mocking Broadcast Facade for Testing Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/service-provider.md Use this snippet to mock the broadcast method of the Broadcast facade when testing your application's event broadcasting. It allows you to assert that the broadcast method was called with specific arguments. ```php use Illuminate\Support\Facades\Broadcast; Broadcast::shouldReceive('broadcast') ->with(['channel1'], 'event.name', ['data' => 'value']) ->once(); // Trigger the event event(new MyEvent()); ``` -------------------------------- ### Create a Private Channel Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Define a private channel that requires user authentication based on specific conditions. Ensure the user is authorized to access the channel. ```php Broadcast::private('messages.{conversationId}', function ($user, $conversationId) { return $user->conversations()->where('id', $conversationId)->exists(); }); ``` -------------------------------- ### Generate Changelog with GitHub Changelog Generator Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md Automates the update of the CHANGELOG.md file. Requires a GitHub token with repository access. The output is written to a delta file for manual insertion. ```bash github_changelog_generator -u ably -p laravel-broadcaster --since-tag v1.0.6 --output delta.md --token $GITHUB_TOKEN_WITH_REPO_ACCESS ``` -------------------------------- ### Define Channel Authentication Logic Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Define how users are authenticated for private and presence channels. This callback determines if a user has access and can return custom metadata. ```php Broadcast::channel('private:chat', function ($user) { return $user->id === auth()->id(); }); Broadcast::channel('presence:notifications', function ($user) { return [ 'id' => $user->id, 'name' => $user->name, 'ably-capability' => ['subscribe', 'presence'] ]; }); ``` -------------------------------- ### Add User Metadata to Presence Channel Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Configure presence channel callbacks to return user metadata, such as ID, name, and status. This metadata is visible to other users subscribed to the presence channel. ```php Broadcast::presence('online.{office}', function ($user, $office) { if ($user->office === $office) { return [ 'id' => $user->id, 'name' => $user->name, 'status' => 'available', ]; } return false; }); ``` -------------------------------- ### Laravel Broadcaster Methods Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/types.md The base `Illuminate\Broadcasting\Broadcasters\Broadcaster` class provides the following methods, extended by `AblyBroadcaster`. ```APIDOC ## Public Methods ### `auth(Request $request): mixed` Authenticates a request. ### `validAuthenticationResponse(Request $request, mixed $result): mixed` Generates a valid authentication response. ### `broadcast(array $channels, string $event, array $payload = []): void` Broadcasts a message to specified channels. ### `verifyUserCanAccessChannel(Request $request, string $channel): mixed` Verifies if the user can access a given channel. ### `retrieveUser(Request $request, string $channel): ?User` Retrieves the user associated with a channel. ``` -------------------------------- ### Register Broadcast Service Provider Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md If using Laravel 10 or older, uncomment or set the BroadcastServiceProvider in your `config/app.php` file. ```php App\Providers\AuthServiceProvider::class, App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, ``` -------------------------------- ### Using Broadcast::fake() for Testing (Laravel 8+) Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/service-provider.md For Laravel 8 and later, utilize the `Broadcast::fake()` method to mock the broadcasting system. This allows you to trigger events and then assert that they were broadcasted with specific data. ```php Broadcast::fake(); event(new MyEvent()); Broadcast::assertBroadcasted('event.name', function ($payload) { return $payload['data'] === 'value'; }); ``` -------------------------------- ### Laravel Broadcaster Interface Methods Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/types.md These are the core methods defined by the base Laravel Broadcaster interface that concrete implementations like AblyBroadcaster must provide. ```php public function auth(Request $request): mixed; public function validAuthenticationResponse(Request $request, mixed $result): mixed; public function broadcast(array $channels, string $event, array $payload = []): void; public function verifyUserCanAccessChannel(Request $request, string $channel): mixed; public function retrieveUser(Request $request, string $channel): ?User; ``` -------------------------------- ### Typical JWT Payload Structure Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/utils.md Illustrates the standard structure of a JWT payload generated by `generateJwt()`, including issued at, expiration, client ID, and capability claims. ```php [ 'iat' => 1234567890, // Issued at 'exp' => 1234571490, // Expiration 'x-ably-clientId' => 'user-123', // User identifier 'x-ably-capability' => '{ "public:*" : ["subscribe", "history", "channel-metadata"], "private:chat": ["subscribe", "publish"] }' ] ``` -------------------------------- ### Environment Variable: Disable Public Channels Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/configuration.md Set to 'true' to restrict public channel access to metadata-only, preventing subscriptions and history requests. Defaults to 'false'. ```env ABLY_DISABLE_PUBLIC_CHANNELS=false ``` -------------------------------- ### HTTP Endpoint Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/MANIFEST.md Documentation for the HTTP endpoint used for broadcasting authentication. ```APIDOC ## HTTP Endpoint ### POST /broadcasting/auth Handles authentication requests for broadcasting channels. ``` -------------------------------- ### formatChannels() Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Normalizes channel names to Ably convention with prefixes. It ensures that channel names adhere to Ably's standard format for public, private, and presence channels. ```APIDOC ## formatChannels() ### Description Normalizes channel names to Ably convention with prefixes. It ensures that channel names adhere to Ably's standard format for public, private, and presence channels. ### Method ```php public function formatChannels(array $channels): array ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **$channels** (array) - Yes - Array of channel names in various formats ### Returns `array` - Array of channel names with normalized prefixes (`public:`, `private:`, `presence:`). ### Behavior - `private-*` → `private:*` - `presence-*` → `presence:*` - `*` (no prefix) → `public:*` ### Example ```php $formatted = $broadcaster->formatChannels([ 'private-chat', 'presence-room1', 'public_channel' ]); // Returns: ['private:chat', 'presence:room1', 'public:public_channel'] ``` ``` -------------------------------- ### Test Token Generation Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Generate and display a signed token for a specific channel and user. This is useful for testing authentication and authorization logic. ```php $broadcaster = app('Illuminate\Broadcasting\BroadcastManager')->driver('ably'); $token = $broadcaster->getSignedToken('private:test', null, 'user-1', ['*']); dd($token); ``` -------------------------------- ### Handling Access Denied Exceptions in Broadcast Auth Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/endpoints.md Implements a try-catch block to gracefully handle `AccessDeniedHttpException` during broadcast authentication. Logs the failure details and returns a 403 response to the client. ```php Route::post('/broadcasting/auth', function (Request $request) { try { return Broadcast::auth($request); } catch (\Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException $e) { Log::warning('Broadcasting auth failed', [ 'channel' => $request->channel_name, 'user' => auth()->id(), 'reason' => $e->getMessage(), ]); return response()->json( ['message' => 'Access denied'], 403 ); } }); ``` -------------------------------- ### Test Signed Token Generation and Validation Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/errors.md Generate a signed token for a test channel and validate its integrity using a secret key. This helps in verifying the token generation process. ```php $token = $broadcaster->getSignedToken('private:test', null, 'user-1', ['*']); $valid = Utils::isJwtValid($token, function() { return time(); }, 'secret-key'); if (!$valid) { echo "Token generation failed"; } ``` -------------------------------- ### Registering Ably Broadcaster Driver Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/service-provider.md This PHP code registers the 'ably' broadcaster driver with Laravel's broadcasting system. It sets Ably agent headers for SDK identification and creates a new AblyBroadcaster instance. ```php Broadcast::extend('ably', function ($broadcasting, $config) { // Set Ably agent headers for SDK identification AblyRest::setAblyAgentHeader('laravel-broadcaster', AblyBroadcaster::LIB_VERSION); $laravelVersion = Miscellaneous::getNumeric(app()->version()); AblyRest::setAblyAgentHeader('laravel', $laravelVersion); // Create and return broadcaster instance return new AblyBroadcaster(new AblyRest($config), $config); }); ``` -------------------------------- ### Define Public and Private Channels Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/README.md Define broadcast channels in routes/channels.php. Public channels require no authentication, while private channels enforce authorization. ```php Broadcast::channel('public.announcements', function ($user) { return true; }); Broadcast::private('chat.{roomId}', function ($user, $roomId) { return $user->can('access-room', $roomId); }); ``` -------------------------------- ### Normalize Channel Name Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Removes the Ably namespace prefix (e.g., 'private:', 'presence:', 'public:') from a given channel name. ```php $broadcaster->normalizeChannelName('private:chat-room'); // 'chat-room' $broadcaster->normalizeChannelName('presence:notifications'); // 'notifications' $broadcaster->normalizeChannelName('public:announcements'); // 'announcements' ``` -------------------------------- ### Format Channel Names Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/ably-broadcaster.md Normalizes an array of channel names to the Ably convention, ensuring correct prefixes like 'public:', 'private:', and 'presence:'. ```php $formatted = $broadcaster->formatChannels([ 'private-chat', 'presence-room1', 'public_channel' ]); // Returns: ['private:chat', 'presence:room1', 'public:public_channel'] ``` -------------------------------- ### base64urlDecode() Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/utils.md Decodes a base64url-encoded string. Returns an empty string if decoding fails. ```APIDOC ## base64urlDecode() ### Description Decodes a base64url-encoded string. ### Method ```php public static function base64urlDecode(string $data): string ``` ### Parameters #### Path Parameters - **$data** (string) - Required - Base64url-encoded string ### Returns `string` The decoded string, or an empty string if decoding fails. ### Example ```php $encoded = 'eyJrZXkiOiJ2YWx1ZSJ9'; $decoded = Utils::base64urlDecode($encoded); echo $decoded; // '{"key":"value"}' ``` ``` -------------------------------- ### base64urlEncode() Source: https://github.com/ably/laravel-broadcaster/blob/main/_autodocs/api-reference/utils.md Encodes a string using base64url (RFC 4648 §5). It replaces '+' with '-', '/' with '_', and removes trailing '=' padding. ```APIDOC ## base64urlEncode() ### Description Encodes a string using base64url (RFC 4648 §5). ### Method ```php public static function base64urlEncode(string $str): string ``` ### Parameters #### Path Parameters - **$str** (string) - Required - String to encode ### Returns `string` Base64url-encoded string with: - `+` replaced with `-` - `/` replaced with `_` - Trailing `=` padding removed ### Example ```php $json = '{"key":"value"}'; $encoded = Utils::base64urlEncode($json); // Returns: 'eyJrZXkiOiJ2YWx1ZSJ9' ``` ``` -------------------------------- ### Update Token Expiry Configuration Source: https://github.com/ably/laravel-broadcaster/blob/main/README.md Set the 'ABLY_TOKEN_EXPIRY' environment variable to customize the token expiry duration and update the 'config/broadcasting.php' file accordingly. The default is 8 hours. ```dotenv ABLY_TOKEN_EXPIRY=43200 ``` ```php 'ably' => [ 'driver' => 'ably', 'key' => env('ABLY_KEY'), 'token_expiry' => env('ABLY_TOKEN_EXPIRY', 28800) ], ```