https://d226lax1qjow5r.cloudfront.net/blog/blogposts/inbound-voice-call-campaign-tracking-dr/call-tracking-1.png

Verfolgung eingehender Voice-Anrufkampagnen mit Mixpanel

Zuletzt aktualisiert am May 18, 2021

Lesedauer: 9 Minuten

Kampagnenverfolgung ist ein "Muss" für jede Marketing- oder Werbekampagne. Ohne die Möglichkeit, die Anzahl der Nutzer, die sich mit jeder Werbung beschäftigen, genau zu verfolgen, können Sie Ihre Kosten pro Akquisition (CPA) nicht berechnen, so dass Sie letztendlich nicht feststellen können, welche Kampagnen erfolgreich sind und welche Ihrem Unternehmen Geld kosten; CPA größer als ARPU (Average Revenue Per User).

Could he be any more asleep?

(Bei der Business Intelligence werden noch schlimmere Akronyme und Fachausdrücke verwendet als in der Technik!)

Angesichts des großen Anteils des Internets, der durch Werbung unterstützt wird, sollte es nicht überraschen, dass die Werkzeuge für die Verwaltung von Online-Kampagnen bereits ziemlich ausgereift sind. Wenn wir jedoch "Klicks" aus Print- oder anderen Offline-Werbemitteln verfolgen wollen, müssen wir auf eindeutige Werbe-URLs oder Gutscheincodes zurückgreifen.

Nachdem der Nutzer jedoch unsere Werbe-URL oder unseren Gutscheincode eingegeben hat, können wir ihn mit denselben bewährten Business Intelligence- und Analysetools wie bei jeder anderen Online-Kampagne verfolgen.

Aber was ist mit unseren eingehenden Telefonanrufern? Diejenigen, die sich für einen Anruf bei unserem Unternehmen entscheiden, sind bereits stärker mit unserer Marke verbunden als jemand, der lediglich auf einen Link geklickt hat, aber die vorhandenen Instrumente zur Verfolgung dieser Interaktionen sind entweder fehleranfällig oder im Falle von Anrufbearbeitungsanlagen in Unternehmen unerschwinglich.

Die Nachverfolgung von eingehenden Anrufen hat die gleichen Schwierigkeiten wie URLs in Printmedien, nämlich den Sprung von analog zu digital. Wir brauchen einen eindeutigen Einstiegspunkt für jede Kampagne, etwas, das so billig und einfach einzurichten ist wie eine eindeutige URL, uns aber erlaubt, unsere Inbound Voice-Kampagnen in unserer bestehenden CRM- oder BI-Plattform zu verfolgen.

Die virtuellen Nexmo Numbers sind in dieser Situation perfekt. Sie sind billig, einfach einzurichten und wir können für jede Kampagne eine eigene virtuelle Nummer erstellen, so dass wir nachverfolgen können, wo der Nutzer jede Nummer gesehen hat und welche Kampagne letztendlich den besten ROI (Return on Investment) erzielt. Sie können auch lokale Numbers in 66 verschiedenen Ländern erwerben, so dass sie regionsspezifisch sein können, und diese Zahl steigt ständig.

Anforderungen

Wenn Sie das Beispiel lokal ausführen möchten, benötigen Sie Folgendes:

  1. a Mixpanel AccountDie kostenlose Version ist für dieses Beispiel ausreichend.

  2. eine Möglichkeit, Ihre lokale Flask-Anwendung dem öffentlichen Internet zugänglich zu machen. Ich tendiere dazu ngrok für die Entwicklung zu verwenden

Einige Kenntnisse in Python/Flask wären nützlich, sind aber nicht erforderlich. Der Code ist ziemlich einfach, so dass Sie, auch wenn Sie Ruby, PHP, JavaScript usw. bevorzugen, in der Lage sein sollten, ohne allzu große Schwierigkeiten zu folgen.

Vonage API-Konto

Um dieses Tutorial durchzuführen, benötigen Sie ein Vonage API-Konto. Wenn Sie noch keines haben, können Sie sich noch heute anmelden und mit einem kostenlosen Guthaben beginnen. Sobald Sie ein Konto haben, finden Sie Ihren API-Schlüssel und Ihr API-Geheimnis oben auf dem Vonage-API-Dashboard.

In diesem Lernprogramm wird auch eine virtuelle Telefonnummer verwendet. Um eine zu erwerben, gehen Sie zu Rufnummern > Rufnummern kaufen und suchen Sie nach einer Nummer, die Ihren Anforderungen entspricht.

Was wollen wir verfolgen?

Mindmap showing what elements we want to track

Die Inbound-Kampagne

Wir müssen wissen, welche Kampagne der Benutzer aufgerufen hat. Wir können mehrere verschiedene Kampagnen über verschiedene Kanäle laufen lassen, also müssen wir die Kampagne identifizieren, damit wir ihr alle Benutzeraktionen korrekt zuordnen können.

Der Anrufer

Idealerweise würden wir gerne ihren Namen herausfinden, aber das ist nur in bestimmten nur in bestimmten Gebieten möglich sein. Aber mit der Number Insight API sollten wir immer in der Lage sein, die Art der Nummer, von der sie anrufen, das Land, in dem sie sich befinden, und die Häufigkeit ihrer Anrufe zu ermitteln.

Indem wir ihre Telefonnummer als eindeutige Kennung verwenden, können wir ihre Handlungen auch über diesen Anruf hinaus verfolgen. Wenn wir bei der Registrierung auf unserer Website die Telefonnummer des Nutzers erfassen, können wir diese mit der Number Verify API bestätigen könnenbestätigen können, dann können wir alle zukünftigen Aktionen des Nutzers mit dem Anruf bei unserer virtuellen Nummer abgleichen.

Der Anruf

In diesem Beispiel werden wir nur die abgeschlossenen Anrufe verfolgen, aber wir könnten die die verschiedenen Anrufzustände wie Timeout, fehlgeschlagen, abgewiesen, besetzt. Weitere Informationen, die wir erfassen müssen, sind die Anrufdauer und die Kosten des Anrufs. Auf dieser Grundlage können wir die Kosten pro Akquisition unserer neuen Kunden über diese Kampagne berechnen.

Verfolgung von Inbound Voice-Kampagnen, der gesamte Prozess

process diagram showing the complete call tracking flow

Das obige Sequenzdiagramm sieht vielleicht etwas entmutigend aus, aber lassen Sie uns einen Teil nach dem anderen abarbeiten.

Beantwortung eingehender Anrufe

Wenn ein Benutzer eine virtuelle Nexmo-Nummer wählt, fordert die Nexmo-API ein Nexmo-Anrufsteuerungsobjekt (NCCO) von der von uns angegebenen URL. Diese NCCO JSON-Datei enthält eine Liste von Aktionen, die Nexmo ausführen soll, wenn ein Anruf eingeht.

Die Die erste Aktion, die wir durchführen wollen, ist das Streamen einer mp3 an den Anrufer zu übertragen; diese Tondatei informiert ihn darüber, dass wir den Anruf aufzeichnen können.

[
  {
    "action": "stream", 
    "streamUrl": [
      "https://example.com/audio/calls-recorded.mp3"
    ]
  }
]

Aufzeichnen und Verbinden des Anrufs mit unserem Agenten

Im zweiten Teil des Sequenzdiagramms beginnen wir mit der Aufzeichnung unseres Anrufs und verbinden wir den Anrufer mit dem Agenten, der die Anrufe für diese Kampagne bearbeitet.

[
  {
    "action": "stream", 
    "streamUrl": [
      "https://example.com/audio/calls-recorded.mp3"
    ]
  }, 
  {
    "action": "record", 
    "eventUrl": [
      "https://example.com/record/"
    ]
  }
]

Die Website Aufzeichnungsvorgang in der NCCO ist einfach zu handhaben. Wir müssen nur die URL angeben, die eine Benachrichtigung erhalten soll, wenn die Aufzeichnung des Anrufs verfügbar ist. Wenn der Anruf beendet ist, wird die Aufzeichnung automatisch gestoppt.

Verbinden des Anrufs

Wenn Sie die Aktion "Verbinden" verwenden, muss die Absendernummer eine virtuelle Nexmo-Nummer sein. In diesem Fall verwenden wir die Nummer für die eingehende Voice-Kampagne, die der Benutzer anruft.

[
  {
    "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"
  }
]

Sie können verschiedene Arten von Endpunkten für die Verbindung angeben, z. B. einen WebSocketDa wir jedoch einen Proxy-Anruf tätigen wollen, verwenden wir den Typ "Telefon" und dann die Nummer, mit der wir uns verbinden wollen.

Erstellen unserer ersten Flask-Ansicht

Im obigen Beispiel der NCCOs sind alle unsere Werte fest codiert. In einer realen Situation werden sich jedoch viele der Werte ändern, je nachdem, welche virtuelle Nummer der Benutzer gewählt hat. Wir müssen zunächst die Kampagne identifizieren, wegen der der Anrufer anruft, und dann den Speicherort der mp3-Datei und die Telefonnummer des eingehenden Agenten aktualisieren.

Wir müssen auch den Fall berücksichtigen, dass wir keine aktive Kampagne für eine Nummer haben. Vielleicht handelt es sich um eine ältere Werbung, und die Marketingkampagne läuft nicht mehr. Möglicherweise haben wir keine Agenten zur Verfügung, die Anrufe zu dieser Kampagne entgegennehmen können, aber wir wollen die virtuelle Nummer nicht freigeben. In unserem Beispielcode werden wir die Text-to-Speech-Aktion verwenden, um den Benutzer darüber zu informieren, dass die Nummer nicht mehr aktiv ist. In Ihrer Live-Anwendung könnten Sie den Benutzer jedoch an Ihre Hauptvermittlungsstelle weiterleiten oder eine andere Aktion durchführen, die eine bessere Benutzererfahrung bietet.

Schauen wir uns zunächst an, wie wir die betreffende Kampagne finden würden.

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)

Wir verwenden tinydb in unserem Beispiel; es ist eine einfache Datenbank-Engine für Python, die für eingebettete Systeme entwickelt wurde. Sie ist perfekt für unser Beispiel, da sie sich auf eine einzige flache (JSON-)Datei als Datenbank stützt, aber Sie könnten sie leicht gegen SQLAlchemy oder eine andere ORM Ihrer Wahl austauschen.

Wenn Nexmo unseren NCCO anfordert, enthält er die angerufene Nummer im E.164 internationales Format als Teil des Abfrage-Strings. Wir verwenden diese Nummer, wenn wir unsere Datenbank nach der entsprechenden Kampagne abfragen. Sie müssen also sicherstellen, dass Sie auch das E.164-Format verwenden, wenn Sie Ihre Kampagneninformationen in Ihrer Datenbank speichern.

Unsere get_campaign Funktion gibt die erste übereinstimmende Kampagne zurück, oder wenn keine gefunden wird, geben wir None.

Beantwortung mit unserem Nexmo Call Control Objekt

Wenn es uns gelungen ist, in den obigen Schritten eine passende Kampagne zu finden, werden wir unser NCCO mit den richtigen streamUrl, from Nummer und endpoint. Wenn wir keine passende Kampagne finden, verwenden wir die Text-to-Speech-API und eine synthetische Stimme, um den Benutzer zu informieren; 'Die gewählte Nummer wurde nicht erkannt.

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'
    }])

Verfolgung der Informationen über eingehende Anrufe

Nach Beendigung des Anrufs wird nicht nur die Aufzeichnung beendet, sondern Nexmo wird auch unseren Webhook mit den relevanten Informationen auslösen.

Dieses abgeschlossene Ereignis enthält jedoch keine Informationen über den Benutzer, der den Anruf getätigt hat. Hierfür müssen wir die Nexmo number insight API.

Nachdem wir alle Informationen haben, die wir brauchen - welche Kampagne sie angerufen haben, wer es war, der angerufen hat, und Informationen über den Anruf selbst -, speichern wir diese Informationen in Mixpanel.

Wir verwenden in diesem Beispiel Mixpanel, aber das bedeutet nicht, dass Sie nur Mixpanel verwenden können. Senden Sie die Daten an jedes beliebige Tool, oder an mehrere Applications gleichzeitig mit einem Tool wie Segment. Es spielt keine Rolle, ob Sie Mixpanel, KISSmetrics, Periscope, Chartio, Salesforce oder sogar ein maßgeschneidertes BI- oder CRM-System verwenden. Wenn es Daten empfangen kann, können Sie den gleichen Ansatz verwenden, um Ihre eingehenden Anrufe zu verfolgen.

@app.route('/event', methods=['POST'])
def callevent():
    event = json.loads(request.data)

    if event['status'] == 'completed':
        campaign = get_campaign(event['to'])

Zunächst einmal legen wir fest, dass dieser Endpunkt nur POST Anfragen akzeptiert, da dies die Anfragen sind, die wir von Nexmo erhalten werden. Der Körper dieser POST Anfrage wird ein JSON-String sein, den wir in ein Python-Objekt umwandeln müssen.

Wie bereits erwähnt, sind wir in diesem Beispiel nur an Aufrufen interessiert, die den Status "abgeschlossen" haben. Es gibt viele andere Zustände die wir erhalten könnten, wie z. B. "besetzt" oder "fehlgeschlagen", und diese Status könnten sehr wichtig sein, wenn Sie z. B. eine Software schreiben würden, um eingehende Support-Anrufe zu verfolgen. Aber im Moment wollen wir uns nur auf die abgeschlossenen Anrufe konzentrieren.

Wir werden auch nur Anfragen für bestehende Kampagnen verfolgen. Bevor wir also etwas anderes tun, verwenden wir unsere get_campaign Funktion verwenden und prüfen, ob der Benutzer eine aktive Kampagne angefordert hat.

Erstellung unserer Mixpanel- und Nexmo-Kunden

Um Informationen über unseren Aufrufer zu erhalten, benötigen wir eine Instanz des Nexmo API-Client damit wir die Number Insight API verwenden können. Gemäß der 12-Faktoren-App-Methodehabe ich Umgebungsvariablen erstellt, die meinen Nexmo-API-Schlüssel und -Geheimnis sowie das Token für mein Mixpanel-Projekt enthalten.

mix = Mixpanel(os.environ['MIXPANEL_TOKEN'])
client = nexmo.Client(
    key=os.environ['NEXMO_API_KEY'],
    secret=os.environ['NEXMO_API_SECRET']
)

Abrufen und Verfolgen von Informationen über unseren Anrufer

Wir werden die erweiterte Number Insight API verwenden, um alle verfügbaren Informationen über den Anrufer abzurufen. Zu diesen Informationen gehören Daten wie das Land, aus dem der Anrufer angerufen hat, der Netztyp und, sofern verfügbar, der Name des Anrufers.

Wir speichern diese Informationen zusammen mit der Telefonnummer als eindeutigen Identifikator für den Nutzer. Auf diese Weise können wir dieses Ereignis und alle nachfolgenden Ereignisse mit demselben Benutzerkonto in Mixpanel verknüpfen. Wenn es bereits einen Nutzer mit dieser Telefonnummer gibt, erstellt Mixpanel kein neues Nutzerprofil, sondern aktualisiert das Profil mit den Daten, die wir von unserer Anfrage zur Einsicht in die Telefonnummer erhalten haben, um sicherzustellen, dass es immer aktuell ist.

# 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'),
    }
)

Wir werden auch ein paar andere Mixpanel API-Methoden verwenden people_track_charge und people_increment. Wir werden diese Methoden verwenden, um zu verfolgen, wie viel wir für die Beantwortung von Anrufen dieses Nutzers ausgegeben haben und wie oft er angerufen hat.

# 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})

Senden des Ereignisses "Eingehender Anruf" an Mixpanel

Schließlich werden wir den eigentlichen Anruf verfolgen. Wir verwenden wieder die Telefonnummer des Anrufers als Kennung, damit wir das Ereignis dem richtigen Nutzer zuordnen können. Wir werden auch verfolgen, wegen welcher Kampagne der Anrufer angerufen hat, damit wir unsere Daten leicht segmentieren können, um zu sehen, wie gut die einzelnen Kampagnen funktionieren.

# 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'))
    }
)

Probieren Sie es selbst aus

Der gesamte Code für diesen Artikel ist auf Github verfügbar. Er verwendet Python, Flask und tinydb. Stellen Sie also sicher, dass Sie die Abhängigkeiten in requirements.txt zuerst mit pip installieren.

Es gibt auch ein Beispiel campaigns.jsonDies ist die Datei, die von tinydb verwendet wird. Sie müssen sie mit den richtigen Werten aktualisieren. Siehe die tinydb-Dokumentation erfahren Sie, wie Sie zusätzliche Zeilen zu Ihrer Datenbank hinzufügen können, wenn Sie mehr als eine Kampagne hinzufügen möchten.

Nexmo application creation screen

Sie benötigen außerdem eine virtuelle Nexmo-Nummer und eine konfigurierte Sprachanwendung. Wir haben kürzlich unser Dashboard für Voice-Anwendungen; Sie können mehr darüber lesen und wie man eine neue Voice-Anwendung erstellt in unserem Blog.

Wenn Sie alles richtig eingerichtet haben, können Sie die Flask-Anwendung mit den folgenden Befehlen ausführen:

export FLASK_APP=app.py
flask run

Wenn Sie auf Fehler stoßen, versuchen Sie, den Debug-Modus in Flask einzuschalten, bevor Sie es erneut versuchen. Oh, und vergessen Sie nicht, die Umgebungsvariablen zu erstellen, die von den Mixpanel- und Nexmo-Clients benötigt werden!

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>"

Was kommt als Nächstes?

Versuchen Sie, Folgendes hinzuzufügen SMS-Benachrichtigungen bei Beendigung eines Anrufsoder tauschen Sie das Mixpanel-Tracking gegen Segment aus. Weitere Informationen über die Voice API und die Number Insight API, die in den obigen Beispielen verwendet wurden, finden Sie auf unserer Entwickler-Website. Sehen Sie sich auch die anderen in NCCOs verfügbaren Aktionen.

Teilen Sie:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Aaron BassettVonage Ehemalige

Aaron war ein Entwickler-Befürworter bei Nexmo. Aaron ist ein erfahrener Software-Ingenieur und Möchtegern-Digitalkünstler, der häufig Dinge mit Code oder Elektronik entwickelt, manchmal auch beides. Wenn er an etwas Neuem arbeitet, erkennt man das in der Regel am Geruch von brennenden Bauteilen in der Luft.