shade-plugins-whatsapp
Envia mensagem de texto e de modelo pela WhatsApp Business Cloud
API, de dentro de um robô do
shade-sdk. Só a biblioteca padrão do Python: nenhuma
dependência além do shade-sdk.
No shade.toml do robô, o host da API vai em [hosts] permitidos e o token em [credenciais]:
[hosts]
permitidos = ["graph.facebook.com"]
[credenciais]
nomes = ["WHATSAPP_ACCESS_TOKEN"]
[plugins]
whatsapp = "0.1.0"
import shade_plugins_whatsapp as whatsapp
# Escrita: só dentro de item.efetivar() (no ensaio não roda).
with item.efetivar("avisar o cliente"):
whatsapp.enviar_modelo(
item["telefone"], # "+55 11 91234-5678": o plugin só guarda os dígitos
"pedido_recebido", # o modelo aprovado no painel da Meta
"pt_BR",
numero_id=config["whatsapp_numero"], # o id do número de telefone da conta
corpo=[item["cliente"], item["pedido"]], # {{1}}, {{2}}
)
with item.efetivar("responder a dúvida"):
whatsapp.enviar_texto(
item["telefone"], "Seu pedido sai hoje.", numero_id=config["whatsapp_numero"]
)
A conta
- Token: o token de acesso de um usuário do sistema do seu negócio no Meta Business, com a
permissão
whatsapp_business_messaging. Guarde-o como a credencialWHATSAPP_ACCESS_TOKEN; o plugin o lê só porsegredo(), e ele nunca aparece em evento, log nem mensagem de erro. numero_id: o identificador do número de telefone da conta (não é o telefone). Não é segredo: guarde-o no[config]do robô.- Texto ou modelo: o texto livre (
enviar_texto) só chega a quem escreveu para o número nas últimas 24 horas. Fora dessa janela, só o modelo aprovado (enviar_modelo) abre a conversa. O modelo leva os parâmetros de texto do corpo e do cabeçalho: a lista na ordem de{{1}},{{2}}, ou o dicionário{nome: texto}do modelo com parâmetros nomeados. Cada texto sai sem quebra de linha, tabulação nem quatro espaços seguidos (a API os recusa). Botão dinâmico, mídia e localização não são suportados nesta versão.
O que o plugin garante
- Nunca envia duas vezes. A Cloud API não reconhece repetição: não há chave de idempotência, e
um segundo pedido é uma segunda mensagem no celular. Por isso o plugin não repete depois do
despacho, em nenhum erro:
- A conexão que não chegou a abrir (recusada, nome que não resolve, rede inalcançável) é tentada
de novo, dentro do
timeout=, porque nada saiu. - A API que recusou (4xx) é
WhatsAppNaoSaiu: nenhuma mensagem saiu. Ocodigodo erro da Meta vem emerro.codigo(por exemplo,131047: fora da janela de 24 horas). - O que sobra é
WhatsAppIncerto: otimeout, a conexão que cai depois do envio, o5xxe a resposta de sucesso sem o identificador da mensagem. A mensagem pode estar no celular. O item fica retido para uma pessoa conferir (no celular de teste, no painel da Meta ou nos webhooks de status) e, só se a mensagem não chegou, mandar refazer. O plugin não reenvia sozinho, e uma nova execução do robô também não.
- A conexão que não chegou a abrir (recusada, nome que não resolve, rede inalcançável) é tentada
de novo, dentro do
- Só dentro de
item.efetivar(). Fora dele, a operação é um erro de contrato antes de qualquer byte; no ensaio, o bloco é pulado e nada é enviado. - Host e prazo: só
graph.facebook.com, com o certificado verificado, sem seguir redirecionamento; toda chamada aceitatimeout=(30 s por padrão), que vale para a chamada inteira. - Sem dado pessoal em evento nem em erro: cada chamada emite um evento com a operação, o host, a duração e o status. Nunca o texto, o telefone do destinatário nem o corpo da resposta; o erro da Meta chega só pelo código numérico.
Operações
| Operação | Efeito | O que faz |
|---|---|---|
enviar_texto(para, texto, *, numero_id, previa_de_link=False) |
sim | Mensagem de texto de até 4096 caracteres. |
enviar_modelo(para, modelo, idioma, *, numero_id, corpo=None, cabecalho=None) |
sim | Mensagem de modelo aprovado. |
As duas devolvem {"mensagem_id": "wamid...."}.
Testes
A suíte de contrato do shade_sdk.testing.plugins e um servidor falso da Cloud API (TLS de uma CA
de teste) acompanham o código-fonte em tests/. O servidor falso não reconhece repetição, como a
API de verdade.
Metadata
Release files for shade-plugins-whatsapp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| shade_plugins_whatsapp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / shade_plugins_whatsapp-0.1.0-py3-none-any.whl
| Download URL | shade_plugins_whatsapp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 16.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1461727e7ee7684bf86d65d6426c3f6b5ea2d2966de50dcb8dfce55388370a77
|
|
BLAKE2b-256 checksum How to use checksums |
96ab044329c509818821416d7ebbb4ae32ca125aed987be75bd16de5d378d788
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for shade-plugins-whatsapp 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.