@webventures/comms
v2.0.5
Published
WebVentures Comms SDK - Unified communication SDK for TypeScript & JavaScript. Send emails, SMS, push notifications, and more with a single, type-safe API. First-class support for Next.js 16+, React 19, React Native, and Expo.
Maintainers
Keywords
Readme
📨 WebVentures Comms SDK
Unified Communication SDK for Modern Applications
Send emails, SMS, push notifications, and more with a single, type-safe API
Features • Installation • Quick Start • Documentation • Examples
🎯 Overview
WebVentures Comms SDK is a production-ready, type-safe communication library that provides a unified interface for sending transactional notifications across multiple channels and providers. Built entirely in TypeScript with first-class support for modern frameworks.
Why WebVentures Comms SDK?
// One SDK, multiple channels, full type safety
import CommsSdk from '@webventures/comms'
const comms = new CommsSdk({
channels: {
email: { providers: [{ type: 'sendgrid', apiKey: process.env.SENDGRID_KEY }] },
sms: { providers: [{ type: 'twilio', accountSid: '...', authToken: '...' }] },
push: { providers: [{ type: 'fcm', id: 'your-fcm-key' }] },
},
})
// Send notifications with intelligent fallback
await comms.send({
email: { to: '[email protected]', subject: 'Welcome!', html: '<h1>Hello!</h1>' },
sms: { to: '+1234567890', text: 'Welcome to WebVentures!' },
push: { registrationToken: 'device-token', title: 'Welcome!', body: 'Get started' },
})Key Benefits
| Feature | Description | | ------------------------- | --------------------------------------------------------------- | | 🎯 Unified API | Single interface for all notification channels | | 🛡️ Type-Safe | Full TypeScript support with comprehensive IntelliSense | | ⚡ Multi-Provider | Built-in failover & load balancing across 40+ providers | | 🚀 Framework-First | Optimized for Next.js 16+, React 19, React Native, Expo | | 🔧 Production-Ready | Battle-tested error handling, logging, and provider abstraction | | 🎨 Developer-Friendly | Local testing tools, extensive docs, and real-world examples | | 📦 Tree-Shakeable | Modular exports for optimal bundle size | | 🔌 Extensible | Custom providers and strategies support |
✨ Features
📬 Supported Channels
SMTP, SendGrid, AWS SES, Mailgun, Mandrill, SparkPost, Sendmail
💬 SMS
Twilio, Vonage, Plivo, Infobip, OVH, Callr, Clickatell, 46elks, Seven
📱 Push
APNs (iOS), FCM (Android/iOS), WNS (Windows), ADM (Amazon)
🔊 Voice
Twilio Voice with TwiML support
🌐 Webpush
Web Push with VAPID authentication
💼 Slack
Webhook integration with rich formatting
Infobip WhatsApp Business API
📱 Telegram
Telegram Bot API with rich formatting
🎯 Custom
Build your own providers
More channels coming soon
🏗️ Framework Support
- Next.js 16+ - Server Components, Server Actions, API Routes, Edge Runtime
- React 19 - Latest React with full concurrent features
- React Native - Native mobile app integration
- Expo - Managed React Native workflow with push notifications
- Node.js 18+ - Standard Node.js applications, CLI tools, serverless
🔄 Multi-Provider Strategies
| Strategy | Description | Use Case | | --------------- | -------------------------------------- | -------------------------------- | | Fallback | Automatic failover to backup providers | High availability, 99.9% uptime | | Round-robin | Load balancing across providers | Cost optimization, rate limiting | | No-fallback | Single provider with immediate errors | Testing, debugging | | Weighted | Probability-based provider selection | Gradual rollouts, A/B testing | | Custom | Define your own selection logic | Geographic routing, custom logic |
🚀 Installation
# Using npm
npm install @webventures/comms
# Using yarn
yarn add @webventures/comms
# Using pnpm
pnpm add @webventures/commsRequirements
- Node.js: 18.0.0 or higher
- TypeScript: 5.0.0 or higher (optional)
Optional Development Tools
For local testing:
npm install --save-dev notification-catcher⚡ Quick Start
1. Basic Email Sending
import CommsSdk from '@webventures/comms'
const comms = new CommsSdk({
channels: {
email: {
providers: [
{
type: 'sendgrid',
apiKey: process.env.SENDGRID_API_KEY,
},
],
},
},
})
const result = await comms.send({
email: {
from: '[email protected]',
to: '[email protected]',
subject: 'Welcome to WebVentures!',
html: '<h1>Hello!</h1><p>Thanks for signing up.</p>',
},
})
console.log(result)
// { status: 'success', channels: { email: { id: 'msg-123', providerId: 'sendgrid' } } }2. Multi-Channel with High Availability
const comms = new CommsSdk({
channels: {
email: {
multiProviderStrategy: 'fallback', // Automatic failover
providers: [
{ type: 'sendgrid', apiKey: process.env.SENDGRID_KEY }, // Primary
{ type: 'ses', region: 'us-east-1', accessKeyId: '...', secretAccessKey: '...' }, // Backup
{ type: 'mailgun', apiKey: '...', domainName: 'mg.example.com' }, // Fallback
],
},
sms: {
providers: [
{
type: 'twilio',
accountSid: process.env.TWILIO_SID,
authToken: process.env.TWILIO_TOKEN,
},
],
},
},
})
// If SendGrid fails, automatically tries SES, then Mailgun
await comms.send({
email: {
from: '[email protected]',
to: '[email protected]',
subject: 'Critical Alert',
text: 'Your account requires immediate attention.',
},
sms: {
from: '+1234567890',
to: '+0987654321',
text: 'Critical alert - check your email',
},
})3. Next.js 16+ Server Actions
// app/actions/notifications.ts
'use server'
import { createNextJSComms } from '@webventures/comms/adapters'
export async function sendWelcomeEmail(email: string) {
const comms = createNextJSComms({
channels: {
email: {
providers: [{ type: 'sendgrid', apiKey: process.env.SENDGRID_API_KEY! }],
},
},
})
return await comms.send({
email: {
from: '[email protected]',
to: email,
subject: 'Welcome!',
html: '<h1>Thanks for joining!</h1>',
},
})
}// app/signup/page.tsx
import { sendWelcomeEmail } from '../actions/notifications'
export default function SignupPage() {
return (
<form action={async (formData) => {
'use server'
const email = formData.get('email') as string
await sendWelcomeEmail(email)
}}>
<input type="email" name="email" required />
<button type="submit">Sign Up</button>
</form>
)
}4. React Native Push Notifications
import { createReactNativeComms } from '@webventures/comms/adapters'
const comms = createReactNativeComms({
channels: {
push: {
providers: [
{
type: 'fcm',
id: process.env.FCM_SERVER_KEY,
},
],
},
},
})
await comms.send({
push: {
registrationToken: deviceToken,
title: 'New Message',
body: 'You have a new message from John',
badge: 1,
sound: 'default',
custom: {
messageId: '123',
type: 'chat',
},
},
})🎨 Framework Integration
Next.js 16+ (App Router)
// lib/comms.ts - Reusable SDK instance
import { withComms } from '@webventures/comms/adapters'
export const sendNotification = withComms(
async (comms, options) => {
return await comms.send(options)
},
{
channels: {
email: {
providers: [{ type: 'sendgrid', apiKey: process.env.SENDGRID_API_KEY! }],
},
},
}
)// app/api/notify/route.ts - API Route
import { sendNotification } from '@/lib/comms'
export async function POST(request: Request) {
const { email, message } = await request.json()
const result = await sendNotification({
email: {
from: '[email protected]',
to: email,
subject: 'Notification',
text: message,
},
})
return Response.json(result)
}Expo with Push Notifications
import { createExpoComms } from '@webventures/comms/adapters'
import * as Notifications from 'expo-notifications'
const comms = createExpoComms({
channels: {
push: {
providers: [
{
type: 'fcm',
id: process.env.EXPO_FCM_KEY,
},
],
},
},
})
// Get push token
const token = (await Notifications.getExpoPushTokenAsync()).data
// Send notification
await comms.send({
push: {
registrationToken: token,
title: 'Expo Notification',
body: 'Hello from WebVentures Comms!',
},
})Node.js Express API
import express from 'express'
import { createNodeComms } from '@webventures/comms/adapters'
const app = express()
const comms = createNodeComms({
channels: {
email: { providers: [{ type: 'smtp', host: 'smtp.gmail.com', port: 587 }] },
},
})
app.post('/api/send-email', async (req, res) => {
const result = await comms.send({
email: {
from: '[email protected]',
to: req.body.email,
subject: 'Hello',
text: 'Your message here',
},
})
res.json(result)
})
app.listen(3000)See complete framework guides →
📘 Documentation
Complete Guides
- 📖 Complete Documentation - Full SDK documentation
- 📚 API Reference - Complete API documentation with types
- 🔧 Framework Integration - Next.js, React, React Native, Expo
- ⚙️ Provider Configuration - Detailed setup for 40+ providers
- 💡 Examples - Comprehensive code examples
- 🏗️ Architecture - Technical architecture and patterns
- 🔄 Migration Guide - Upgrading from other SDKs
Quick Links
| Topic | Link | | ------------------------- | -------------------------------------------------------------------------------------- | | Error Handling | docs/README.md#error-handling | | Multi-Provider Strategies | docs/README.md#multi-provider-strategies | | TypeScript Types | docs/API.md#types | | Custom Providers | docs/PROVIDERS.md#custom-providers | | Production Patterns | docs/EXAMPLES.md#production | | Testing Guide | docs/EXAMPLES.md#testing |
💡 Examples
Email with Attachments
await comms.send({
email: {
from: '[email protected]',
to: '[email protected]',
subject: 'Invoice #12345',
html: '<h1>Your Invoice</h1><p>Please find attached.</p>',
attachments: [
{
filename: 'invoice.pdf',
content: pdfBuffer,
contentType: 'application/pdf',
},
],
cc: ['[email protected]'],
bcc: ['[email protected]'],
},
})SMS with Unicode
await comms.send({
sms: {
from: '+1234567890',
to: '+0987654321',
text: '您的验证码是: 123456',
type: 'unicode',
},
})Push with Rich Notifications
await comms.send({
push: {
registrationToken: 'device-token',
title: 'New Message from John',
body: 'Hey, are you coming to the meeting?',
icon: 'https://example.com/avatar.png',
image: 'https://example.com/preview.jpg',
badge: 5,
sound: 'default',
priority: 'high',
clickAction: 'OPEN_CHAT',
custom: {
chatId: '123',
senderId: '456',
type: 'chat_message',
},
},
})Slack Rich Messages
await comms.send({
slack: {
text: 'Production deployment completed! 🎉',
attachments: [
{
color: 'good',
title: 'v2.0.2 Deployment',
text: 'All systems operational',
fields: [
{ title: 'Environment', value: 'Production', short: true },
{ title: 'Version', value: 'v2.0.2', short: true },
{ title: 'Deploy Time', value: '2 minutes', short: true },
{ title: 'Status', value: '✅ Success', short: true },
],
footer: 'WebVentures Deploy Bot',
ts: Math.floor(Date.now() / 1000),
},
],
},
})Telegram Notifications
await comms.send({
telegram: {
chatId: '-1001234567890',
text: `
<b>🚀 Deployment Complete</b>
<b>Environment:</b> Production
<b>Version:</b> <code>v2.0.2</code>
<b>Status:</b> ✅ Success
<i>All systems operational</i>
<a href="https://status.example.com">View Status</a>
`.trim(),
parseMode: 'HTML',
},
})Custom Strategy (Geographic Routing)
import type { StrategyFunction } from '@webventures/comms'
const geographicRouting: StrategyFunction = (providers, notification) => {
const userCountry = notification.metadata?.country
// Route EU users to EU provider, US users to US provider
if (userCountry === 'DE' || userCountry === 'FR') {
return providers.find((p) => p.id === 'eu-provider')
}
if (userCountry === 'US') {
return providers.find((p) => p.id === 'us-provider')
}
return providers[0] // Default
}
const comms = new CommsSdk({
channels: {
email: {
providers: [
{ type: 'ses', id: 'us-provider', region: 'us-east-1' },
{ type: 'ses', id: 'eu-provider', region: 'eu-west-1' },
],
customStrategy: geographicRouting,
},
},
})🛡️ Error Handling
Response Status Checking
const result = await comms.send({
/* ... */
})
if (result.status === 'success') {
console.log('✓ Notification sent:', result.channels.email?.id)
} else {
console.error('✗ Notification failed:', result.errors)
result.errors?.forEach((error) => {
console.error(`${error.channel}: ${error.message}`)
})
}Using Type Guards
import { isSuccessResponse, isErrorResponse, getErrors, isCommsError } from '@webventures/comms'
const result = await comms.send({
/* ... */
})
if (isSuccessResponse(result)) {
console.log('Success!', result.channels)
}
if (isErrorResponse(result)) {
const errors = getErrors(result)
errors.forEach((err) => console.error(err.message))
}Try-Catch Pattern
import { CommsError, ProviderError } from '@webventures/comms'
try {
await comms.send({
/* ... */
})
} catch (error) {
if (error instanceof ProviderError) {
console.error(`Provider ${error.providerId} failed on ${error.channel}:`, error.message)
// Implement fallback logic or alerting
} else if (error instanceof CommsError) {
console.error('SDK Error:', error.code, error.message)
} else {
console.error('Unexpected error:', error)
}
}🧪 Local Development & Testing
Notification Catcher
For local development, use Notification Catcher to intercept all notifications in a web UI:
# Install
npm install --save-dev notification-catcher
# Start catcher (runs on port 1080)
npx notification-catcherConfigure SDK:
const comms = new CommsSdk({
useNotificationCatcher: true, // Sends all to http://localhost:1080
channels: {
email: { providers: [{ type: 'logger' }] }, // Optional: also log to console
},
})
await comms.send({
email: {
from: '[email protected]',
to: '[email protected]',
subject: 'Test Email',
html: '<h1>Testing</h1>',
},
})Open http://localhost:1080 to view all sent notifications with full headers, content, and metadata.
Environment-Based Configuration
const isDev = process.env.NODE_ENV === 'development'
const isProd = process.env.NODE_ENV === 'production'
const comms = new CommsSdk({
useNotificationCatcher: isDev,
channels: {
email: {
providers: isProd
? [
{ type: 'sendgrid', apiKey: process.env.SENDGRID_API_KEY! },
{ type: 'ses', region: 'us-east-1', accessKeyId: '...', secretAccessKey: '...' },
]
: [{ type: 'logger' }],
},
},
})📦 TypeScript Support
WebVentures Comms SDK is built with TypeScript and provides comprehensive type definitions:
Import Types
import CommsSdk, {
// Configuration Types
CommsSdkConfig,
ChannelConfig,
ProviderConfig,
// Request Types
NotificationRequest,
EmailRequest,
SmsRequest,
PushRequest,
VoiceRequest,
WebpushRequest,
SlackRequest,
WhatsappRequest,
TelegramRequest,
// Response Types
NotificationStatus,
SuccessNotificationStatus,
ErrorNotificationStatus,
ChannelStatus,
// Error Types
CommsError,
ProviderError,
ConfigurationError,
ValidationError,
NetworkError,
// Provider Types
EmailProvider,
SmsProvider,
PushProvider,
// Strategy Types
StrategyFunction,
MultiProviderStrategyType,
// Utility Functions
isSuccessResponse,
isErrorResponse,
getErrors,
isCommsError,
} from '@webventures/comms'Type-Safe Configuration
const config: CommsSdkConfig = {
channels: {
email: {
multiProviderStrategy: 'fallback',
providers: [
{
type: 'sendgrid',
apiKey: 'your-key',
}, // TypeScript validates provider config
],
},
},
}
const comms = new CommsSdk(config)Type-Safe Requests
const emailRequest: EmailRequest = {
from: '[email protected]',
to: '[email protected]',
subject: 'Hello',
html: '<h1>World</h1>',
attachments: [
{
filename: 'doc.pdf',
content: buffer,
contentType: 'application/pdf',
},
],
}
const request: NotificationRequest = {
email: emailRequest,
// TypeScript ensures correct structure
}
const result: NotificationStatus = await comms.send(request)
// TypeScript knows result.channels, result.status, result.errors⚙️ Supported Providers
Email Providers (7)
| Provider | Type | Features |
| ------------- | ----------- | ---------------------------------- |
| SMTP | smtp | Any SMTP server, OAuth 2.0 support |
| SendGrid | sendgrid | API v3, templates, tracking |
| AWS SES | ses | High volume, cost-effective |
| Mailgun | mailgun | EU/US regions, validation API |
| Mandrill | mandrill | MailChimp integration, templates |
| SparkPost | sparkpost | Analytics, A/B testing |
| Sendmail | sendmail | Local sendmail binary |
SMS Providers (9)
| Provider | Type | Countries |
| ------------------ | ------------ | --------------------- |
| Twilio | twilio | 180+ countries |
| Vonage (Nexmo) | nexmo | Global coverage |
| Plivo | plivo | 190+ countries |
| Infobip | infobip | Global, enterprise |
| OVH | ovh | Europe focus |
| Callr | callr | Europe, North America |
| Clickatell | clickatell | Global coverage |
| 46elks | 46elks | Sweden focus |
| Seven | seven | Europe, APAC |
Push Notification Providers (4)
| Provider | Type | Platform |
| -------- | ----- | ------------------------------ |
| APNs | apn | iOS (Token & Certificate auth) |
| FCM | fcm | Android, iOS, Web |
| WNS | wns | Windows |
| ADM | adm | Amazon Fire devices |
Other Providers
- Voice: Twilio (TwiML support)
- Webpush: Web Push with VAPID
- Slack: Webhook with rich formatting
- WhatsApp: Infobip Business API
- Telegram: Telegram Bot API with HTML/Markdown formatting
See provider configuration guide →
🏗️ Architecture
WebVentures Comms SDK follows enterprise-grade design patterns:
- Factory Pattern - Provider and strategy instantiation
- Strategy Pattern - Multi-provider selection algorithms
- Facade Pattern - Simplified API over complex provider logic
- Registry Pattern - Provider instance management
- Adapter Pattern - Framework-specific optimizations
See architecture documentation →
🚀 Performance & Best Practices
✅ Reuse SDK Instances
// ✓ Good - Reuse instance (connection pooling, caching)
const comms = new CommsSdk({
/* config */
})
export async function sendEmail(to: string, subject: string) {
return await comms.send({ email: { from: '[email protected]', to, subject, text: '...' } })
}
// ✗ Bad - Creating new instance per call (expensive)
export async function sendEmail(to: string, subject: string) {
const comms = new CommsSdk({
/* config */
}) // Don't do this!
return await comms.send({
/* ... */
})
}✅ Use Environment Variables
import { createNodeCommsFromEnv } from '@webventures/comms/adapters'
// Reads COMMS_EMAIL_PROVIDER, COMMS_SMS_PROVIDER, etc.
const comms = createNodeCommsFromEnv()✅ Configure Logging
import winston from 'winston'
const comms = new CommsSdk({
/* ... */
})
// Mute logs in production
if (process.env.NODE_ENV === 'production') {
comms.logger.mute()
}
// Custom logging
comms.logger.configure([
new winston.transports.File({ filename: 'notifications.log', level: 'error' }),
new winston.transports.Console({ level: 'info' }),
])✅ Handle Errors Gracefully
const result = await comms.send({
/* ... */
})
if (result.status === 'error') {
// Log for monitoring
logger.error('Notification failed', { errors: result.errors })
// Alert dev team for critical notifications
if (isCritical) {
await alertOps(result.errors)
}
// Retry or queue for later
await retryQueue.add(notification, { attempts: 3 })
}🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
# Clone repository
git clone https://github.com/CryptVenture/Comms.git
cd comms
# Install dependencies
pnpm install
# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Type check
pnpm type-check
# Build
pnpm build
# Lint & format
pnpm lint:fixRunning Tests
# All tests
pnpm test
# Coverage report
pnpm test:coverage
# UI mode
pnpm test:ui📊 Stats
- 556 Tests - 100% passing
- 40+ Providers - Production-ready integrations
- 8 Channels - Email, SMS, Push, Voice, Webpush, Slack, WhatsApp, Telegram
- TypeScript 100% - Full type safety
- Node.js 18+ - Modern JavaScript features
- Production Ready - Battle-tested error handling
📄 License
MIT License - see LICENSE file for details.
🆘 Support & Community
- GitHub Issues - Report bugs and request features
- GitHub Discussions - Ask questions and share ideas
- npm Package - View on npm registry
- Documentation - Complete guides and API reference
🔗 Related Projects
- Notification Catcher - Local notification testing tool
- WebVentures Platform - Complete communication platform (coming soon)
Built with ❤️ by the WebVentures team
