https://d226lax1qjow5r.cloudfront.net/blog/blogposts/sending-sms-templates-python-dr/Sending-SMS-templates-with-Jinja2-and-Python.png

SMS-Vorlagen mit Jinja2 und Python verschicken

Zuletzt aktualisiert am May 11, 2021

Lesedauer: 2 Minuten

Sie müssen eine Nachricht an viele Personen gleichzeitig senden? Sie möchten sie persönlich gestalten, damit sie nicht so, nun ja, unpersönlich wirkt? Sie können keine Gruppennachricht verschicken, weil Sie nicht wollen, dass Ihre Mutter sieht, dass Sie allen Ihren Verwandten dieselbe herzliche Nachricht geschickt haben und nicht nur ihr? Wir werden uns ansehen, wie man einen SMS-Client erstellt, der Massennachrichten und Vorlagen zur Personalisierung unterstützt.

Erste Schritte

Sie benötigen ein wenig Erfahrung mit Python, um die CLI auszuführen, und mindestens Python 3.6, da wir f-strings verwenden werden.

  1. Klonen Sie den Quellcode von GitHub

  2. Installieren Sie die Abhängigkeiten in Ihrer virtuellen Umgebung; ich empfehle die Verwendung von pipenv zu verwenden und das Paket im Bearbeitungsmodus zu installieren: pipenv install -e .

  3. Legen Sie die folgenden Umgebungsvariablen an; NEXMO_KEY, NEXMO_SECRET, und MY_NUMBER die ersten beiden sind verfügbar über Ihrem Nexmo Dashboard. MY_NUMBER ist Ihre Handynummer im internationalen E.164-Format.

SMS-Kontakte verwalten

Creating a new contact via the CLICreating a new contact via the CLI

Unsere Anwendung wird Folgendes benötigen ein grundlegendes CRM, um unsere Kontakte zu speichern. Wir werden tinydb für unsere Persistenzschicht verwenden, da wir nichts allzu Kompliziertes benötigen und die Daten als JSON-Datei gespeichert werden, was Backups und manuelle Bearbeitungen der Daten einfach macht.

Neben dem Namen und der Telefonnummer des Ansprechpartners gibt es einige Multiple-Choice-Werte, die wir erfassen.

@contact.command("create")
def contact_create():
    """Creates a new contact"""
    questions = [
        {"type": "input", "name": "name", "message": "Contact name"},
        {
            "type": "input",
            "name": "phonenumber",
            "message": "Contact phone number (E.164 international format)",
        },
        {
            "type": "checkbox",
            "qmark": "?",
            "message": "Select diminutives (select at least 1)",
            "name": "diminutive",
            "choices": [
                Separator("= The Bros ="),
                {"name": "Bro"},
                {"name": "Buddy"},
                {"name": "Dude"},
                {"name": "Matey"},
                {"name": "Pal"},
                Separator("= The Sweethearts ="),
                {"name": "Baby"},
                {"name": "Bae"},
                {"name": "Darling"},
                {"name": "Sweetheart"},
                {"name": "Sugar"},
                Separator("= The Scots/Irish/Aussies ="),
                {"name": "████"},
                {"name": "Eejit"},
                {"name": "█████████"},
                {"name": "Numpty"},
            ],
            "validate": lambda answer: "You must choose at least one diminutive."
            if len(answer) == 0
            else True,
        },
        {
            "type": "checkbox",
            "qmark": "?",
            "message": "Select greetings (select at least 1)",
            "name": "greeting",
            "choices": [
                {"name": "Alright"},
                {"name": "Greetings"},
                {"name": "Hello"},
                {"name": "Hey"},
                {"name": "Hi"},
                {"name": "Oi"},
                {"name": "Wasssssup"},
                {"name": "Yo"},
            ],
            "validate": lambda answer: "You must choose at least one greeting."
            if len(answer) == 0
            else True,
        },
        {
            "type": "checkbox",
            "qmark": "?",
            "message": "Select valediction (select at least 1)",
            "name": "valediction",
            "choices": [
                {"name": "Bye"},
                {"name": "Cya"},
                {"name": "Love you x"},
                {"name": "Peace"},
                {"name": "xox"},
            ],
            "validate": lambda answer: "You must choose at least one valediction."
            if len(answer) == 0
            else True,
        },
    ]

    answers = prompt(questions, style=questions_style)
    contacts_db.insert(answers)

    click.secho(
        f"New contact {answers['name']} created", fg="black", bg="cyan", bold=True
    )

Wenn wir die Vorlage für eine Nachricht rendern, geben wir einen Zufallswert aus diesen Listen in den Kontext ein, um den Nachrichten etwas Abwechslung zu verleihen.

Verwaltung unserer SMS-Vorlagen

Unsere Vorlagen werden mit Jinja2 gerendert, wodurch wir Zugang zu allen in Jinja integrierten Filtern und Funktionen erhalten. Wir werden auch liefern Informationen über jeden Kontakt im Kontext wenn die Vorlage gerendert wird.

Creating a new template via the CLICreating a new template via the CLI

Ich habe den Filter von Jinja großzügig genutzt random Filter verwendet, damit meine Nachrichten etwas variieren. Selbst wenn ich dieselbe Person mehrmals anschreibe, sollte es so aussehen, als hätte ich mir jedes Mal die Zeit genommen, sie persönlich zu schreiben. Für zusätzliche Authentizität können Sie von Zeit zu Zeit einen Tippfehler einbauen.

{{ greeting }} {{ diminutive }} {{ ["gah", "sorry", "I suck", "soz"]|random }}, I'm {{ ["running", "runnin", "runing"]|random }} about {{ range(5,25)|random }} {{ ["mins", "minutes", "mintes"]|random }} late. {{ valediction }}

Screenshot of phone with multiple SMSScreenshot of phone with multiple SMS

Der Rest des Code unserer Vorlagenverwaltung sieht den Kontakten sehr ähnlich, obwohl wir ein grobes Drilldown/Expandieren haben, damit Sie den Inhalt der Vorlage schnell sehen können.

@template.command("list")
def template_list():
    """View all templates"""
    viewing_templates = True
    all_templates = templates_db.all()

    while viewing_templates:
        questions = [
            {
                "type": "list",
                "message": "View template",
                "name": "template",
                "choices": [
                    {"name": f"{template['name']}", "value": template}
                    for template in all_templates
                ],
            }
        ]

        answers = prompt(questions, style=questions_style)

        click.echo(answers["template"]["name"])
        click.echo("---")
        click.echo(answers["template"]["template"])

        if not click.confirm("View another template?"):
            viewing_templates = False

Versenden mehrerer SMS mit Python

Sending multiple/bulk SMS via the CLISending multiple/bulk SMS via the CLI

Mit dem Nexmo Python-Klient ist das Senden einer SMS ein einzelner FunktionsaufrufDer größte Teil des Codes für den SMS-Versand besteht darin, dass der Benutzer auswählen kann, welche Numbers die Nachricht erhalten sollen, und welche Vorlage wir verwenden sollen.

@click.command()
def send():
    """Send SMS"""

    questions = [
        {
            "type": "checkbox",
            "qmark": "?",
            "message": "Select contacts to message",
            "name": "contacts",
            "choices": [
                {
                    "name": f"{contact['name']} - {contact['phonenumber']}",
                    "value": contact,
                }
                for contact in contacts_db.all()
            ],
            "validate": lambda answer: "You must choose at least one contact."
            if len(answer) == 0
            else True,
        },
        {
            "type": "list",
            "message": "Select template",
            "name": "template",
            "choices": [
                {"name": f"{template['name']}", "value": template["template"]}
                for template in templates_db.all()
            ],
        },
    ]

    answers = prompt(questions, style=questions_style)
    template = Template(answers["template"])

    with click.progressbar(answers["contacts"], label="Sending messages") as contacts:
        for contact in contacts:
            message = template.render(
                name=contact["name"],
                phonenumber=contact["phonenumber"],
                diminutive=random.choice(contact["diminutive"]),
                greeting=random.choice(contact["greeting"]),
                valediction=random.choice(contact["valediction"]),
            )

            nexmo_client.send_message(
                {
                    "from": os.environ["MY_NUMBER"],
                    "to": contact["phonenumber"],
                    "text": message,
                }
            )

Ich habe den obigen Code geändert, um die Ergebnisse meiner Weihnachtsnachricht zu protokollieren, so dass Sie sehen können, welche Unterschiede zwischen den verschiedenen Kontakten entstehen.

Multiple messages output from bulk SMS CLI in PythonMultiple messages output from bulk SMS CLI in Python

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.