@kapsula-chat/capacitor-push-calls
v1.0.3
Published
Capacitor plugin with push routing (message/call), CallKit (iOS), and ConnectionService (Android)
Maintainers
Readme
Capacitor Push Calls Plugin
@kapsula-chat/capacitor-push-calls is a unified Capacitor plugin for:
- regular push notifications (API compatible in shape with
@capacitor/push-notifications) - VoIP/telephony call handling
Platform behavior:
- iOS: regular push via APNS registration + VoIP via PushKit + CallKit UI
- Android: single FCM router service inside this plugin (
type=message|money|system|call) + ConnectionService UI for calls
Install
npm install @kapsula-chat/capacitor-push-calls
npx cap syncAdd Plugin To App (iOS + Android)
- Install and sync:
npm install @kapsula-chat/capacitor-push-calls
npx cap sync- Open native projects at least once so Capacitor updates plugin wiring:
npx cap open ios
npx cap open android- iOS:
- Ensure VoIP background mode is enabled in
Info.plist(see iOS section below). - If you use FCM for regular pushes on iOS, keep your APNs + Firebase setup configured in the app.
- Android:
- Ensure your app is configured for Firebase Messaging (
google-services.json, Firebase project). - Register the phone account once on app startup (recommended):
import com.capacitor.voipcalls.VoipConnectionService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
VoipConnectionService.registerPhoneAccount(this)
}Import
import { CapacitorPushCalls } from '@kapsula-chat/capacitor-push-calls';Push API (regular notifications)
Register / permissions
const permissions = await CapacitorPushCalls.checkPermissions();
if (permissions.receive !== 'granted') {
await CapacitorPushCalls.requestPermissions();
}
await CapacitorPushCalls.register();
CapacitorPushCalls.addListener('registration', token => {
console.log('push token:', token.value);
// Send token to backend and bind with authenticated user/device
});
CapacitorPushCalls.addListener('registrationError', error => {
console.error('registration error:', error.error);
});Receive and tap events
CapacitorPushCalls.addListener('pushNotificationReceived', notification => {
console.log('push received:', notification);
});
CapacitorPushCalls.addListener('pushNotificationActionPerformed', action => {
console.log('push action:', action.actionId, action.notification);
});Delivered notifications and channels
const delivered = await CapacitorPushCalls.getDeliveredNotifications();
await CapacitorPushCalls.removeAllDeliveredNotifications();
await CapacitorPushCalls.createChannel({
id: 'messages',
name: 'Messages',
importance: 4,
});
const channels = await CapacitorPushCalls.listChannels();
await CapacitorPushCalls.deleteChannel({ id: 'messages' });Note: channel APIs are Android-only (iOS returns no-op / empty list).
Badge count
const current = await CapacitorPushCalls.getBadgeCount();
await CapacitorPushCalls.setBadgeCount({ count: current.count + 1 });
await CapacitorPushCalls.clearBadgeCount();Android Device Registration
Recommended bootstrap flow on Android:
const permissions = await CapacitorPushCalls.checkPermissions();
if (permissions.receive !== 'granted') {
await CapacitorPushCalls.requestPermissions();
}
await CapacitorPushCalls.register();
CapacitorPushCalls.addListener('registration', async ({ value }) => {
// Persist FCM token on backend for this device/session
await api.registerPushDevice({ token: value, platform: 'android' });
});Use the same registration flow on iOS for regular push token registration.
VoIP / calls API
iOS VoIP registration
await CapacitorPushCalls.registerVoipNotifications();
CapacitorPushCalls.addListener('voipPushToken', ({ token }) => {
console.log('voip token:', token);
});Start / control calls
const { callId } = await CapacitorPushCalls.startCall({
handle: '+1234567890',
displayName: 'John Doe',
handleType: 'phone',
video: false,
});
await CapacitorPushCalls.setMuted({ muted: true });
await CapacitorPushCalls.setAudioRoute({ route: 'speaker' });
await CapacitorPushCalls.setCallOnHold({ callId, onHold: true });
await CapacitorPushCalls.endCall({ callId });Call events
CapacitorPushCalls.addListener('incomingCall', call => {});
CapacitorPushCalls.addListener('callStarted', call => {});
CapacitorPushCalls.addListener('callAnswered', call => {});
CapacitorPushCalls.addListener('callEnded', call => {});
CapacitorPushCalls.addListener('callRejected', call => {});
CapacitorPushCalls.addListener('callHeld', call => {});Android FCM routing contract
This plugin owns one FirebaseMessagingService and routes by data.type.
type=call-> reported as incoming call to system UItype=message|money|system-> emitted aspushNotificationReceived- anything else (or missing
type) -> emitted aspushNotificationReceived
Example FCM message payloads:
Message push
{
"data": {
"type": "message",
"messageId": "msg-123",
"chatId": "room-7"
},
"notification": {
"title": "New message",
"body": "Hello"
}
}Money push
{
"data": {
"type": "money",
"transactionId": "txn-99",
"amount": "250.00",
"currency": "USD"
},
"notification": {
"title": "Payment received",
"body": "You received $250.00"
}
}System push
{
"data": {
"type": "system",
"code": "maintenance",
"severity": "info"
},
"notification": {
"title": "System notice",
"body": "Scheduled maintenance at 02:00 UTC"
}
}Call push
{
"data": {
"type": "call",
"callId": "call-123",
"handle": "+1234567890",
"displayName": "John Doe",
"handleType": "phone",
"video": "false"
}
}Foreground Service (Android)
The plugin currently routes FCM and triggers ConnectionService/Call UI, but it does not run a long-lived custom foreground service for your app logic.
Use your own foreground service if you need:
- long-running signaling/reconnect loops in background,
- persistent background media/session processing,
- guaranteed ongoing processing beyond call UI handoff.
Typical split:
- plugin handles push ingress + system call UI bridge,
- app service handles long-lived networking/media responsibilities.
iOS setup notes
Add VoIP background mode in Info.plist:
<key>UIBackgroundModes</key>
<array>
<string>voip</string>
</array>Server side:
- regular push -> APNS/FCM token from
registration - VoIP call push -> PushKit token from
voipPushToken
Test app helper
Use included helper scripts and UI:
npm run test:setup
npm run test:updateThe generated test app uses scripts/test-app-ui.html.
API Types
See /src/definitions.ts for the complete TypeScript contract.
