https://d226lax1qjow5r.cloudfront.net/blog/blogposts/pycascades-code-of-conduct-hotline-nexmo-voice-api-dr/PyCascades-CoC-Hotline.png

Erweiterung der PyCascades Code of Conduct Hotline mit Nexmo Voice API

Zuletzt aktualisiert am May 4, 2021

Lesedauer: 10 Minuten

Hallo, mein Name ist Mariatta. Ich arbeite als Platform Engineer bei Zapier .. Ich bin ein Python Core Developer und helfe auch bei der Organisation der PyCascades Konferenz.

Bei PyCascades, Vielfalt in unserer Gemeinschaft eine Priorität und nicht ein nachträglicher Gedanke. Wir versuchen dies unter anderem durch einen strengen Verhaltenskodex und dessen Durchsetzung zu erreichen. Um die Meldung von Problemen mit dem Verhaltenskodex zu erleichtern, hat Alan Vezina, einer unserer Organisatoren, eine Verhaltenskodex (CoC)-Hotline. Die Hotline wurde inzwischen von der PyCon US 2018 und der DjangoCon 2018 übernommen.

So funktioniert die erste PyCascades CoC-Hotline. Wenn jemand ein Problem mit dem Verhaltenskodex melden möchte, kann er die Hotline-Nummer anrufen. Zu diesem Zeitpunkt werden alle unsere Organisatoren benachrichtigt, und der Anrufer wird dann mit dem ersten Organisator verbunden, der antwortet. Aus Gründen der Rechenschaftspflicht werden die Informationen über den Anruf auch in einem Slack-Kanal gepostet, damit wir eine Aufzeichnung des Anrufs haben.

Seit dem Start der Hotline habe ich mir Gedanken darüber gemacht, wie die Hotline im kommenden Jahr verbessert werden kann.

In diesem Blogbeitrag zeige ich Ihnen, wie ich Nexmo Voice API und Zapier verwendet habe, um die PyCascades Code of Conduct Hotline zu verbessern.

Dies sind die Merkmale der erweiterten Hotline:

  • Der Anrufer wird begrüßt und darüber informiert, dass er die PyCascades Code of Conduct Hotline erreicht hat. Es ist wichtig, dass der Anrufer weiß, dass er die richtige Nummer erreicht hat, nämlich die offizielle PyCascades Code of Conduct Hotline.

  • Alle Anrufe werden automatisch aufgezeichnet. Die Berichterstattung über den Verhaltenskodex ist eine wichtige und sensible Angelegenheit. Eine Aufzeichnung hilft uns dabei, die Verantwortung zu behalten, und ermöglicht es uns, das Gespräch noch einmal abzuspielen, damit wir keine Details verpassen.

  • Während der Anrufer darauf wartet, mit einem unserer Mitarbeiter verbunden zu werden, wird nun Wartemusik abgespielt.

  • Wenn ein Organisator den Anruf entgegennimmt, hört der Anrufer eine Nachricht, die den Organisator identifiziert: "Mariatta nimmt an diesem Gespräch teil."

  • Wir haben einen Warnhinweis hinzugefügt, um den Organisator darauf hinzuweisen, dass dieser Anruf den PyCascades-Verhaltenskodex betrifft. Ich kontrolliere meine Anrufe. Ich ignoriere oft Anrufe von 1-800 Numbers oder unbekannten Anrufen, deren Nummer ich nicht kenne. Während der Konferenz muss ich wissen, ob es bei diesen Anrufen um Fragen zum Verhaltenskodex geht (was ich annehmen sollte) oder ob es sich um einen Telemarketing-Anruf handelt, bei dem mir eine kostenlose Kreuzfahrt angeboten wird (was ich ignorieren werde).

  • Ein Buch über alle CoC-Anrufe wird jetzt in Google Spreadsheets geführt.

Darüber hinaus muss die folgende Funktion noch funktionieren:

  • Informationen über eingehende Anrufe bei der CoC-Hotline werden auf Slack gepostet. Slack ist eines der wichtigsten Kommunikationsmittel der PyCascades-Organisatoren. Die Slack-Nachricht dient sowohl als Benachrichtigung als auch als Aufzeichnung, dass ein Anruf stattgefunden hat, auch wenn niemand geantwortet hat.

Sonstige technische Informationen:

Die Hotline ist in Python geschrieben, und mein Web-Framework der Wahl ist aiohttpein asynchrones Webserver- und Client-Framework für Python. Ich habe aiohttp verwendet, um GitHub-Bots wie miss-islington und Stromausfall.

Der Webdienst wird auf Heroku bereitgestellt. Der größte Teil der Webinfrastruktur der PSF wird auf Heroku gehostet. Als Python-Kernentwickler bin ich daher mit Heroku vertrauter als mit anderen Arten von Cloud-Infrastrukturen.

Einer der Hauptgründe für die Wahl von Nexmo API ist für mich, dass Nexmo die Python-Gemeinschaft in vielerlei Hinsicht unterstützt hat, einschließlich des Sponsorings der PyCon US 2018, der DjangoCon 2018 und der ersten PyCascades ? Ein weiterer Grund für die Wahl von Nexmo API ist, dass die nexmo-python-Bibliothek als Open Source verfügbar ist und mit den neueren Python-Versionen kompatibel ist und gegen Python 3.7 getestet wurde.

Sie können sich den Quellcode der Erweiterten CoC-Hotline.

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.

Nexmo Voice App Einrichtung

Zunächst möchte ich Ihnen zeigen, wie meine Nexmo Voice Anwendung eingerichtet ist.

Nexmo Voice App settings screenshotNexmo voice app settings

Wenn Sie eine Voice-Anwendung in Nexmo einrichten, müssen Sie zwei Webhook-URLs konfigurieren, eine Ereignis-URL und eine Antwort-URL.

Die Ereignis-URL ist immer erforderlich; an diese Adresse sendet Nexmo Informationen, wenn sich der Status des Anrufs ändert.

Empfang des Webhooks für Ereignisse und Protokollierung der Aktivitäten

Im Folgenden finden Sie ein Beispiel für eine Nutzlast, die vom Ereignis-Webhook übermittelt wird:

{
    "status": "started",
    "direction": "outbound",
    "from": "12025550124",
    "uuid": "80c80c80-80ce-80c8-80c8-80c80c80c80c",
    "conversation_uuid": "CON-be2be2be-a0dd-a0dd-a0dd-34b34b34b34b",
    "timestamp": "2018-10-25T17:42:17.552Z",
    "to": "12025550124"
}

Sie enthält Informationen wie die Nummer des Anrufers, die gewählte Nummer, den Status des Anrufs, den Zeitstempel und eindeutige Anruf- und Gesprächskennungen. Dies sind alles nützliche Informationen, die protokolliert werden können, damit wir Aufzeichnungen über jede Aktivität haben.

Anstatt meinen eigenen Webdienst zu erstellen, um diese Webhooks zu empfangen, habe ich eine Zapier-Integration erstellt. Eine der Integrationen, die Sie in Zapier verwenden können, ist Webhooks von Zapier. Mit Webhooks von Zapier können Sie Daten von jedem Dienst empfangen oder Anfragen an jede URL senden, ohne Code zu schreiben oder Server zu betreiben. Mit anderen Worten: Sie können Webhooks empfangen und senden.

Als ich einen neuen Zap mit Webhooks von Zapier als Auslöseaktion erstellt habe, hat Zapier eine URL "hooks.zapier.com" generiert, die ich für den Empfang der Webhooks verwenden kann. Ich habe die URL hooks.zapier.com als Ereignis-URL in Nexmo Voice Application angegeben.

Webhook Trigger ScreenshotWebhook Trigger

Jetzt, wo ich Zapier so eingerichtet habe, dass es den Event-Webhook von Nexmo empfängt, kann ich viele Dinge tun. Zunächst habe ich eine Slack-Integration hinzugefügt, so dass automatisch eine Nachricht in unserem privaten CoC-Kanal über eingehende Anrufe bei der Hotline gepostet wird. Als Nächstes habe ich eine Google Sheets-Integration hinzugefügt, so dass alle Aktivitäten im Zusammenhang mit der Hotline automatisch als neue Zeile in Google Sheets hinzugefügt werden.

CoC Events screenshotCoC Events

Beantwortung von Anrufen

Wenn ein Anrufer die Nummer der Hotline wählt, sendet Nexmo den Payload dieses Ereignisses an die Answer URL. Die Antwort-URL muss ein NCCO (Nexmo Anrufsteuerungsobjekt) zurückgeben, das diesen Anruf steuert.

Die Antwort-URL wird auf die URL meines Webservice gesetzt /webhook/answer/ URL. (Quellcode)

Ich wollte, dass der Anrufer begrüßt wird und weiß, dass er die PyCascades Code of Conduct Hotline erreicht hat. Daher ist der erste NCCO, den ich zurückgegeben habe, eine "Sprech"-Aktion:

ncco = [
        {
            "action": "talk",
            "text": "You've reached the PyCascades Code of Conduct Hotline. This call is recorded."
        }
    ]

Da ich jetzt Ereignisse erhalte, wenn ein Anrufer die Hotline gewählt hat, muss ich als Nächstes alle unsere Mitarbeiter anrufen und sie mit demselben Anruf verbinden. Dazu muss ich den Anrufer und die Mitarbeiter in eine Telefonkonferenz einbinden.

Um Anrufer zu einer Telefonkonferenz hinzuzufügen, füge ich eine NCCO-Aktion "Gespräch" mit demselben Namen hinzu.

{
            "action": "conversation",
            "name": conversation name,
}

Muss ich mir also einen "Namen" für das Gespräch ausdenken? Nicht unbedingt. Werfen Sie einen Blick auf die Nutzdaten, die die Antwort-URL liefert

Ein Beispiel für eine GET-Anfrage an die answer_url lautet wie folgt:

/webhooks/answer?to=447700900000&from=447700900001&conversation_uuid=CON-aaaaaaaa-bbbb-cccc-dddd-0123456789ab&uuid=aaaaaaaa-bbbb-cccc-dddd-0123456789cd

Beachten Sie, dass die Nutzlast eine conversation_uuid. Anstatt neue Namen für die Konversation zu "erfinden", habe ich mich entschieden, denselben conversation_uuid als Konversationsnamen zu verwenden.

Also habe ich die conversation_uuid aus der Anfrage abgerufen und in der NCCO verwendet.

conversation_uuid = request.rel_url.query["conversation_uuid"].strip()
    ...
    {
            "action": "conversation",
            "name": conversation_uuid,
            ...
    }

Um das Gespräch aufzuzeichnen, kann ich "record": True im NCCO-Wörterbuch der Unterhaltung angeben. Wenn die Aufzeichnung endet, sendet Nexmo auch einen Webhook an den eventUrlDer Payload dieses Webhooks enthält die URL, unter der die Aufzeichnung gespeichert ist.

Nachfolgend ein Beispiel für den Payload der Aufzeichnung eventUrl Webhook:

{
  "start_time": "2020-01-01T12:00:00Z",
  "recording_url": "https://api.nexmo.com/media/download?id=aaaaaaaa-bbbb-cccc-dddd-0123456789ab",
  "size": 12345,
  "recording_uuid": "aaaaaaaa-bbbb-cccc-dddd-0123456789ab",
  "end_time": "2020-01-01T12:01:00Z",
  "conversation_uuid": "bbbbbbbb-cccc-dddd-eeee-0123456789ab",
  "timestamp": "2020-01-01T14:00:00.000Z"
}

Auch hier habe ich, anstatt meinen eigenen Webdienst für den Empfang des Webhooks zu konfigurieren, die Webhooks von Zapier verwendet. Ich habe einen anderen Zap für den Empfang der Aufzeichnungs-Webhooks erstellt.

Recording Zapier screenshotZapier Recording

In diesem Zap habe ich eine Google Spreadsheet-Integration hinzugefügt, so dass die Informationen aus der Nutzlast, einschließlich der recording_urlautomatisch als eine neue Zeile in Google Spreadsheets hinzugefügt werden. Außerdem habe ich eine Slack-Integration hinzugefügt, damit unsere Mitarbeiter über die neue Aufnahme benachrichtigt werden.

Zu diesem Zeitpunkt sieht das Gespräch NCCO wie folgt aus:

conversation_uuid = request.rel_url.query["conversation_uuid"].strip()
    ...
    {
            "action": "conversation",
            "name": conversation_uuid,
            "record": True,
            "eventUrl": [os.environ.get("ZAPIER_CATCH_HOOK_RECORDING_FINISHED_URL")],

            ...
    }

Zu diesem Zeitpunkt muss die Hotline zwei Dinge tun. Erstens muss sie jeden Mitarbeiter anrufen, damit ich sie dem Gespräch hinzufügen kann. Und zweitens muss sie Musik abspielen, während der Anrufer darauf wartet, verbunden zu werden.

Musik abspielen, während der Anrufer wartet

Das Abspielen von Musik in diesem Anruf ist ganz einfach. Fügen Sie das "musicOnHoldURL" zum NCCO hinzu, und geben Sie eine URL für die abzuspielende Musik an, zum Beispiel:

"musicOnHoldUrl": ["https://..../music.mp3"]

Ich verwende die Musik aus der Musiksammlung von Wistiaund zwar aus den Let 'Em In Sessions. Sie können die Lizenz für diese Musik hier.

import random
    
    MUSIC_WHILE_YOU_WAIT = [
        "https://assets.ctfassets.net/j7pfe8y48ry3/530pLnJVZmiUu8mkEgIMm2/dd33d28ab6af9a2d32681ae80004886e/oaklawn-dreams.mp3",
        "https://assets.ctfassets.net/j7pfe8y48ry3/2toXv1xuOsMm0Yku0YEGya/a792ce81a7866fc77f6768d416018012/broken-shovel.mp3",
        "https://assets.ctfassets.net/j7pfe8y48ry3/16VJzaewWsKWg4GsSUiwGi/9b715be5e8c850e46de98b64e6d31141/lennys-song.mp3",
        "https://assets.ctfassets.net/j7pfe8y48ry3/1qApZVYkxaiayA6aysGAOo/8983586c8ab4db8b69490718469a12f5/new-juno.mp3",
        "https://assets.ctfassets.net/j7pfe8y48ry3/6iXXKtJCp2oCMiGmsmAKqu/8163a8fe863405292ba3609193593add/davis-square-shuffle.mp3",
    ]
    
    ncco = {
        ...
        "musicOnHoldUrl": [random.choice(MUSIC_WHILE_YOU_WAIT)],
    }

Rufen Sie die anderen Mitarbeiter zu der Telefonkonferenz auf

Jetzt muss ich alle Mitarbeiter anrufen und sie zu diesem Anruf hinzufügen.

Das ist etwas, was ich im NCCO nicht erreichen kann. Deshalb habe ich den Nexmo Python-Client Bibliothek. Sie kann installiert werden mit pipinstalliert werden, also fügte ich nexmo zu meiner Datei requirements.txt hinzugefügt.

Ich habe eine Hilfsfunktion für die Instanziierung des Clients erstellt.

def get_nexmo_client():
        app_id = os.environ.get("NEXMO_APP_ID")
        private_key = os.environ.get("NEXMO_PRIVATE_KEY_VOICE_APP")
    
        client = nexmo.Client(application_id=app_id, private_key=private_key)
        return client

Ich habe auch eine Hilfsfunktion zum Abrufen der Telefonnummern der Mitarbeiter erstellt. Die Telefonnummern werden in Heroku als Umgebungsvariablen im folgenden Format gespeichert:

[
            {
                "name": "Mariatta",
                "phone": "12025550124"
            },
            {
                "name": "Miss Islington",
                "phone": "12025550123"
            }
        ]

Die Hilfsfunktion ist recht einfach:

import json
    
    def get_phone_numbers():
        return json.loads(os.environ.get("PHONE_NUMBERS"))

Nun, da ich Funktionen zum Abrufen des Nexmo-Clients sowie die zu wählenden Telefonnummern habe, kann ich die Nummern wählen.

Um eine Nummer mit der Nexmo Python Client-Bibliothek anzurufen:

response = client.create_call({
      'to': [{'type': 'phone', 'number': 12025550124}],
      'from': {'type': 'phone', 'number': 12025550123},
      'answer_url': ['https://example.com/answer']
    })

In der create_call Call-Methode musste ich die to Rufnummer sowie die from Rufnummer. Die to Telefonnummer ist die Telefonnummer des Personals, das ich anrufen möchte.

Für die from Nummer habe ich nicht die Telefonnummer des Anrufers der Hotline angegeben, sondern die hotline Nummer selbst; so weiß das Personal durch Lesen der Anrufer-ID, dass der Anruf von der Hotline kommt.

Was ist mit dem answer_url? Die answer_url ist der Webhook für den Fall, dass ein Mitarbeiter diesen Anruf entgegennimmt. Das gewünschte Verhalten ist, dass der Mitarbeiter, der den Anruf entgegengenommen hat, zu der Konversation hinzugefügt wird, in der sich der Anrufer der Hotline befindet. Daher muss ich zusätzlich zu dem von Nexmo bereitgestellten Payload für den Webhook das conversation_name (das ist die conversation_uuid).

Ich habe einen neuen Endpunkt in meinem Webdienst erstellt, um diesen Webhook zu behandeln, indem ich sowohl die conversation_uuid und den Aufruf uuid zu in die URL einfügte:

@routes.get(
        "/webhook/answer_conference_call/{origin_conversation_uuid}/{origin_call_uuid}/"
    )
    async def answer_conference_call(request):
    
        origin_conversation_uuid = request.match_info["origin_conversation_uuid"]
        origin_call_uuid = request.match_info["origin_call_uuid"]
        ...

Wenn ich diesen Endpunkt erstellt habe, kann ich jedes Mal, wenn ein Mitarbeiter einen Anruf von der Hotline entgegennimmt, herausfinden, zu welchem Gespräch ich ihn hinzufügen soll.

Schließlich sieht der Antwort-Webhook wie folgt aus:

@routes.get("/webhook/answer/")
async def answer_call(request):
    conversation_uuid = request.rel_url.query["conversation_uuid"].strip()
    call_uuid = request.rel_url.query["uuid"].strip()

    ncco = [
        {
            "action": "talk",
            "text": "You've reached the PyCascades Code of Conduct Hotline. This call is recorded.",
        },
        {
            "action": "conversation",
            "name": conversation_uuid,
            "record": True,
            "eventMethod": "POST",
            "musicOnHoldUrl": [random.choice(MUSIC_WHILE_YOU_WAIT)],
            "eventUrl": [os.environ.get("ZAPIER_CATCH_HOOK_RECORDING_FINISHED_URL")],
            "endOnExit": False,
            "startOnEnter": False,
        },
    ]

    client = get_nexmo_client()
    phone_numbers = get_phone_numbers()

    for phone_number_dict in phone_numbers:
        client.create_call(
            {
                "to": [{"type": "phone", "number": phone_number_dict["phone"]}],
                "from": {
                    "type": "phone",
                    "number": os.environ.get("NEXMO_HOTLINE_NUMBER"),
                },
                "answer_url": [
                    f"https://mariatta-enhanced-coc.herokuapp.com/webhook/answer_conference_call/{conversation_uuid}/{call_uuid}/"
                ],
            }
        )
    return web.json_response(ncco)

Hinzufügen von Mitarbeitern zur Telefonkonferenz

Der answer_conference_call Endpunkt wurde mit dem Ziel erstellt, die Mitarbeiter zu der Telefonkonferenz hinzuzufügen. Um dies zu erreichen, musste ich einen NCCO an den Webhook zurückgeben, der eine Aktion "Gespräch" und den Namen des Gesprächs enthält. Bevor sie jedoch hinzugefügt werden, möchte ich die Mitarbeiter begrüßen, damit sie wissen, dass sie an der PyCascades Code of Conduct Hotline teilnehmen.

Erinnern Sie sich, dass die PHONE_NUMBERS Umgebungsvariable auch die Namen der Telefonnummernbesitzer enthält.

Ich habe die folgende Funktion erstellt, um den Namen des Eigentümers der Telefonnummer abzurufen:

def get_phone_number_owner(phone_number):
        phone_numbers = get_phone_numbers()
        for phone_number_info in phone_numbers:
            if phone_number_info["phone"] == phone_number:
                return phone_number_info["name"]
    
        return None

Mit dieser Funktion kann ich das Personal wie folgt begrüßen:

@routes.get(
        "/webhook/answer_conference_call/{origin_conversation_uuid}/{origin_call_uuid}/"
    )
    async def answer_conference_call(request):
    
        to_phone_number = request.rel_url.query["to"]
        origin_conversation_uuid = request.match_info["origin_conversation_uuid"]
    
        phone_number_owner = get_phone_number_owner(to_phone_number)
    
        ncco = [
            {
                "action": "talk",
                "text": f"Hello {phone_number_owner}, connecting you to PyCascades hotline.",
            },
            {
                "action": "conversation",
                "name": origin_conversation_uuid,
                "startOnEnter": True,
                "endOnExit": True,
            },
        ]
        return web.json_response(ncco)

Jetzt fragen Sie sich vielleicht, wofür der origin_call_uuid verwendet wird. Ich dachte mir, dass es eine nette Gefälligkeit sein könnte, den Anrufer wissen zu lassen, welches Mitglied des PyCascades-Teams den Anruf entgegennimmt. Bedenken Sie auch, dass es sich um eine Telefonkonferenz handelt, so dass möglicherweise mehr als eine Person teilnehmen kann. Anstatt jemanden stillschweigend beitreten zu lassen, gebe ich eine Vorwarnung an alle Teilnehmer, wer gerade beigetreten ist.

client = get_nexmo_client()

    response = client.send_speech(
        origin_call_uuid, text=f"{phone_number_owner} is joining this call."
    )

Jetzt sieht der answer_conference_call Endpunkt wie folgt aus:

@routes.get(
        "/webhook/answer_conference_call/{origin_conversation_uuid}/{origin_call_uuid}/"
    )
    async def answer_conference_call(request):

        to_phone_number = request.rel_url.query["to"]
        origin_conversation_uuid = request.match_info["origin_conversation_uuid"]
        origin_call_uuid = request.match_info["origin_call_uuid"]
    
        phone_number_owner = get_phone_number_owner(to_phone_number)
        client = get_nexmo_client()
    
        try:
            response = client.send_speech(
                origin_call_uuid, text=f"{phone_number_owner} is joining this call."
            )
        except nexmo.Error as er:
            print(
                f"error sending speech to {origin_call_uuid}, owner is {phone_number_owner}"
            )
            print(er)
    
        else:
            print(f"Successfully notified caller. {response}")
    
        ncco = [
            {
                "action": "talk",
                "text": f"Hello {phone_number_owner}, connecting you to PyCascades hotline.",
            },
            {
                "action": "conversation",
                "name": origin_conversation_uuid,
                "startOnEnter": True,
                "endOnExit": True,
            },
        ]
        return web.json_response(ncco)

Der abgeschlossene Anrufablauf

Damit ist der erweiterte PyCascades-Verhaltenskodex abgeschlossen.

Der vollständige Anrufablauf sieht wie folgt aus:

  • Ein Anrufer wählt die Hotline an.

  • Die Mitarbeiter von PyCascades erhalten eine Slack-Benachrichtigung, dass ein Anruf bei der Hotline eingegangen ist.

  • Die Informationen über den Anruf werden in Google Sheets eingetragen.

  • Der Anrufer hört eine Nachricht: "Willkommen bei der PyCascades Code of Conduct Hotline. Dieser Anruf wird aufgezeichnet."

  • Der Anrufer hört Musik, während er darauf wartet, verbunden zu werden.

  • Jeder PyCascades-Mitarbeiter erhält einen Anruf von der Hotline.

  • Ein PyCascades-Mitarbeiter nimmt den Anruf entgegen und hört: "Hallo {Mitarbeitername}, ich verbinde Sie mit der PyCascades-Hotline."

  • In der Zwischenzeit hört der Anrufer die Nachricht "{Mitarbeitername} nimmt an diesem Anruf teil".

  • Mitarbeiter und Anrufer setzen das Gespräch fort.

  • Das Personal legt auf, woraufhin die Aufzeichnung des Anrufs beendet wird.

  • Die Mitarbeiter erhalten eine Slack-Benachrichtigung, dass es eine neue Aufzeichnung gibt.

  • Die Informationen über die Aufzeichnung werden auch in Google Sheets hinzugefügt.

Herunterladen der Aufzeichnung

Die Aufzeichnung kann mit dem Nexmo Python-Client heruntergeladen werden, und die recording_url ist die im Webhook der Aufzeichnungsereignisse empfangene URL.

client = get_nexmo_client()
    recording = client.get_recording(recording_url)

Anrufaufzeichnungen werden in Nexmo einen Monat lang gespeichert, bevor sie automatisch gelöscht werden. Da diese Anrufe wichtig sind und wir die Aufzeichnungen nicht verlieren wollen, habe ich ein Kommandozeilenskript erstellt, das verwendet werden kann, um Herunterladen der Aufzeichnungen.

Das Skript kann wie folgt ausgeführt werden:

python3 -m download_recording url1 url2 url3 ...

Sobald das Skript ausgeführt wird, werden die Aufnahmen heruntergeladen und lokal im recording Verzeichnis gespeichert.

Schlussfolgerungen

Dank Nexmo und Zapier bin ich in der Lage, die PyCascades Code of Conduct Hotline zu verbessern. Das Einrichten dieser Hotline scheint komplizierter zu sein als vor.

Ich glaube jedoch, dass die neuen Verbesserungen wie die automatische Aufzeichnung und Protokollierung in Google Spreadsheets für alle unsere Mitarbeiter nützlich sind, weshalb ich bereit bin, die zusätzliche Zeit zu investieren, um dies für PyCascades einzurichten. Außerdem können wir durch die Verwendung von Zapier anstelle von Hardcoding flexibler sein, falls wir zusätzliche Integrationen hinzufügen möchten.

Vielen Dank fürs Lesen! Wenn Sie weitere Fragen zur Hotline, PyCascades oder Zapier haben, zögern Sie bitte nicht, mir eine E-Mail an mariatta.wijaya@zapier.com zu schicken.


Anmerkung von Nexmo Developer Relations: Wir freuen uns sehr, dass Mariatta sich entschieden hat, Nexmo zu nutzen, um die Berichterstattung über den PyCascades Code of Conduct zu verbessern. Wir glauben, dass ein Verhaltenskodex ein wichtiger Bestandteil ist, um einen einladenden und inklusiven Raum zu schaffen. Wir würden gerne jede Konferenz oder jedes Treffen unterstützen, das eine Verhaltenskodex-Hotline einrichten möchte. Wenn Sie ein Veranstalter sind und Mariattas Verhaltenskodex-Hotline für Ihre Veranstaltung nutzen möchten, wenden Sie sich bitte an E-Mail an devrel@nexmo.com und wir werden Sie gerne bei der Einrichtung der Anwendung und mit einem kostenlosen Nexmo-Guthaben unterstützen.

Teilen Sie:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Mariatta

I am not open, parts of me are broken