Skip to main content

django-anysms

Envio de SMS e WhatsApp com uma API Django consistente e provedores intercambiáveis. A versão 0.1 inclui Twilio, mensagens síncronas e parsing validado de callbacks de entrega.

Instalação

python -m pip install django-anysms
python -m pip install 'django-anysms[twilio]'

A v0.1 suporta Python 3.10–3.13, Django 5.2 LTS e Django 6.0. O SDK da Twilio é opcional e não é importado pelo core.

Configuração

Configure aliases em suas settings Django:

import os

ANYSMS = {
    "DEFAULT": "twilio",
    "PROVIDERS": {
        "twilio": {
            "CLASS": "django_anysms.providers.twilio.TwilioProvider",
            "OPTIONS": {
                "account_sid": os.environ["TWILIO_ACCOUNT_SID"],
                "auth_token": os.environ["TWILIO_AUTH_TOKEN"],
                "from_": "+5511999999999",
            },
        },
    },
}

O pacote não precisa ser adicionado a INSTALLED_APPS.

SMS

from django_anysms import SMSMessage

result = SMSMessage(
    to="+5511888888888",
    body="Seu código é 123456",
    status_callback="https://example.com/webhooks/twilio/status/",
).send()

print(result.message_id, result.status)

Cada mensagem possui exatamente um destinatário em formato E.164. Números nacionais não são corrigidos ou completados automaticamente.

Um recurso específico pode ser informado sem contaminar a API comum:

message = SMSMessage(
    to="+5511888888888",
    body="Olá",
    provider_options={
        "twilio": {"messaging_service_sid": "MG..."},
    },
)
message.send(using="twilio")

WhatsApp

Texto livre dentro de uma conversa permitida pelo WhatsApp:

from django_anysms import WhatsAppMessage

WhatsAppMessage(
    to="+5511888888888",
    body="Seu pedido saiu para entrega.",
).send()

Mensagem proativa com um Content Template aprovado:

WhatsAppMessage(
    to="+5511888888888",
    content_sid="HX0123456789abcdef0123456789abcdef",
    variables={"1": "Rafael", "2": "15/08/2026"},
).send()

body e content_sid são mutuamente exclusivos. O provider adiciona o prefixo whatsapp:; a API pública recebe somente E.164.

Provider explícito

Settings são opcionais quando a aplicação precisa de credenciais dinâmicas:

from django_anysms import SMSMessage
from django_anysms.providers.twilio import TwilioProvider

provider = TwilioProvider(
    account_sid="AC...",
    auth_token="...",
    from_="+5511999999999",
)

result = SMSMessage(to="+5511888888888", body="Olá").send(provider=provider)

A prioridade é: instância em provider=, alias em using= e, por último, ANYSMS["DEFAULT"]. provider e using não podem ser usados juntos.

Erros

Falhas esperadas herdam de AnySMSError. Por padrão elas são lançadas. Para um fluxo compatível com fail_silently, use:

result = message.send(fail_silently=True)
if not result.accepted:
    report(result.error)

accepted=True significa que o provedor aceitou a chamada, não que a mensagem chegou ao aparelho. Não há retry automático para evitar duplicatas após falhas ambíguas.

A hierarquia pública inclui ConfigurationError, MessageValidationError, ProviderNotInstalledError, ProviderError, InvalidWebhookSignature e InvalidWebhookPayload, todos em django_anysms.exceptions.

Callback de entrega

A aplicação controla sua própria URL e persistência. Exemplo de view:

from django.http import HttpRequest, HttpResponse
from django.views.decorators.csrf import csrf_exempt

from django_anysms.exceptions import InvalidWebhookPayload, InvalidWebhookSignature
from django_anysms.registry import get_provider


@csrf_exempt
def twilio_status(request: HttpRequest) -> HttpResponse:
    provider = get_provider("twilio")
    try:
        event = provider.parse_webhook(
            public_url=request.build_absolute_uri(),
            form=request.POST,
            signature=request.headers.get("X-Twilio-Signature"),
        )
    except InvalidWebhookSignature:
        return HttpResponse(status=403)
    except InvalidWebhookPayload:
        return HttpResponse(status=400)

    consume_delivery_event(event)
    return HttpResponse(status=204)

Em ambientes com proxy, public_url precisa ser exatamente a URL pública assinada pela Twilio. A biblioteca valida a assinatura antes de projetar o payload.

DeliveryEvent.raw preserva o formulário decodificado completo, inclusive campos desconhecidos e valores repetidos. Tanto ele quanto SendResult.raw podem conter telefones e outros dados pessoais; não registre ou persista esses mappings sem uma política adequada.

Callbacks podem chegar fora de ordem. A v0.1 não persiste, deduplica ou ordena eventos, e o status inicial existe apenas em SendResult.

Brasil

Regras de sender, horário, operadora e delivery report mudam fora do ciclo de release da biblioteca. Consulte regularmente as diretrizes oficiais da Twilio para SMS no Brasil.

Fora da v0.1

Mensagens recebidas, MMS/mídia, lotes, agendamento, models, views prontas, signals, async/Celery, retries, fallback entre provedores, normalização de números e gerenciamento de templates não fazem parte desta versão.

O design completo está em docs/superpowers/specs/2026-08-15-django-anysms-v01-design.md.

Releases

O projeto usa Release Please com Conventional Commits. Pushes em main atualizam uma Release PR; ao mesclá-la, o mesmo workflow cria a tag e a GitHub Release, constrói sdist e wheel com Hatchling e publica no PyPI via Trusted Publisher (OIDC). Releases criadas manualmente no GitHub não são publicadas.

Antes do primeiro release:

  1. Em Settings > Actions > General > Workflow permissions, habilite Allow GitHub Actions to create and approve pull requests.

  2. Crie o environment pypi em Settings > Environments. Proteções e aprovação manual são opcionais.

  3. No PyPI, configure um Trusted Publisher — ou um pending publisher para o primeiro upload — com estes valores:

    • Owner: davisilvarafacho
    • Repository: django-anysms
    • Workflow: release.yml
    • Environment: pypi

O workflow não usa PYPI_API_TOKEN. A primeira Release PR publica v0.1.0; as próximas versões são calculadas a partir dos commits feat, fix e mudanças incompatíveis.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_anysms-0.1.0.tar.gz (51.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_anysms-0.1.0-py3-none-any.whl (14.7 kB view details)

Uploaded Python 3

File details

Details for the file django_anysms-0.1.0.tar.gz.

File metadata

  • Download URL: django_anysms-0.1.0.tar.gz
  • Upload date:
  • Size: 51.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for django_anysms-0.1.0.tar.gz
Algorithm Hash digest
SHA256 cc1efebcdbe4dc23e89359bbe78e20fafd7fc85dbe575cd7633245355cded774
MD5 f5d629df86c7e4f878b0889403f9e189
BLAKE2b-256 23f8fd8930e6c8dd84ee9fe570a5758c146944610d3977cf79e7cff13000b8e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_anysms-0.1.0.tar.gz:

Publisher: release.yml on davisilvarafacho/django-anysms

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_anysms-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: django_anysms-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for django_anysms-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b7b63ffe760fca86f68dd504c7a34352206e358773683813d0b8d895784f4973
MD5 94049d16673f277dda4df9e7319b1017
BLAKE2b-256 efd31c2480fbc5cca94ea42e916782819f1f7fc0a54af023f0023775f1420cb9

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_anysms-0.1.0-py3-none-any.whl:

Publisher: release.yml on davisilvarafacho/django-anysms

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

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