Einen eingehenden Anruf entgegennehmen
Eingehende Anrufe werden an Kunden mit aktiven Sitzungen weitergeleitet, nachdem die Vonage-API Ihren Webhook-Ablauf für die Anrufannahme ausgeführt hat.
Eingehender Pfad
Warnung: Registrieren Sie zuerst die Listener Anruf registrieren, Teilnehmer einladen vor eine Sitzung zu erstellen oder die Verbindung wiederherzustellen, damit eingehende Einladungen nicht verpasst werden.
Bearbeitung eingehender Anrufeinladungen
client.on('callInvite', async (callId, from, channelType) => {
console.log(`Received call invite from ${from} on ${channelType}`);
// To accept the call:
await client.answer(callId);
// Or to reject the call:
// await client.reject(callId);
});
client.on('callInviteCancel', (callId, reason) => {
if (reason === CancelReason.AnsweredElsewhere) {
console.log(`Call ${callId} was answered elsewhere`);
} else if (reason === CancelReason.RejectedElsewhere) {
console.log(`Call ${callId} was rejected elsewhere`);
} else if (reason === CancelReason.RemoteCancel) {
console.log(`Call ${callId} was cancelled by the caller`);
} else if (reason === CancelReason.RemoteTimeout) {
console.log(`Call ${callId} timed out`);
}
});
// Answer Call
client.setCallInviteListener {callId, from, channelType ->
println("Incoming Call from $from by channel $channelType")
client.answer(callId) {
it?.let {err ->
// Handle Error in answering call
println("Error in answering call: $err")
}
}
}
// Or reject the call:
// client.setCallInviteListener { callId, from, channelType ->
// client.reject(callId) {
// it?.let {err ->
// println("Error in rejecting call: $err")
// }
// }
// }
// Invite Cancelled
client.setCallInviteCancelListener { callId, reason ->
when (reason) {
VoiceInviteCancelReason.RemoteCancel -> println("Call Invite for call $callId was cancelled by the caller")
VoiceInviteCancelReason.AnsweredElsewhere -> println("Call Invite for call $callId was answered on another device")
VoiceInviteCancelReason.RejectedElsewhere -> println("Call Invite for call $callId was rejected on another device")
VoiceInviteCancelReason.RemoteTimeout -> println("Call Invite for call $callId timed out")
}
}
// Answer Call
client.setCallInviteListener((callId, from, channelType) -> {
System.out.println("Incoming Call from " + from + " by channel " + channelType);
client.answer(callId, it -> {
if (it != null) {
// Handle Error in answering call
System.out.println("Error in answering call: " + it);
}
return null;
});
return null;
});
// Or reject the call:
// client.setCallInviteListener((callId, from, channelType) -> {
// client.reject(callId, it -> {
// if (it != null) {
// System.out.println("Error in rejecting call: " + it);
// }
// return null;
// });
// return null;
// });
// Invite Cancelled
client.setCallInviteCancelListener((callId, reason) -> {
switch (reason) {
case RemoteCancel:
System.out.println("Call Invite for call " + callId + " was cancelled by the caller");
break;
case AnsweredElsewhere:
System.out.println("Call Invite for call " + callId + " was answered on another device");
break;
case RejectedElsewhere:
System.out.println("Call Invite for call " + callId + " was rejected on another device");
break;
case RemoteTimeout:
System.out.println("Call Invite for call " + callId + " timed out");
break;
}
return null;
});
class inboundCallExampleDelegate: NSObject, VGVoiceClientDelegate {
func voiceClient(_ client: VGVoiceClient, didReceiveInviteForCall callId: VGCallId, from caller: String, with type: VGVoiceChannelType) {
print(caller)
// Answer Invite
client.answer(callId) { error in
guard error != nil else {
print("Failed to answer \(error?.localizedDescription ?? "")")
return
}
}
// Or reject the invite:
// client.reject(callId) { error in
// guard error != nil else {
// print("Failed to reject \(error?.localizedDescription ?? "")")
// return
// }
// }
}
func voiceClient(_ client: VGVoiceClient, didReceiveInviteCancelForCall callId: VGCallId, with reason: VGVoiceInviteCancelReason) {
guard callId == "currentCallId" else {
return
}
switch reason {
case .answeredElsewhere:
print("Call answered elsewhere")
case .remoteCancel:
print("Call cancelled by remote")
case .rejectedElsewhere:
print("Call rejected elsewhere")
case .remoteTimeout:
print("Call timed out")
default:
print("reason unknown")
}
}
func client(_ client: VGBaseClient, didReceiveSessionErrorWith reason: VGSessionErrorReason) {}
func voiceClient(_ client: VGVoiceClient, didReceiveHangupForCall callId: VGCallId, withQuality callQuality: VGRTCQuality, reason: VGHangupReason) {}
}
- (void) voiceClient:(VGVoiceClient *)client didReceiveInviteForCall:(VGCallId)callId from:(NSString *)caller withChannelType:(VGVoiceChannelType)type {
NSLog(@"Caller: %@", caller);
// Answer Invite
[client answer:callId callback:^(NSError * _Nullable error) {
if(error){
NSLog(@"Failed to answer: %@", error);
}
}];
// Or reject the invite:
// [client reject:callId callback:^(NSError * _Nullable error) {
// if(error){
// NSLog(@"Failed to reject: %@", error);
// }
// }];
}
- (void) voiceClient:(VGVoiceClient *)client didReceiveInviteCancelForCall:(VGCallId)callId withReason:(VGVoiceInviteCancelReason)reason {
if(![callId isEqualToString:@"currentCallId"]){
return;
}
switch(reason) {
case VGVoiceInviteCancelReasonAnsweredElsewhere:
NSLog(@"Call answered elsewhere");
break;
case VGVoiceInviteCancelReasonRemoteCancel:
NSLog(@"Call canceled by remote");
break;
case VGVoiceInviteCancelReasonRejectedElsewhere:
NSLog(@"Call rejected elsewhere");
break;
case VGVoiceInviteCancelReasonRemoteTimeout:
NSLog(@"Call timed out");
break;
case VGVoiceInviteCancelReasonUnknown:
NSLog(@"Reason Unknown");
break;
}
}
Verhalten beim Einladen und Abbrechen
Einladungen können storniert werden oder verfallen, bevor der Nutzer eine Aktion ausführt. Ihre App erhält einen Stornierungs-Callback mit einem der folgenden Gründe:
| Grund | Beschreibung |
|---|---|
RemoteCancel |
Der Anrufer legte auf, bevor die Einladung beantwortet wurde. |
RemoteTimeout |
Die Einladung ist in der Vonage-API ohne Eingreifen des Benutzers abgelaufen. |
AnsweredElsewhere |
Derselbe Benutzer hat den Anruf auf einem anderen Gerät oder einer anderen Client-Instanz angenommen. |
RejectedElsewhere |
Derselbe Benutzer hat den Anruf auf einem anderen Gerät oder einer anderen Client-Instanz abgelehnt. |
UX-Leitfaden
- Die Benutzeroberfläche für eingehende Anrufe sofort schließen, sobald ein Grund zum Abbrechen vorliegt.
- Versuchen Sie nicht, anzurufen
answer()oderreject()Nach Erhalt einer Absage ist die Einladung nicht mehr gültig. - Für Szenarien mit mehreren Geräten (
AnsweredElsewhere/RejectedElsewhere), sollten Sie erwägen, eine kurze Meldung oder eine visuelle Anzeige einzublenden, damit der Benutzer versteht, warum das Klingeln aufgehört hat.
Umgang mit Fehlern
answer() und reject() kann fehlschlagen, wenn die Sitzung abgelaufen ist, die Einladung nicht mehr gültig ist (bereits storniert wurde) oder ein Netzwerkproblem vorliegt. Behandeln Sie stets den Fehler-Callback, um Ihre Benutzeroberfläche entsprechend anzupassen:
try {
await client.answer(callId);
showActiveCallUI();
} catch (error) {
console.error("Answer failed:", error.type, error.message);
dismissIncomingCallUI();
}
try {
await client.reject(callId);
} catch (error) {
console.error("Reject failed:", error.type, error.message);
} finally {
dismissIncomingCallUI();
}
client.answer(callId) { error ->
if (error != null) {
// Answer failed — dismiss call UI and inform the user
println("Answer failed: ${error.message}")
// Common causes:
// - Session expired (re-create session and retry)
// - Invite already cancelled by caller
dismissIncomingCallUI()
return@answer
}
// Success — transition to active call UI
showActiveCallUI()
}
client.reject(callId) { error ->
if (error != null) {
// Reject failed — the invite may have already been cancelled
println("Reject failed: ${error.message}")
}
// In both success and failure, dismiss the incoming call UI
dismissIncomingCallUI()
}
client.answer(callId) { error in
if let error = error {
print("Answer failed: \(error.localizedDescription)")
self.dismissIncomingCallUI()
return
}
self.showActiveCallUI()
}
client.reject(callId) { error in
if let error = error {
print("Reject failed: \(error.localizedDescription)")
}
self.dismissIncomingCallUI()
}
Wenn answer() Wenn der Vorgang aufgrund einer abgelaufenen Sitzung fehlschlägt, erstellen Sie die Sitzung mit einem neuen JWT neu und versuchen Sie die Antwort erneut. Wenn die Einladung bereits abgebrochen wurde (der Anrufer hat aufgelegt), gibt es keine Möglichkeit zur Wiederherstellung – schließen Sie die Benutzeroberfläche und warten Sie auf die nächste Einladung.
Weitere Lektüre
- NCCO-Referenz — vollständige Dokumentation zur JSON-Struktur, die Ihr Antwort-Webhook zurückgibt