Skip to main content

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 credencial WHATSAPP_ACCESS_TOKEN; o plugin o lê só por segredo(), 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. O codigo do erro da Meta vem em erro.codigo (por exemplo, 131047: fora da janela de 24 horas).
    • O que sobra é WhatsAppIncerto: o timeout, a conexão que cai depois do envio, o 5xx e 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.
  • 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 aceita timeout= (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)

Table of built distributions (wheels) for shade-plugins-whatsapp 0.1.0
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

1 release file No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page