Hacer una llamada
Visión general
Esta guía cubre las funcionalidades de tu aplicación cliente de Vonage para iniciar llamadas de voz dentro de la aplicación o administradas por el servidor.
Antes de empezar, asegúrese de que ha añadido el SDK a su aplicación.
Iniciar una llamada desde la aplicación
La forma más rápida de iniciar una llamada in-app es realizar una llamada in-app a in-app, es decir, entre dos usuarios.
new NexmoClient()
.createSession(USER_JWT)
.then(application => {
...
application.inAppCall(userName);
})
val callListener = object: NexmoRequestListener<NexmoCall> {
override fun onSuccess(nexmoCall: NexmoCall?) {
Log.d("TAG", "Call started: ${nexmoCall.toString()}")
}
override fun onError(apiError: NexmoApiError) {
Log.d("TAG", "Error: Unable to start a call ${apiError.message}")
}
}
client.inAppCall("123456", callListener);
NexmoRequestListener<NexmoCall> callListener = new NexmoRequestListener<NexmoCall>() {
@Override
public void onSuccess(@Nullable NexmoCall nexmoCall) {
Log.d("TAG", "Call started: " + nexmoCall.toString());
}
@Override
public void onError(@NonNull NexmoApiError apiError) {
Log.d("TAG", "Error: Unable to start a call " + apiError.getMessage());
}
};
client.inAppCall("123456", callListener)
NXMClient.shared.inAppCall(withCallee: userName) { [weak self] (error, call) in
guard let call = call else {
// Handle create call failure
...
return
}
// Handle call created successfully.
...
})
[[NXMClient shared] inAppCallWithCallee:userName completionHandler:^(NSError * _Nullable error, NXMCall * _Nullable call) {
if(error) {
// Handle create call failure
...
return;
}
// Handle call created successfully.
...
}];
Las posibles capacidades de voz son muy limitadas, ya que no utiliza la Voice API. Este método se recomienda sobre todo para el onboarding. Más adelante, se recomienda utilizar una llamada gestionada por servidor.
Iniciar una llamada gestionada por el servidor
Este método le permite realizar llamadas dentro de la aplicación, así como llamadas telefónicas, aprovechando al mismo tiempo la riqueza de la aplicación. Funciones de Voice API.
Cuando la aplicación cliente llama a este método, el answer_url webhook que está configurado para su Aplicación de Vonage se ejecutará. Esto define el lógica y capacidades de la llamada.
En el lado del cliente, inicie la llamada como tal:
new NexmoClient()
.createSession(USER_JWT)
.then(application => {
...
application.callServer(phoneNumber);
})
val callListener = object: NexmoRequestListener<NexmoCall> {
override fun onSuccess(nexmoCall: NexmoCall?) {
Log.d("TAG", "Call started: ${nexmoCall.toString()}")
}
override fun onError(apiError: NexmoApiError) {
Log.d("TAG", "Error: Unable to start a call ${apiError.message}")
}
}
client.serverCall("123456", null, callListener);
NexmoRequestListener<NexmoCall> callListener = new NexmoRequestListener<NexmoCall>() {
@Override
public void onSuccess(@Nullable NexmoCall nexmoCall) {
Log.d("TAG", "Call started: " + nexmoCall.toString());
}
@Override
public void onError(@NonNull NexmoApiError apiError) {
Log.d("TAG", "Error: Unable to start a call " + apiError.getMessage());
}
};
client.serverCall("123456", null, callListener)
NXMClient.shared.serverCall(withCallee: userName, customData: nil) { [weak self] (error, call) in
guard let call = call else {
// Handle create call failure
...
return
}
// Handle call created successfully.
...
})
[[NXMClient shared] serverCallWithCallee:userName customData:nil
completionHandler:^(NSError * _Nullable error, NXMCall * _Nullable call) {
if(error) {
// Handle create call failure
...
return;
}
// Handle call created successfully.
...
}];
Datos personalizados
El método de llamada al servidor tiene un parámetro para datos personalizados. Esto le permite pasar contexto adicional, en un formato clave-valor, a su answer_url servidor webhook.
new NexmoClient()
.createSession(USER_JWT)
.then(application => {
...
application.callServer(phoneNumber, "phone", {"device_name": "Alice app"});
})
val callListener = object: NexmoRequestListener<NexmoCall> {
override fun onSuccess(nexmoCall: NexmoCall?) {
Log.d("TAG", "Call started: ${nexmoCall.toString()}")
}
override fun onError(apiError: NexmoApiError) {
Log.d("TAG", "Error: Unable to start a call ${apiError.message}")
}
}
val customData:HashMap<String, Any> = HashMap<String, Any>()
customData.put("device_name", "Alice app")
client.serverCall("123456", customData, callListener);
NexmoRequestListener<NexmoCall> callListener = new NexmoRequestListener<NexmoCall>() {
@Override
public void onSuccess(@Nullable NexmoCall nexmoCall) {
Log.d("TAG", "Call started: " + nexmoCall.toString());
}
@Override
public void onError(@NonNull NexmoApiError apiError) {
Log.d("TAG", "Error: Unable to start a call " + apiError.getMessage());
}
};
HashMap<String, Object> customData = new HashMap<String, Object>();
customData.put("device_name", "Alice app");
client.serverCall("123456", customData, callListener)
NXMClient.shared.serverCall(withCallee: userName, customData: ["device_name": "Alice app"]) { [weak self] (error, call) in
guard let call = call else {
// Handle create call failure
...
return
}
// Handle call created successfully.
...
})
[[NXMClient shared] serverCallWithCallee:userName customData:@{@"device_name": @"Alice app"}
completionHandler:^(NSError * _Nullable error, NXMCall * _Nullable call) {
if(error) {
// Handle create call failure
...
return;
}
// Handle call created successfully.
...
}];
Los datos estarán disponibles en la consulta de la solicitud realizada a su answer_url servidor webhook:
{
"to": "447000000000",
"from_user": "Alice",
"conversation_uuid": "CON-8dd32088-66be-42ae-b0af-c9e12ca588ed",
"uuid": "54c255ca-9c1c-4ecd-b175-a1d022dc7b07",
"custom_data": {
"device_name": "Alice app"
}
}
Escuchar eventos de llamada
Para ver información actualizada sobre el estado de una llamada, por ejemplo, para saber si el otro miembro ha contestado o ha colgado la llamada, debes escuchar los eventos de llamada.
Para ver información actualizada sobre el estado de la convocatoria y sus miembros:
application.on("call:status:changed",(call) => {
...
});
val callEventListener = object : NexmoCallEventListener {
override fun onDTMF(digit: String?, nexmoMember: NexmoMember?) {
Log.d("TAG", "onDTMF(): digit: $digit, nexmoMember: $nexmoMember")
}
override fun onMemberStatusUpdated(memberStatus: NexmoCallMemberStatus?, nexmoMember: NexmoMember?) {
Log.d("TAG", "onMemberStatusUpdated(): status: $memberStatus, nexmoMember: $nexmoMember")
}
override fun onMuteChanged(muteState: NexmoMediaActionState?, nexmoMember: NexmoMember?) {
Log.d("TAG", ":NexmoMediaActionState(): muteState: $muteState, nexmoMember: $nexmoMember")
}
override fun onEarmuffChanged(earmuffState: NexmoMediaActionState?, nexmoMember: NexmoMember?) {
Log.d("TAG", "onEarmuffChanged(): earmuffState: $earmuffState, nexmoMember: $nexmoMember")
}
}
nexmoCall?.addCallEventListener(callEventListener)
Retire el oyente cuando sea necesario:
nexmoCall?.removeCallEventListener(callEventListener)
NexmoCallEventListener callEventListener = new NexmoCallEventListener() {
@Override
public void onMemberStatusUpdated(NexmoCallMemberStatus $memberStatus, NexmoMember nexmoMember) {
Log.d("TAG", "onMemberStatusUpdated(): status: " + $memberStatus + " nexmoMember: " + nexmoMember);
}
@Override
public void onMuteChanged(NexmoMediaActionState muteState, NexmoMember nexmoMember) {
Log.d("TAG", "NexmoMediaActionState(): muteState: " + muteState + ", nexmoMember: " + nexmoMember);
}
@Override
public void onEarmuffChanged(NexmoMediaActionState earmuffState, NexmoMember nexmoMember) {
Log.d("TAG", "onEarmuffChanged(): earmuffState: " + earmuffState + ", nexmoMember: " + nexmoMember);
}
@Override
public void onDTMF(String digit, NexmoMember nexmoMember) {
Log.d("TAG", "onDTMF(): digit:" + digit + ", nexmoMember: " + nexmoMember);
}
};
nexmoCall.addCallEventListener(callEventListener);
Retire el oyente cuando sea necesario:
nexmoCall.removeCallEventListener(callEventListener);
Añade el ViewControllero similar, como delegado del call devuelto al realizar una llamada:
call.setDelegate(self)
call.answer { [weak self] error in
...
}
ViewController ahora tendrán que ajustarse a NXMCallDelegate:
extension ViewController: NXMCallDelegate {
func call(_ call: NXMCall, didUpdate member: NXMMember, with status: NXMCallMemberStatus) {
// Handle call status updates
...
}
func call(_ call: NXMCall, didUpdate member: NXMMember, isMuted muted: Bool) {
// Handle member muting updates
...
}
func call(_ call: NXMCall, didReceive error: Error) {
print("call error: \(error.localizedDescription)")
// Handle call errors
...
}
}
Añade el ViewControllero similar, como delegado del call devuelto al realizar una llamada:
[call setDelegate:self];
[call answer:^(NSError * _Nullable error) {
...
}];
ViewController ahora tendrán que ajustarse a NXMCallDelegate:
@interface ViewController () <NXMCallDelegate>
...
@end
@implementation ViewController
...
//MARK:- NXMCallDelegate
- (void)call:(nonnull NXMCall *)call didUpdate:(nonnull NXMMember *)member withStatus:(NXMCallMemberStatus)status {
// Handle call status updates
...
}
- (void)call:(nonnull NXMCall *)call didUpdate:(nonnull NXMMember *)member isMuted:(BOOL)muted {
// Handle member muting updates
...
}
- (void)call:(nonnull NXMCall *)call didReceive:(nonnull NSError *)error {
NSLog(@"call error: %@", [error localizedDescription]);
// Handle call errors
...
}
@end