
Compartilhar:
Aaron era um defensor de desenvolvedores na Nexmo. Engenheiro de software experiente e aspirante a artista digital, Aaron costuma ser visto criando coisas com código ou com eletrônica; às vezes, os dois. Geralmente, dá para perceber quando ele está trabalhando em algo novo pelo cheiro de componentes queimando no ar.
Envio de modelos de SMS com Jinja2 e Python
Precisa enviar uma mensagem para várias pessoas ao mesmo tempo? Quer personalizá-la para que não pareça tão, digamos, impessoal? Não consegue enviar uma mensagem em grupo porque não quer que sua mãe perceba que você enviou o mesmo texto carinhoso para todos os seus parentes, e não apenas para ela? Vamos ver como criar um cliente de SMS que ofereça suporte a mensagens em massa e modelos para personalização.
Introdução
Você precisará de um pouco de experiência com Python para executar a CLI e, no mínimo, o Python 3.6, já que vamos usar f-strings.
Instale as dependências no seu ambiente virtual; recomendo usar pipenv e instalar o pacote no modo de edição:
pipenv install -e .Crie as seguintes variáveis de ambiente;
NEXMO_KEY,NEXMO_SECRET, eMY_NUMBERas duas primeiras estão disponíveis no seu Painel do Nexmo.MY_NUMBERé o seu número de celular no formato internacional E.164.
Gerenciamento de contatos de SMS
Creating a new contact via the CLI
Nosso aplicativo vai precisar de um CRM básico para armazenar nossos contatos. Vamos usar o tinydb como nossa camada de persistência, já que não precisamos de nada muito complicado e, como bônus, ele armazena os dados como um arquivo JSON, o que facilita os backups e as edições manuais dos dados.
Além do nome e do número de telefone do contato, coletamos algumas opções de resposta múltipla.
@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
)Ao renderizar o modelo de uma mensagem, vamos inserir um valor aleatório dessas listas no contexto, para dar um pouco de variação às mensagens.
Gerenciamento de nossos modelos de SMS
Nossos modelos serão renderizados usando o Jinja2, o que nos dará acesso a todos os filtros e recursos integrados do Jinja. Também fornecemos informações sobre cada contato no contexto ao renderizar o modelo.
Creating a new template via the CLI
Tenho usado bastante o filtro do Jinja random para que haja alguma variação nas minhas mensagens; mesmo que eu reenvie a mesma mensagem várias vezes para a mesma pessoa, deve parecer que dediquei tempo para escrevê-la pessoalmente a cada vez. Para dar mais autenticidade, você pode inserir aleatoriamente algum erro de digitação de vez em quando.
{{ 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 SMS
O restante do nosso código de gerenciamento de modelos é muito semelhante ao dos contatos, embora tenhamos uma função rudimentar de detalhamento/expansão para que você possa visualizar rapidamente o conteúdo do modelo.
@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 Envio de várias mensagens SMS com Python
Sending multiple/bulk SMS via the CLI
Com o Cliente Python da Nexmo , enviar um SMS é uma única chamada de função; a maior parte do nosso código de envio de SMS serve para permitir que o usuário selecione quais números receberão a mensagem e qual modelo devemos usar.
@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,
}
)Modifiquei o código acima para registrar os resultados da minha mensagem de Natal, para que você possa ver o tipo de variação que ele produz entre os diferentes contatos.
Multiple messages output from bulk SMS CLI in Python
Compartilhar:
Aaron era um defensor de desenvolvedores na Nexmo. Engenheiro de software experiente e aspirante a artista digital, Aaron costuma ser visto criando coisas com código ou com eletrônica; às vezes, os dois. Geralmente, dá para perceber quando ele está trabalhando em algo novo pelo cheiro de componentes queimando no ar.