Partager:
Aaron était défenseur des développeurs chez Nexmo. Ingénieur logiciel chevronné et artiste numérique en herbe, Aaron est souvent amené à créer des choses avec du code ou de l'électronique, parfois les deux. On peut généralement savoir qu'il travaille sur quelque chose de nouveau grâce à l'odeur de composants brûlés qui flotte dans l'air.
Suivi des campagnes d'appels vocaux entrants avec Mixpanel
Temps de lecture : 10 minutes
Le suivi des campagnes est indispensable à toute campagne de marketing ou de publicité. Sans la possibilité de suivre avec précision le nombre d'utilisateurs qui s'engagent dans chaque publicité, vous ne pouvez pas calculer votre coût par acquisition (CPA), et vous ne pouvez donc pas déterminer quelles sont les campagnes qui réussissent et quelles sont celles qui font perdre de l'argent à votre entreprise ; le CPA est supérieur à l'ARPU (revenu moyen par utilisateur).
![]()
(L'intelligence économique utilise des acronymes et un jargon encore pires que ceux de la technologie !)
Compte tenu de l'importance de la publicité sur le web, il n'est pas surprenant que les outils de gestion des campagnes en ligne soient déjà bien au point. Cependant, lorsque nous voulons suivre les "clics" de la publicité imprimée ou d'autres publicités hors ligne, nous devons recourir à des URL promotionnels uniques ou à des codes de coupon.
Cependant, une fois que l'utilisateur a saisi notre URL promotionnelle ou notre code de coupon, nous pouvons le suivre à l'aide des mêmes outils de veille stratégique et d'analyse éprouvés que pour toute autre campagne en ligne.
Mais qu'en est-il de nos appels téléphoniques entrants? On peut soutenir que les utilisateurs qui choisissent d'appeler notre entreprise sont déjà plus engagés vis-à-vis de notre marque que ceux qui ont simplement cliqué sur un lien, mais les outils existants pour suivre ces interactions sont soit sujets à des erreurs, soit, dans le cas des équipements de traitement des appels des entreprises, d'un coût prohibitif.
Le suivi des appels entrants se heurte à la même difficulté que les URL d'impression, à savoir le passage de l'analogique au numérique. Nous avons besoin d'un point d'entrée unique pour chaque campagne, quelque chose qui soit aussi bon marché et facile à mettre en place qu'une URL unique, mais qui nous permette de suivre nos campagnes vocales entrantes dans notre plateforme CRM ou BI existante.
Les Numbers virtuels Nexmo sont parfaits dans cette situation. Ils sont bon marché, faciles à installer et nous pouvons créer un numéro virtuel unique pour chaque campagne, ce qui nous permet de savoir où l'utilisateur a vu chaque numéro et, en fin de compte, quelle campagne fournit le meilleur ROI (retour sur investissement). Il est également possible d'acheter des numéros locaux dans 66 pays différents, de manière à ce qu'ils soient spécifiques à une région, et ce nombre ne cesse d'augmenter.
Exigences
Si vous souhaitez exécuter l'exemple localement, vous aurez besoin des éléments suivants :
a Account MixpanelLe niveau gratuit est suffisant pour cet exemple.
un moyen d'exposer votre application locale Flask à l'internet public. J'ai tendance à d'utiliser ngrok pour cela pendant le développement
Quelques connaissance de Python/Flask serait utile mais n'est pas nécessaire. Le code est assez simple, donc même si vous préférez Ruby, PHP, JavaScript, etc. vous devriez pouvoir suivre sans trop de difficultés.
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.
This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.
Que voulons-nous suivre ?
![]()
La campagne de réception
Nous devons savoir quelle campagne a été appelée par l'utilisateur. Il se peut que plusieurs campagnes différentes soient menées sur différents canaux. Nous devons donc identifier la campagne afin de pouvoir y associer correctement les actions de l'utilisateur.
L'appelant
Idéalement, nous aimerions connaître leur nom, mais cela ne sera possible que dans certains territoires. mais cela ne sera possible que dans certains territoires. Mais en utilisant l Number Insight API nous devrions toujours être en mesure d'identifier le type de numéro à partir duquel ils appellent, le pays dans lequel ils se trouvent et la fréquence de leurs appels.
En utilisant leur numéro de téléphone comme identifiant unique, nous pouvons également être en mesure de suivre leurs actions au-delà de cet appel. Si, lors de l'enregistrement sur notre site web, nous capturons le numéro de téléphone de l'utilisateur, que nous pouvons confirmer avec le numéro Verify APIde vérification du numéro, nous pouvons croiser toutes les actions futures de l'utilisateur avec l'appel qu'il a passé à notre numéro virtuel.
L'appel
Dans cet exemple, nous n'allons suivre que les appels terminés, mais nous pourrions suivre les différents statuts d'appel tels que le délai d'attente, l'échec, le rejet, l'occupation, etc. les différents statuts d'appel tels que le délai d'attente, l'échec, le rejet, l'occupation. Les autres informations que nous devons suivre sont la durée et le coût de l'appel. Grâce à ces informations, nous pouvons commencer à calculer le coût par acquisition de nos nouveaux clients par le biais de cette campagne.
Suivi de la campagne vocale entrante, tout au long du processus.
![]()
Le diagramme de séquence ci-dessus peut sembler impressionnant, mais prenons-le un par un.
Répondre aux appels entrants
Lorsqu'un utilisateur compose un numéro virtuel Nexmo, l'API Nexmo demande un objet de contrôle d'appel Nexmo (NCCO). objet de contrôle d'appel Nexmo (NCCO) à partir de l'URL que nous fournissons. Ce fichier JSON NCCO contient une liste d'actions que Nexmo doit exécuter lorsqu'un appel est reçu.
La première action que nous voulons effectuer est de diffuser un mp3 en continu. La première action que nous voulons effectuer est de diffuser un mp3 à l'appelant ; ce fichier son l'informera que nous pouvons enregistrer l'appel.
[
{
"action": "stream",
"streamUrl": [
"https://example.com/audio/calls-recorded.mp3"
]
}
] Enregistrement et connexion de l'appel à notre agent
Dans la deuxième partie du diagramme de séquence, nous commençons l'enregistrement de l'appel, puis nous connectons l'appelant à l'agent qui traite les appels pour cette campagne.
[
{
"action": "stream",
"streamUrl": [
"https://example.com/audio/calls-recorded.mp3"
]
},
{
"action": "record",
"eventUrl": [
"https://example.com/record/"
]
}
]L'action action d'enregistrement dans le NCCO est simple. Il suffit de spécifier l'URL qui doit recevoir une notification lorsque l'enregistrement de l'appel est disponible. Lorsque l'appel est terminé, l'enregistrement s'arrête automatiquement.
Connexion de l'appel
Lors de l'utilisation de l'action de connexion, notre numéro de départ doit être un numéro virtuel Nexmo. Dans ce cas, nous utiliserons le numéro de la campagne vocale entrante que l'utilisateur appelle.
[
{
"action": "stream",
"streamUrl": [
"https://example.com/audio/calls-recorded.mp3"
]
},
{
"action": "record",
"eventUrl": [
"https://example.com/record/"
]
},
{
"action": "connect",
"endpoint": [
{
"number": "441632960616",
"type": "phone"
}
],
"from": "441632960277"
}
]Vous pouvez spécifier différents types de points d'extrémité auxquels se connecter, tels qu'une connexion WebSocketmais comme nous voulons passer l'appel par procuration, nous allons utiliser le type "téléphone", puis le numéro auquel nous souhaitons nous connecter.
Création de notre première vue Flask
Dans l'exemple ci-dessus, toutes nos valeurs sont codées en dur. Mais dans une situation réelle, de nombreuses valeurs changeront en fonction du numéro virtuel que l'utilisateur a composé. Nous devrons d'abord identifier la campagne pour laquelle ils appellent, puis mettre à jour l'emplacement du fichier mp3 et le numéro de téléphone de l'agent entrant.
Nous devons également envisager le cas où nous ne disposons pas d'une campagne active pour un numéro. Il s'agit peut-être d'une ancienne publicité, et la campagne de marketing n'est plus en cours. Il se peut que nous n'ayons pas d'agents disponibles pour traiter les appels relatifs à cette campagne, mais nous ne voulons pas libérer le numéro virtuel. Dans notre exemple de code, nous utiliserons l'action action de synthèse vocale pour informer l'utilisateur que le numéro n'est plus actif. Cependant, dans votre application réelle, vous pourriez rediriger l'utilisateur vers votre standard principal ou effectuer une autre action qui offrirait une meilleure expérience à l'utilisateur.
Voyons d'abord comment trouver la campagne concernée.
def get_campaign(number_to):
Campaign = Query()
campaigns = db.search(
(Campaign.inbound_number == number_to) | (Campaign.redirect_number == number_to)
)
return campaigns[0] if campaigns else None
@app.route('/')
def answer():
number_to = request.args.get('to')
campaign = get_campaign(number_to)Nous utilisons tinydb dans notre exemple ; il s'agit d'un moteur de base de données simple pour Python, conçu pour les systèmes embarqués. Il est parfait pour notre exemple car il s'appuie sur un simple fichier plat (JSON) comme base de données, mais vous pouvez facilement le remplacer par SQLAlchemy ou un autre ORM de votre choix.
Lorsque Numbers demande notre NCCO, il inclut le numéro appelé dans le format international E.164. format international E.164 dans la chaîne de requête. Nous utiliserons ce numéro lorsque nous interrogerons notre base de données pour la campagne concernée. Vous devez donc veiller à utiliser également le format E.164 lorsque vous enregistrez les informations relatives à votre campagne dans votre base de données.
Notre fonction get_campaign renvoie la première campagne correspondante, ou si aucune campagne n'est trouvée, nous renvoyons None.
Répondre avec notre objet de contrôle d'appel Nexmo
Si nous avons réussi à trouver une campagne correspondante dans les étapes ci-dessus, nous remplirons notre NCCO avec les données correctes suivantes streamUrl, from et endpoint. Si nous ne trouvons pas de campagne correspondante, nous utiliserons l'API de synthèse vocale et une voix synthétisée pour informer l'utilisateur ; Le numéro composé n'a pas été reconnu.
if campaign:
ncco = [
{
'action': 'stream',
'streamUrl': ['https://example.com/{message}'.format(
message=campaign['welcome_message']
)]
},
{
'action': 'record',
'eventUrl': ['https://example.com/record/']
},
{
'action': 'connect',
'from': campaign['inbound_number'],
'endpoint': [{
'type': 'phone',
'number': campaign['redirect_number']
}]
}
]
return jsonify(ncco)
else:
return jsonify([{
'action': 'talk',
'text': 'The number dialled has not been recognised. Please check and try again'
}]) Suivi des informations relatives aux appels entrants
Une fois l'appel terminé, non seulement l'enregistrement de l'appel se terminera, mais Nexmo déclenchera notre webhook avec les informations pertinentes.
Cet événement terminé ne contiendra cependant pas d'informations sur l'utilisateur qui a effectué l'appel. Pour cela, nous devrons utiliser l'API Number Insight API de Numbers.
Une fois que nous avons obtenu toutes les informations dont nous avons besoin, à savoir la campagne pour laquelle ils ont appelé, l'identité de la personne qui a appelé et les informations sur l'appel lui-même, nous stockons ces informations dans Mixpanel.
Nous utilisons Mixpanel dans cet exemple, mais cela ne signifie pas que vous ne pouvez utiliser que Mixpanel. Envoyez les données à l'outil de votre choix, ou à plusieurs Applications en même temps à l'aide d'un outil tel que Segment. Peu importe que vous utilisiez Mixpanel, KISSmetrics, Periscope, Chartio, Salesforce ou même un système BI ou CRM sur mesure. S'il peut recevoir des données, vous pourrez utiliser cette même approche pour suivre vos appels entrants.
@app.route('/event', methods=['POST'])
def callevent():
event = json.loads(request.data)
if event['status'] == 'completed':
campaign = get_campaign(event['to'])Tout d'abord, nous spécifions que ce point d'accès n'accepte que des POST car c'est ce que nous recevrons de Nexmo. Le corps de cette POST sera une chaîne JSON, nous devrons donc la convertir en un objet Python.
Comme indiqué ci-dessus, dans cet exemple, nous ne nous intéressons qu'aux appels dont le statut est terminé. Il existe beaucoup d'autres statuts que nous pourrions recevoir, tels que occupé ou échoué, et ces statuts pourraient être très importants à suivre si, par exemple, vous écriviez un logiciel pour suivre les appels d'assistance entrants. Mais pour l'instant, nous allons nous concentrer sur les appels terminés.
De plus, nous n'allons suivre que les demandes relatives aux campagnes existantes. Donc, avant de faire quoi que ce soit d'autre, nous allons utiliser notre fonction get_campaign et vérifier que l'utilisateur a appelé pour une campagne active.
Création de nos clients Mixpanel et Nexmo
Pour rechercher des informations sur notre appelant, nous avons besoin d'une instance du client de l'API client API Nexmo afin de pouvoir utiliser l'API Number Insight. En suivant la méthodologie de l'application méthodologie de l'application à 12 facteursj'ai créé des variables d'environnement contenant la clé et le secret de l'API Nexmo ainsi que le jeton de mon projet Mixpanel.
mix = Mixpanel(os.environ['MIXPANEL_TOKEN'])
client = nexmo.Client(
key=os.environ['NEXMO_API_KEY'],
secret=os.environ['NEXMO_API_SECRET']
) Récupération et suivi des informations relatives à l'appelant
Nous allons utiliser l'API "advanced number insight" pour récupérer toutes les informations disponibles sur l'appelant. Ces informations comprendront des données telles que le pays d'où il a appelé, le type de réseau et, le cas échéant, le nom de l'appelant.
Cette information sera stockée avec le numéro de téléphone de l'utilisateur en tant qu'identifiant unique de ce dernier. De cette manière, nous pouvons relier cet événement, et tous les événements ultérieurs, au même compte d'utilisateur dans Mixpanel. Si un utilisateur existe déjà avec ce numéro de téléphone, au lieu de créer un nouveau profil d'utilisateur, Mixpanel mettra à jour son profil avec les données reçues de notre demande d'analyse du numéro, ce qui garantit qu'il est toujours à jour.
# Fetch people data
insight = client.get_advanced_number_insight(number=event['from'])
uid = event['from']
# Create/Update user in Mixpanel
mix.people_set(
uid,
{
'$phone': '+' + event['from'],
'$first_name': insight.get('first_name'),
'$last_name': insight.get('last_name'),
'Country': insight.get('country_name'),
'Country Code': insight.get('country_code_iso3'),
'Valid Number': insight.get('valid_number'),
'Reachable': insight.get('reachable'),
'Ported': insight.get('ported'),
'Roaming': insight.get('roaming').get('status'),
'Carrier Name': insight.get('current_carrier').get('name'),
'Network Type': insight.get('current_carrier').get('network_type'),
'Network Country': insight.get('current_carrier').get('country'),
}
)Nous allons également utiliser quelques autres méthodes de l'API Mixpanel people_track_charge et people_increment. Nous utiliserons ces méthodes pour suivre combien nous avons dépensé pour répondre aux appels de cet utilisateur et le nombre de fois qu'il a appelé.
# Useful for Mixpanel revenue tracking
mix.people_track_charge(uid, float(data.get('price')) * -1)
# Track number of times user calls
mix.people_increment(uid, {'Number of Calls': 1}) Envoi de notre événement d'appel entrant à Mixpanel
Enfin, nous allons suivre l'appel lui-même. Nous utiliserons à nouveau le numéro de téléphone de l'appelant comme identifiant afin d'enregistrer l'événement pour le bon utilisateur. Nous suivrons également la campagne à propos de laquelle l'appel a été effectué afin de pouvoir facilement segmenter nos données et voir les performances de chaque campagne.
# Track call data in Mixpanel
mix.track(
uid,
'Inbound Call',
{
'Campaign Name': campaign['name'],
'Duration': int(data.get('duration')),
'Start Time': data.get('start_time'),
'End Time': data.get('end_time'),
'Cost': float(data.get('price'))
}
) Essayez-le vous-même
Tout le pour cet article est disponible sur Github. Il utilise Python, Flask et tinydb. Assurez-vous donc d'installer les dépendances dans requirements.txt à l'aide de pip.
Il y a aussi un exemple campaigns.jsonIl s'agit du fichier utilisé par tinydb. Vous devrez le mettre à jour avec les valeurs correctes. Voir la documentation de documentation tinydb pour savoir comment ajouter des lignes supplémentaires à votre base de données si vous souhaitez ajouter plus d'une campagne.
![]()
Vous aurez également besoin d'un numéro virtuel Nexmo et d'une application vocale configurée. Nous avons récemment lancé notre tableau de bord des applications vocales; vous pouvez en savoir plus sur ce tableau de bord et sur la création d'une nouvelle application vocale sur notre blog.
Une fois que tout est correctement configuré, vous pouvez lancer l'application Flask à l'aide des commandes suivantes :
export FLASK_APP=app.py
flask runSi vous rencontrez des erreurs, essayez d'activer le mode de débogage dans Flask avant de réessayer. Oh, et n'oubliez pas de créer les variables d'environnement requises par les clients Mixpanel et Nexmo !
export FLASK_DEBUG=1
export MIXPANEL_TOKEN="<YOUR MIXPANEL PROJECT TOKEN>"
export NEXMO_API_KEY="<YOUR NEXMO API KEY>"
export NEXMO_API_SECRET="<YOUR NEXMO API SECRET>" Quelle est la prochaine étape ?
Essayez d'ajouter des notifications par SMS lorsqu'un appel est terminéou remplacez le suivi Mixpanel par Segment. Pour en savoir plus sur l'API Voice et l'API Number Insight utilisées dans les exemples ci-dessus, consultez notre site des développeurs. N'oubliez pas non plus de consulter les autres actions disponibles dans les NCCO.
Partager:
Aaron était défenseur des développeurs chez Nexmo. Ingénieur logiciel chevronné et artiste numérique en herbe, Aaron est souvent amené à créer des choses avec du code ou de l'électronique, parfois les deux. On peut généralement savoir qu'il travaille sur quelque chose de nouveau grâce à l'odeur de composants brûlés qui flotte dans l'air.
