
Partager:
Chris est Developer Advocate chez Nexmo où il aide les développeurs à utiliser leur plateforme de communication globale. Lorsqu'il n'est pas en conférence, vous pouvez le trouver en train de parcourir le monde.
Passer et recevoir des appels téléphoniques dans les applications Android avec Firebase
Avec Nexmo In-App VoiceAvec Nexmo In-App Voice, vous pouvez facilement passer et recevoir des appels téléphoniques avec le SDK Nexmo Stitch Android et la technologie WebRTC. Dans ce tutoriel, nous allons vous montrer comment créer une application Android simple qui peut passer des appels téléphoniques sortants et recevoir des appels téléphoniques entrants. Cette fonctionnalité peut être utilisée lorsque les clients souhaitent passer et recevoir des appels au service clientèle, sans quitter l'application.
Pour faire fonctionner l'application, nous utiliserons Firebase Functions pour héberger l'application NCCO et renvoyer un JWT pour que les utilisateurs puissent se connecter.
Pour suivre cet article de blog, vous devez avoir des connaissances en JavaScript et être capable de construire une application Android en utilisant Kotlin.
Avant de commencer
Vous aurez besoin de quelques éléments avant de commencer.
Account Vonage
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
Configurer la fonction Firebase.
Tout d'abord, nous allons créer un nouveau répertoire pour notre projet Firebase functions et pour stocker nos fichiers de configuration.
mkdir firebase-functions-nexmo-in-app-calling cd firebase-functions-nexmo-in-app-calling
Maintenant qu'un nouveau répertoire a été créé, nous pouvons suivre les instructions de configuration fournies par Firebase. fournies par Firebase et créer un nouveau projet.
npm install -g firebase-tools firebase login firebase init functions
Pour ce projet, j'ai choisi d'utiliser JavaScript au lieu de TypeScript.
Si, comme moi, vous n'avez pas réussi à créer un projet firebase function à partir de la ligne de commande, vous pouvez visiter la Firebase Console pour créer un nouveau projet, puis lancer firebase use --add à partir de votre ligne de commande.
Modifier les fonctions Firebase
Vous pouvez voir la version finale des méthodes que nous utiliserons pour les fonctions Firebase dans le repo de cette démo sur GitHub. pour cette démo sur GitHub. En bref, nous avons besoin de trois points de terminaison :
Une URL de réponse qui hébergera le NCCO
Une URL d'événement pour capturer les événements de l'API Voice
URL renvoyant un JWT permettant aux utilisateurs de se connecter.
Pour éditer les fonctions Firebase, nous devons éditer le fichier index.js dans le nouveau répertoire functions/ que firebase a créé après l'exécution de firebase init functions
Commençons par examiner la méthode Answer
exports.answer = functions.https.onRequest((request, response) => {
//use the `to` query parameter that Nexmo gives us to make a call.
//if `to` is null, then we are receiving a call.
var to = request.query.to
var from = request.query.from
var ncco = [];
if (to) {
ncco.push(
{
action: "talk",
text: "Thank you for calling, you are now being connected."
},
{
"action": "connect",
"from": functions.config().nexmo.from_number,
"endpoint": [
{
"type": "phone",
"number": `${to}`
}
]
}
)
} else {
ncco.push(
{
action: "talk",
text: "You are being connected to the Customer."
},
{
"action": "connect",
"from": from,
"endpoint": [
{
"type": "app",
"user": "Customer"
}
]
})
}
response.json(ncco);
});Comme l'API Voice de Nexmo utilise une URL de réponse par application, nous pouvons afficher dynamiquement le NCCO pour l'acceptation d'un appel entrant si le paramètre de requête to est nul. Si le paramètre to paramètre de requête est non null, nous afficherons le NCCO pour passer un appel téléphonique sortant.
Notre point d'arrivée pour fournir un JWT aux utilisateurs est assez simple. Nous utiliserons la bibliothèque bibliothèque Nexmo Node pour générer un JWT. Afin d'utiliser la bibliothèque, nous devons installer le paquetage.
#Assurez-vous d'être dans le répertoire /functions où se trouvent les fichiers package.json et index.js npm install nexmo
Après avoir installé la bibliothèque, vous pouvez vous assurer que tout fonctionne correctement en inspectant le fichier package.json en inspectant le fichier Il devrait ressembler à ceci :
"dependencies": {
"firebase-admin": "~5.12.1",
"firebase-functions": "^1.0.3",
"nexmo": "^2.3.2"
}Une fois la bibliothèque Nexmo Node installée, nous pouvons l'utiliser dans le point de terminaison jwt de la manière suivante pour renvoyer un . user_jwt.
exports.jwt = functions.https.onRequest((request, response) => {
response.json({
user_jwt: Nexmo.generateJwt("private.key", {
application_id: functions.config().nexmo.application_id,
sub: "Customer",
exp: new Date().getTime() + 86400,
acl: adminAcl
})
});
});Maintenant que nous avons créé nos fonctions Firebase, nous allons créer une application Vonage.
Déployer la fonction Firebase
Maintenant que les fonctions Firebase ont été écrites, nous pouvons déployer le projet Firebase. Après avoir déployé les fonctions, Firebase nous fournira les URL pour nos points de terminaison de réponse et d'événement. Nous pouvons utiliser ces URL pour créer notre application Vonage.
#Assurez-vous d'être dans le répertoire firebase-functions-nexmo-in-app-calling/ que nous avons créé au début de ce tutoriel firebase deploy --only functions
✔ fonctions[réponse] : Opération de création réussie. URL de la fonction (réponse) : https://your-project-name.cloudfunctions.net/answer ✔ functions[event] : Opération de création réussie. URL de la fonction (événement) : https://your-project-name.cloudfunctions.net/event ✔ functions[jwt] : Opération de création réussie. URL de la fonction (jwt) : https://your-project-name.cloudfunctions.net/jwt
Configurez l'Applications Vonage.
Pour créer une application, installez d'abord le CLI de Vonage globalement avec cette commande :
npm install @vonage/cli -gEnsuite, configurez le CLI avec votre clé et votre secret API Vonage. Vous pouvez trouver ces informations dans le tableau de bord du développeur.
vonage config:set --apiKey=VONAGE_API_KEY --apiSecret=VONAGE_API_SECRETNous allons maintenant utiliser l'URL de réponse et d'événement que Firebase nous a fournie dans la section précédente.
# Ensure you're in the firebase-functions-nexmo-in-app-calling/ directory we created at the beginning of this tutorial
vonage apps:create
✔ Application Name … ruling_narwhal
✔ Select App Capabilities › Voice
✔ Create voice webhooks? … yes
✔ Answer Webhook - URL … https://your-project-name.cloudfunctions.net/answer
✔ Answer Webhook - Method › POST
✔ Event Webhook - URL … https://your-project-name.cloudfunctions.net/event
✔ Event Webhook - Method › POST
✔ Allow use of data for AI training? Read data collection disclosure - https://help.nexmo.com/hc/en-us/articles/4401914566036 … no
Creating Application... done
Application Name: ruling_narwhalVotre clé privée est enregistrée dans le répertoire de fonctions que vous avez créé. La clé portera le même nom que votre projet.
Enregistrez l'identifiant de l'application et sauvegardez la clé privée dans le répertoire "functions". Je vous recommande d'ajouter les éléments your_private_key_name.key et .nexmo-app contenant vos informations d'identification à votre fichier .gitignore.
En suivant les bonnes pratiques, nous allons stocker quelques variables d'environnement Firebase config via le CLI firebase. La documentation de Firebase contient un sur la configuration de l'environnement.
Nous devons maintenant stocker l'identifiant de l'application Vonage dans la configuration de firebase via la CLI de firebase.
firebase functions:config:set nexmo.application_id="aaaaaaaa-bbbb-cccc-dddd-0123456789ab"
Note : Firebase exige que les clés des variables de configuration soient en minuscules, nous utiliserons donc la casse serpent pour nos noms de variables.
Si vous le souhaitez, vous pouvez télécharger la chaîne de clé privée trouvée dans le fichier .nexmo-app depuis votre application Vonage en tant que variable de configuration de firebase au lieu de télécharger le fichier entier dans les fonctions de firebase. your_private_key_name.key dans les fonctions de firebase.
Lier un numéro de téléphone et un utilisateur à notre application.
Maintenant que nos fonctions ont été écrites, nous devons acheter un numéro pour que nos utilisateurs puissent passer des appels sortants à partir de ce numéro et recevoir des appels entrants dans leur application Android chaque fois que quelqu'un compose ce numéro. Nous devons également lier le numéro à notre application Vonage.
Vous pouvez louer un numéro auprès de Vonage en utilisant la commande suivante (en remplaçant le code du pays par votre code). Par exemple, si vous êtes aux États-Unis, remplacez GB par US:
Reliez maintenant le numéro à votre application :
vonage apps:link --number=VONAGE_NUMBER APP_ID Configurer le projet Android
Si vous souhaitez voir le projet fini de notre application Android, vous pouvez voir le code source sur GitHub.
Tout d'abord, nous devons ajouter les bibliothèques nécessaires. Nous allons utiliser le SDK Android Nexmo Stitch, Retrofit, et Moshi Converter de Retrofit.
dependencies {
implementation 'com.nexmo:stitch:1.8.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation "com.squareup.retrofit2:converter-moshi:2.4.0"
}Nous utiliserons Retrofit pour faire une GET au point de terminaison JWT de la fonction Firebase que Firebase CLI nous a fourni.
//FirebaseFunctionService.kt
interface FirebaseFunctionService {
@GET("jwt")
fun getJWT(): Call<UserJWT>
}
//RetrofitClient.kt
var retrofitClient = Retrofit.Builder()
.baseUrl("https://your-project-name.cloudfunctions.net/")
.addConverterFactory(MoshiConverterFactory.create())
.build()
var retrofitService = retrofitClient.create<FirebaseFunctionService>(FirebaseFunctionService::class.java) Ajouter l'activité de connexion
Après avoir configuré Retrofit, nous pouvons l'utiliser pour récupérer un JWT à partir du point de terminaison de la fonction Firebase JWT dans le fichier LoginActivity. Je montrerai ici le chemin heureux lorsque nous récupérons le JWT de l'utilisateur et que nous l'utilisons pour nous connecter au Nexmo Stitch Android SDK. Le layout de cette activité est disponible sur GitHub.
class LoginActivity : BaseActivity(), RequestHandler<User>, Callback<UserJWT> {
override fun onCreate(savedInstanceState: Bundle?) {
...
loginBtn.setOnClickListener {
login()
}
}
private fun login() {
showProgress(true)
retrofitService.getJWT().enqueue(this)
}
//Successfully retrieved a JWT from the Firebase Function endpoint
override fun onResponse(call: Call<UserJWT>?, response: Response<UserJWT>?) {
val jwt = response?.body()?.user_jwt
client.login(jwt, this)
}
//User successfully logged in with the Nexmo Stitch SDK
override fun onSuccess(result: User?) {
goToCallActivity()
}
} Ajouter l'activité d'appel
Nous ajouterons une disposition simple pour saisir les numéros de téléphone, commencer et terminer les appels téléphoniques. La présentation de cette activité est disponible sur GitHub. Comme précédemment, je montrerai le cheminement heureux de l'émission et de la réception d'un appel.
class CallActivity : BaseActivity(), RequestHandler<Call> {
private var currentCall: Call? = null
private lateinit var client: ConversationClient
override fun onCreate(savedInstanceState: Bundle?) {
...
client = Stitch.getInstance(this).conversationClient
attachIncomingCallListener()
callControlBtn.setOnClickListener { callPhone() }
}
private fun attachIncomingCallListener() {
//Listen for incoming calls
client.callEvent().add({ incomingCall ->
logAndShow("answering Call")
//Answer an incoming call
incomingCall.answer(object : RequestHandler<Void> {
override fun onError(apiError: NexmoAPIError) {
logAndShow("Error answer: " + apiError.message)
}
override fun onSuccess(result: Void) {
currentCall = incomingCall
attachCallStateListener(incomingCall)
showHangupButton()
}
})
})
}
private fun attachCallStateListener(incomingCall: Call) {
//Listen for incoming member events in a call
val callEventListener = ResultListener<CallEvent> { message ->
logAndShow("callEvent : state: " + message.state + " .content:" + message.toString())
}
incomingCall.event().add(callEventListener)
}
private fun callPhone() {
val phoneNumber = phoneNumberInput.text.toString()
client.callPhone(phoneNumber, object : RequestHandler<Call> {
override fun onError(apiError: NexmoAPIError) {
logAndShow("Cannot initiate call: " + apiError.message)
}
override fun onSuccess(result: Call) {
currentCall = result
showHangupButton()
when (result.callState) {
Call.CALL_STATE.STARTED -> logAndShow("Started")
Call.CALL_STATE.RINGING -> logAndShow("Ringing")
Call.CALL_STATE.ANSWERED -> logAndShow("Answered")
else -> logAndShow("Error attaching call listener")
}
}
})
}
}Comme vous pouvez le constater, le SDK Nexmo Stitch s'occupe de passer les appels téléphoniques et d'y répondre.
Comment cela fonctionne-t-il ?
Recevoir un appel téléphonique
Lorsqu'un utilisateur appelle le numéro que nous avons acheté dans la section précédente, Numbers recherche le NCCO dans notre URL de réponse, à savoir https://your-project-name.cloudfunctions.net/answer . Le NCCO se présentera comme suit :
[
{
"action":"talk",
"text":"You are being connected to the Customer."
},
{
"action":"connect",
"endpoint":[
{
"type":"app",
"user":"Customer"
}
]
}
]Ce NCCO dirigera l'appel vers l'utilisateur "Client" que nous avons créé dans notre application avec le SDK Stitch. L'application s'occupera de répondre à l'appel en attachant le Call Listener dans attachIncomingCallListener() Pour des raisons de simplicité, nous répondrons automatiquement à l'appel, mais vous pourriez mettre en place une interface utilisateur et une logique pour permettre à l'utilisateur de répondre ou non à l'appel. reject() l'appel.
Passer un appel téléphonique
Si l'utilisateur choisit de passer un appel, nous le traiterons dans la méthode callPhone() dans la méthode. Par exemple, si notre méthode est appelée comme suit :
client.callPhone("14155550100", callback)Ensuite, la client.callPhone(phoneNumber, callback) méthode dans le SDK Nexmo Stitch Android utilisera l'API Stitch pour faire une demande à l'url de votre réponse GET une requête à votre url de réponse https://your-project-name.cloudfunctions.net/answer avec les paramètres de requête suivants :
?from=16625461410\ &to=14155550100\ &conversation_uuid=CON-4e977dab-2abc-42b5-bf64-d468d4763e54\ &uuid=0666edbe58077d826944a7c1913da2b0
Nous pouvons utiliser le paramètre to pour renvoyer dynamiquement un NCCO qui indique à Numbers quel numéro de téléphone appeler. L'API Stitch verra la réponse NCCO suivante :
[
{
"action":"talk",
"text":"Thank you for calling, you are now being connected."
},
{
"action":"connect",
"from":"12013753230",
"endpoint":[
{
"type":"phone",
"number":"14155550100"
}
]
}
]Dans ce cas, le from est le numéro que nous avons loué auprès de Numbers et que nous avons défini comme la valeur nexmo.from_number avec les variables de configuration de Firebase. La valeur dans number dans le tableau endpoint est le numéro que l'utilisateur veut appeler.
Essayez-le vous-même
Le repo de ce projet d'exemple contient le code source des fonctions Firebase et de l'application Android. Clonez le projet pour le découvrir !
Quelle est la prochaine étape ?
Maintenant que vous avez appris à passer et à recevoir des appels téléphoniques avec Nexmo In-App Voice vous pouvez également en savoir plus sur In-App Messaging.
Pour plus de détails sur ce que couvre le SDK Nexmo Stitch Android, vous pouvez lire la documentation du SDK en ligne. documentation SDK en ligne.
Notre Voice API offre également d'autres possibilités que la simple connexion et réception d'appels ! Consultez notre documentation pour en savoir plus sur l'enregistrement d'appels, la lecture de flux audio lors d'appels, etc.
