@scwar/nestjs-pusher
v1.0.0
Published
A comprehensive NestJS module for integrating with Pusher Channels REST API
Maintainers
Readme
@scwar/nestjs-pusher
A comprehensive NestJS module for integrating with the Pusher Channels REST API. This package provides a complete wrapper around all Pusher API endpoints with robust error handling, retries, and TypeScript support.
Features
- 🚀 Complete API Coverage: All Pusher Channels REST API endpoints implemented
- 🔄 Automatic Retries: Built-in retry mechanism with exponential backoff
- 🛡️ Robust Error Handling: Comprehensive error handling with detailed error messages
- 📝 TypeScript Support: Full type definitions for all API requests and responses
- 🔐 End-to-End Encryption: Support for encrypted channels (requires
tweetnaclandtweetnacl-util) - 🧪 Comprehensive Testing: Extensive test coverage for all endpoints
- ⚡ Performance: Uses native fetch API for optimal performance
- 🔧 Configurable: Easy configuration through NestJS module options
Installation
npm install @scwar/nestjs-pusherFor end-to-end encryption support (optional):
npm install tweetnacl tweetnacl-utilQuick Start
1. Import the module
import { PusherModule } from '@scwar/nestjs-pusher';
@Module({
imports: [
PusherModule.forRoot({
appId: 'your-app-id',
key: 'your-pusher-key',
secret: 'your-pusher-secret',
cluster: 'us2', // or your cluster
timeout: 30000,
retries: 3,
}),
],
})
export class AppModule {}2. Inject and use the service
import { PusherService } from '@scwar/nestjs-pusher';
@Injectable()
export class NotificationService {
constructor(private readonly pusherService: PusherService) {}
async sendNotification(channel: string, event: string, data: any) {
return this.pusherService.event.trigger(channel, event, data);
}
}Configuration Options
interface PusherModuleOptions {
appId: string;
key: string;
secret: string;
cluster?: string; // Default: 'us2'
encryptionMasterKeyBase64?: string; // Required for private-encrypted-* channels
baseUrl?: string; // Default: 'https://api.pusherapp.com'
timeout?: number; // Default: 30000
retries?: number; // Default: 3
retryDelay?: number; // Default: 1000
maxRetryDelay?: number; // Default: 10000
useTLS?: boolean; // Default: true
}Available Services
Event Service
Trigger events on channels:
// Single channel
await pusherService.event.trigger('my-channel', 'my-event', { message: 'Hello' });
// Multiple channels
await pusherService.event.trigger(
['channel-1', 'channel-2'],
'my-event',
{ message: 'Hello' }
);
// With socket ID exclusion
await pusherService.event.trigger(
'my-channel',
'my-event',
{ message: 'Hello' },
'socket-id-to-exclude'
);
// Batch events
await pusherService.event.triggerBatch({
batch: [
{
channel: 'channel-1',
name: 'event-1',
data: { message: 'Hello' },
},
{
channel: 'channel-2',
name: 'event-2',
data: { message: 'World' },
},
],
});Channel Service
Query channel information:
// List all channels
const channels = await pusherService.channel.getChannels({
filter_by_prefix: 'presence-',
attributes: 'user_count,subscription_count',
});
// Get channel info
const channelInfo = await pusherService.channel.getChannel('my-channel', {
attributes: 'user_count',
});
// Get users in presence channel
const users = await pusherService.channel.getChannelUsers('presence-channel');Auth Service
Authenticate users and authorize channels:
// Authenticate user
const userAuth = pusherService.auth.authenticateUser('socket-id', {
id: 'user-123',
name: 'John Doe',
image: 'https://example.com/avatar.jpg',
});
// Authorize private channel
const channelAuth = pusherService.auth.authorizeChannel('socket-id', 'private-channel');
// Authorize presence channel
const presenceAuth = pusherService.auth.authorizeChannel(
'socket-id',
'presence-channel',
{
user_id: 'user-123',
user_info: {
name: 'John Doe',
},
}
);
// Terminate user connections
await pusherService.auth.terminateUserConnections('user-123');Webhook Service
Validate and parse webhooks:
// Validate webhook
const isValid = pusherService.webhook.isValid(webhookRequest);
// Get webhook data
const webhookData = pusherService.webhook.getData(webhookRequest);
// Get events from webhook
const events = pusherService.webhook.getEvents(webhookRequest);
// Get webhook timestamp
const timestamp = pusherService.webhook.getTime(webhookRequest);End-to-End Encryption
To use end-to-end encryption for private-encrypted-* channels:
- Install required dependencies:
npm install tweetnacl tweetnacl-util- Configure the encryption master key:
PusherModule.forRoot({
appId: 'your-app-id',
key: 'your-key',
secret: 'your-secret',
encryptionMasterKeyBase64: 'your-base64-encoded-master-key',
})- Trigger events on encrypted channels:
// The data will be automatically encrypted
await pusherService.event.trigger(
'private-encrypted-channel',
'my-event',
{ message: 'This will be encrypted' }
);Error Handling
The package provides comprehensive error handling:
try {
const result = await pusherService.event.trigger('channel', 'event', data);
} catch (error) {
if (error instanceof PusherError) {
console.log('Pusher Error:', error.message);
console.log('Error Code:', error.code);
console.log('HTTP Status:', error.status);
console.log('Error Data:', error.data);
}
}Retry Mechanism
Automatic retries with exponential backoff for failed requests:
// Configure retries in module options
PusherModule.forRoot({
appId: 'your-app-id',
key: 'your-key',
secret: 'your-secret',
retries: 3, // Number of retry attempts
retryDelay: 1000, // Initial delay in ms
maxRetryDelay: 10000, // Maximum delay in ms
})REST API Signatures
Generate signed query strings for manual API requests:
const queryString = pusherService.createSignedQueryString({
method: 'GET',
path: '/apps/123/channels',
params: {
filter_by_prefix: 'presence-',
},
});Testing
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:covVersion Management & Releases
This package includes an automated version bumping system that follows semantic versioning and conventional commits.
Automatic Version Bumping
# Automatically determine and bump version
npm run version:auto
# Manual version bumps
npm run version:patch # 1.0.0 → 1.0.1
npm run version:minor # 1.0.0 → 1.1.0
npm run version:major # 1.0.0 → 2.0.0Conventional Commits
All commits must follow the Conventional Commits specification:
# Feature commits (minor version bump)
git commit -m "feat: add new event type"
# Bug fix commits (patch version bump)
git commit -m "fix: resolve authentication issue"
# Breaking change commits (major version bump)
git commit -m "feat!: breaking change in API"Release Process
# Complete release process with automatic version bump
npm run release:auto
# Manual release with specific version bump
npm run release:patch
npm run release:minor
npm run release:majorContributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes using conventional commit format
- Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Important: All commits must follow the conventional commit format to ensure proper version bumping.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For support, please open an issue on GitHub or contact the maintainers.
Changelog
See CHANGELOG.md for a list of changes and version history.
