Empezando
registered- Registrado exitosamente con Twiliounregistered- No registrado desde TwilioregistrationFailed- Error en el registroincomingCall- Llamada entrante recibidacallConnected- Llamada conectada exitosamentecallDisconnected- Llamada desconectadacallRinging- La llamada saliente está sonandocallReconnecting- La llamada se está reconectandocallReconnected- Llamada reconectada después de una interrupciónqualityWarning- Advertencia de calidad de llamadaerror- Se produjo un error
Ejemplos de eventos
Section titled “Ejemplos de eventos”// Handle incoming callsTwilioVoice.addListener('incomingCall', (data) => { console.log('Incoming call from:', data.from); console.log('Call SID:', data.callSid);
// Show incoming call UI showIncomingCallScreen({ from: data.from, callSid: data.callSid });});
// Handle call state changesTwilioVoice.addListener('callConnected', (data) => { console.log('Call connected:', data.callSid); startCallTimer();});
TwilioVoice.addListener('callDisconnected', (data) => { console.log('Call ended:', data.callSid); stopCallTimer(); hideCallScreen();});
// Handle quality warningsTwilioVoice.addListener('qualityWarning', (data) => { console.warn('Call quality warning:', data.warning); showQualityWarning(data.warning);});
// Handle errorsTwilioVoice.addListener('error', (error) => { console.error('Twilio error:', error.message); handleError(error);});
// Remove listeners when doneconst listener = await TwilioVoice.addListener('callConnected', (data) => { console.log('Connected');});
// Later...listener.remove();Ejemplo completo
Section titled “Ejemplo completo”import { TwilioVoice } from '@capgo/capacitor-twilio-voice';
class VoiceCallService { private currentCallSid: string | null = null; private isMuted = false; private isSpeakerOn = false;
async initialize(accessToken: string) { try { // Login to Twilio await TwilioVoice.login({ accessToken });
// Check login status const { loggedIn } = await TwilioVoice.isLoggedIn(); console.log('Login status:', loggedIn);
// Setup event listeners this.setupEventListeners();
} catch (error) { console.error('Failed to initialize:', error); } }
setupEventListeners() { // Registration events TwilioVoice.addListener('registered', () => { console.log('Successfully registered with Twilio'); });
TwilioVoice.addListener('registrationFailed', (error) => { console.error('Registration failed:', error); });
// Incoming call TwilioVoice.addListener('incomingCall', async (data) => { console.log('Incoming call from:', data.from);
const accepted = await this.showIncomingCallDialog(data.from);
if (accepted) { await TwilioVoice.acceptCall({ callSid: data.callSid }); this.currentCallSid = data.callSid; } else { await TwilioVoice.rejectCall({ callSid: data.callSid }); } });
// Call events TwilioVoice.addListener('callConnected', (data) => { console.log('Call connected'); this.currentCallSid = data.callSid; this.showCallScreen(); });
TwilioVoice.addListener('callDisconnected', () => { console.log('Call disconnected'); this.currentCallSid = null; this.hideCallScreen(); });
TwilioVoice.addListener('callRinging', () => { console.log('Call ringing...'); });
// Quality warnings TwilioVoice.addListener('qualityWarning', (data) => { console.warn('Call quality warning:', data.warning); this.showQualityIndicator(data.warning); }); }
async makeCall(phoneNumber: string) { try { const result = await TwilioVoice.makeCall({ to: phoneNumber, params: { // Optional custom parameters customerId: 'customer-123' } });
this.currentCallSid = result.callSid; console.log('Call initiated:', result.callSid); } catch (error) { console.error('Failed to make call:', error); } }
async endCall() { if (this.currentCallSid) { await TwilioVoice.endCall({ callSid: this.currentCallSid }); this.currentCallSid = null; } }
async toggleMute() { this.isMuted = !this.isMuted; await TwilioVoice.muteCall({ muted: this.isMuted, callSid: this.currentCallSid || undefined }); }
async toggleSpeaker() { this.isSpeakerOn = !this.isSpeakerOn; await TwilioVoice.setSpeaker({ enabled: this.isSpeakerOn }); }
async sendDTMF(digits: string) { if (this.currentCallSid) { await TwilioVoice.sendDigits({ digits, callSid: this.currentCallSid }); } }
async logout() { await TwilioVoice.logout(); }
private async showIncomingCallDialog(from: string): Promise<boolean> { // Show native dialog or custom UI return confirm(`Incoming call from ${from}`); }
private showCallScreen() { // Show call UI console.log('Showing call screen'); }
private hideCallScreen() { // Hide call UI console.log('Hiding call screen'); }
private showQualityIndicator(warning: string) { // Show quality warning console.log('Quality warning:', warning); }}
// Usageconst voiceService = new VoiceCallService();
// Initialize with access token from your backendconst token = await fetchTwilioToken();await voiceService.initialize(token);
// Make a callawait voiceService.makeCall('+1234567890');
// Control callawait voiceService.toggleMute();await voiceService.toggleSpeaker();await voiceService.sendDTMF('1');
// End callawait voiceService.endCall();
// Logoutawait voiceService.logout();Mejores prácticas
Section titled “Mejores prácticas”- Obtenga tokens de acceso de su servidor backend, nunca los incruste en la aplicación
- Implementar lógica de actualización de tokens para sesiones de larga duración.
- Manejar las interrupciones de la red con lógica de reconexión.
- Proporcionar información visual para los estados de las llamadas.
- Prueba en dispositivos reales con notificaciones push
- Implementar un manejo adecuado de errores.
- Limpiar los oyentes cuando los componentes se desmontan
- Solicitar permisos de micrófono antes de realizar llamadas.
Consideraciones de seguridad
Section titled “Consideraciones de seguridad”- Nunca almacene Twilio credenciales en la aplicación
- Genera tokens de acceso en tu backend
- Implementar la caducidad y actualización del token.
- Utilice HTTPS para todas las solicitudes de tokens
- Validar llamadas entrantes del lado del servidor
Solución de problemas
Section titled “Solución de problemas”Llamadas que no se conectan
Section titled “Llamadas que no se conectan”- Verificar que el token de acceso sea válido y no esté caducado.
- Verificar la conectividad de la red.
- Asegúrese de que se concedan los permisos del micrófono
- Verificar que la cuenta Twilio esté configurada correctamente
Las notificaciones automáticas no funcionan
Section titled “Las notificaciones automáticas no funcionan”- Verifique que los certificados PushKit/FCM estén configurados en Twilio
- Verifique que el dispositivo esté registrado para recibir notificaciones push
- Prueba con certificados de producción.
Problemas de audio
Section titled “Problemas de audio”- Verificar los permisos del micrófono
- Verificar la configuración del altavoz/bluetooth
- Pruebe el enrutamiento de audio en dispositivos reales
Visualización del nombre de la persona que llama (CapacitorTwilioCallerName)
Section titled “Visualización del nombre de la persona que llama (CapacitorTwilioCallerName)”De forma predeterminada, las llamadas entrantes muestran el número de teléfono o la identificación del cliente de la persona que llama. Puede personalizar esto pasando un parámetro CapacitorTwilioCallerName desde su backend TwiML para mostrar un nombre descriptivo.
Configuración del servidor
Section titled “Configuración del servidor”Al generar su respuesta TwiML para el dial <Client>, agregue el parámetro CapacitorTwilioCallerName:
// Java exampleParameter callerNameParam = new Parameter.Builder() .name("CapacitorTwilioCallerName") .value("John Doe") .build();
Client client = new Client.Builder(identity) .parameter(callerNameParam) .build();
Dial dial = new Dial.Builder() .client(client) .build();// Node.js exampleconst VoiceResponse = require('twilio').twiml.VoiceResponse;
const response = new VoiceResponse();const dial = response.dial();dial.client({ name: 'CapacitorTwilioCallerName', value: 'John Doe'}, identity);Cómo funciona
Section titled “Cómo funciona”- Cuando su backend recibe una llamada entrante, genera TwiML para enrutar la llamada.
- Incluya el parámetro
CapacitorTwilioCallerNamecon el nombre para mostrar de la persona que llama. - El complemento extrae automáticamente este parámetro y lo utiliza para:
- iOS Pantalla de llamada entrante de CallKit
- Android notificación de llamada entrante
- El campo
fromen eventosincomingCall - La matriz
pendingInvitesen estado de llamada
Si no se proporciona CapacitorTwilioCallerName, el complemento recurre al número de teléfono o ID del cliente de la persona que llama.