maquinaweb-shared-msg 0.1.10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. maquinaweb_shared_msg-0.1.10/PKG-INFO +569 -0
  2. maquinaweb_shared_msg-0.1.10/README.md +544 -0
  3. maquinaweb_shared_msg-0.1.10/maquinaweb_shared_msg.egg-info/PKG-INFO +569 -0
  4. maquinaweb_shared_msg-0.1.10/maquinaweb_shared_msg.egg-info/SOURCES.txt +24 -0
  5. maquinaweb_shared_msg-0.1.10/maquinaweb_shared_msg.egg-info/dependency_links.txt +1 -0
  6. maquinaweb_shared_msg-0.1.10/maquinaweb_shared_msg.egg-info/requires.txt +7 -0
  7. maquinaweb_shared_msg-0.1.10/maquinaweb_shared_msg.egg-info/top_level.txt +1 -0
  8. maquinaweb_shared_msg-0.1.10/pyproject.toml +34 -0
  9. maquinaweb_shared_msg-0.1.10/setup.cfg +4 -0
  10. maquinaweb_shared_msg-0.1.10/setup.py +16 -0
  11. maquinaweb_shared_msg-0.1.10/shared_msg/__init__.py +7 -0
  12. maquinaweb_shared_msg-0.1.10/shared_msg/app.py +9 -0
  13. maquinaweb_shared_msg-0.1.10/shared_msg/conf.py +16 -0
  14. maquinaweb_shared_msg-0.1.10/shared_msg/managers.py +27 -0
  15. maquinaweb_shared_msg-0.1.10/shared_msg/message/__init__.py +0 -0
  16. maquinaweb_shared_msg-0.1.10/shared_msg/message/services/__init__.py +4 -0
  17. maquinaweb_shared_msg-0.1.10/shared_msg/message/services/twilio_service.py +148 -0
  18. maquinaweb_shared_msg-0.1.10/shared_msg/message/utils/__init__.py +6 -0
  19. maquinaweb_shared_msg-0.1.10/shared_msg/message/utils/build_email_message.py +31 -0
  20. maquinaweb_shared_msg-0.1.10/shared_msg/message/utils/build_sms_message.py +15 -0
  21. maquinaweb_shared_msg-0.1.10/shared_msg/message/utils/build_whatsapp_message.py +49 -0
  22. maquinaweb_shared_msg-0.1.10/shared_msg/message/utils/send_message.py +58 -0
  23. maquinaweb_shared_msg-0.1.10/shared_msg/mixins/__init__.py +0 -0
  24. maquinaweb_shared_msg-0.1.10/shared_msg/mixins/contact.py +39 -0
  25. maquinaweb_shared_msg-0.1.10/shared_msg/models.py +67 -0
  26. maquinaweb_shared_msg-0.1.10/shared_msg/router.py +27 -0
@@ -0,0 +1,569 @@
1
+ Metadata-Version: 2.4
2
+ Name: maquinaweb-shared-msg
3
+ Version: 0.1.10
4
+ Summary: Models and Functions for to send messages to contacts.
5
+ Author-email: Seu Nome <seuemail@dominio.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/maquinaweb/maquinaweb-shared-msg
8
+ Project-URL: Repository, https://github.com/maquinaweb/maquinaweb-shared-msg
9
+ Project-URL: Issues, https://github.com/maquinaweb/maquinaweb-shared-msg/issues
10
+ Keywords: django,msg,models,shared
11
+ Classifier: Framework :: Django
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Requires-Python: >=3.8
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: django>=5
18
+ Requires-Dist: django-storages>=1.14.6
19
+ Requires-Dist: djangorestframework>=3
20
+ Requires-Dist: pyyaml>=6.0.3
21
+ Requires-Dist: setuptools>=70
22
+ Requires-Dist: twilio>=9.8.8
23
+ Requires-Dist: zappa>=0.61.2
24
+ Dynamic: requires-python
25
+
26
+ # 📨 Maquinaweb Shared Msg
27
+
28
+ > Biblioteca Django para envio de mensagens (Email, SMS, WhatsApp) compartilhada entre múltiplos sistemas usando um banco de dados centralizado e integração com Twilio.
29
+
30
+ [![Python](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
31
+ [![Django](https://img.shields.io/badge/django-5.0+-green.svg)](https://www.djangoproject.com/)
32
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
33
+
34
+ ## 📋 Índice
35
+
36
+ - [Visão Geral](#-visão-geral)
37
+ - [Características](#-características)
38
+ - [Arquitetura](#️-arquitetura)
39
+ - [Instalação](#-instalação)
40
+ - [Configuração](#️-configuração)
41
+ - [Uso Básico](#-uso-básico)
42
+ - [API Reference](#-api-reference)
43
+
44
+ ---
45
+
46
+ ## 🎯 Visão Geral
47
+
48
+ A **Maquinaweb Shared Msg** permite que múltiplos sistemas Django enviem mensagens para contatos através de um banco de dados centralizado, com suporte a:
49
+
50
+ - 📧 **Email** - Envio de emails HTML usando Django templates
51
+ - 📱 **SMS** - Envio de SMS via Twilio
52
+ - 💬 **WhatsApp** - Envio de mensagens WhatsApp via Twilio com suporte a templates
53
+
54
+ ### Problema Resolvido
55
+
56
+ Ao invés de:
57
+ - ❌ Configurar envio de mensagens em cada sistema separadamente
58
+ - ❌ Duplicar lógica de integração com Twilio
59
+ - ❌ Gerenciar contatos em múltiplos bancos
60
+
61
+ Você pode:
62
+ - ✅ Centralizar envio de mensagens em uma biblioteca
63
+ - ✅ Compartilhar contatos entre sistemas
64
+ - ✅ Usar templates Django para personalizar mensagens
65
+ - ✅ Executar envios assíncronos com Zappa
66
+
67
+ ---
68
+
69
+ ## ✨ Características
70
+
71
+ ### Core Features
72
+
73
+ - **📧 Email HTML**: Envio de emails com templates Django renderizados
74
+ - **📱 SMS via Twilio**: Integração completa com Twilio para SMS
75
+ - **💬 WhatsApp Templates**: Suporte a Twilio Content Templates para WhatsApp
76
+ - **🔄 Envio Assíncrono**: Decorador `@task` do Zappa para execução em background
77
+ - **🗄️ Banco Centralizado**: Models read-only para contatos compartilhados
78
+ - **🧩 Mixins Reutilizáveis**: `ContactMixin` para integração fácil em seus models
79
+
80
+ ### Componentes Principais
81
+
82
+ | Componente | Descrição |
83
+ |------------|-----------|
84
+ | **Models** | Contact, Email, Phone, Message |
85
+ | **Services** | TwilioService para SMS e WhatsApp |
86
+ | **Utils** | Builders para Email, SMS e WhatsApp |
87
+ | **Mixins** | ContactMixin para models com contatos |
88
+ | **Router** | SharedMsgRouter para roteamento de banco |
89
+
90
+ ---
91
+
92
+ ## 🏗️ Arquitetura
93
+
94
+ ```
95
+ ┌─────────────────────────────────────────┐
96
+ │ Sistema de Mensagens Centralizado │
97
+ │ │
98
+ │ ┌──────────┐ ┌────────┐ ┌─────────┐ │
99
+ │ │ Contact │ │ Email │ │ Phone │ │
100
+ │ └────┬─────┘ └───┬────┘ └────┬────┘ │
101
+ │ │ │ │ │
102
+ │ └────────────┴────────────┘ │
103
+ │ │ │
104
+ │ ┌────────▼────────┐ │
105
+ │ │ Message │ │
106
+ │ │ (status track) │ │
107
+ │ └─────────────────┘ │
108
+ └──────────────────┬──────────────────────┘
109
+
110
+ ┌────────────┴────────────┐
111
+ │ PostgreSQL/MySQL │
112
+ │ (auth_db) │
113
+ └────────────┬────────────┘
114
+
115
+ ┌────────────┼────────────┐
116
+ │ │ │
117
+ ┌─────▼─────┐ ┌────▼────┐ ┌────▼─────┐
118
+ │ Sistema A │ │Sistema B│ │ Sistema C│
119
+ │ │ │ │ │ │
120
+ │ send_msg()│ │send_msg()││send_msg()│
121
+ └───────────┘ └─────────┘ └──────────┘
122
+
123
+ ┌────────────┴────────────┐
124
+ │ │
125
+ ▼ ▼
126
+ ┌──────────┐ ┌──────────┐
127
+ │ Twilio │ │ Django │
128
+ │ SMS/WA │ │ Email │
129
+ └──────────┘ └──────────┘
130
+ ```
131
+
132
+ **Fluxo de Envio:**
133
+
134
+ 1. Sistema cliente chama `send_message()` ou usa `ContactMixin`
135
+ 2. Mensagem é processada e enviada via canal apropriado (Email/Twilio)
136
+ 3. Status da mensagem é atualizado no model `Message`
137
+ 4. Execução pode ser síncrona ou assíncrona (via Zappa)
138
+
139
+ ---
140
+
141
+ ## 📦 Instalação
142
+
143
+ ### 1. Instalar a Biblioteca
144
+
145
+ ```bash
146
+ # Via pip (quando publicado)
147
+ pip install maquinaweb-shared-msg
148
+
149
+ # Ou modo desenvolvimento
150
+ pip install -e /path/to/maquinaweb-shared-msg
151
+ ```
152
+
153
+ ### 2. Adicionar ao requirements.txt
154
+
155
+ ```txt
156
+ Django>=5.0
157
+ djangorestframework>=3.0
158
+ maquinaweb-shared-msg>=0.1.9
159
+ twilio>=9.8.8
160
+ zappa>=0.61.2
161
+ ```
162
+
163
+ ---
164
+
165
+ ## ⚙️ Configuração
166
+
167
+ ### 1. Settings do Django
168
+
169
+ ```python
170
+ # settings.py
171
+
172
+ INSTALLED_APPS = [
173
+ 'django.contrib.admin',
174
+ 'django.contrib.auth',
175
+ 'django.contrib.contenttypes',
176
+ 'django.contrib.sessions',
177
+ 'rest_framework',
178
+
179
+ # Adicionar shared_msg
180
+ 'shared_msg',
181
+
182
+ # Suas apps
183
+ 'myapp',
184
+ ]
185
+ ```
186
+
187
+ ### 2. Configurar Banco de Dados
188
+
189
+ ```python
190
+ # settings.py
191
+
192
+ DATABASES = {
193
+ 'default': {
194
+ # Banco do sistema atual
195
+ 'ENGINE': 'django.db.backends.postgresql',
196
+ 'NAME': 'meu_sistema_db',
197
+ 'USER': 'meu_user',
198
+ 'PASSWORD': 'senha',
199
+ 'HOST': 'localhost',
200
+ 'PORT': '5432',
201
+ },
202
+ 'auth_db': {
203
+ # Banco centralizado de mensagens
204
+ 'ENGINE': 'django.db.backends.postgresql',
205
+ 'NAME': 'sistema_msg_db',
206
+ 'USER': 'msg_user',
207
+ 'PASSWORD': 'senha',
208
+ 'HOST': 'msg-server.example.com',
209
+ 'PORT': '5432',
210
+ }
211
+ }
212
+
213
+ # Router para direcionar queries
214
+ DATABASE_ROUTERS = ['shared_msg.router.SharedMsgRouter']
215
+ ```
216
+
217
+ ### 3. Configurar Twilio
218
+
219
+ ```python
220
+ # settings.py
221
+
222
+ # Credenciais Twilio
223
+ TWILIO_ACCOUNT_SID = 'ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
224
+ TWILIO_AUTH_TOKEN = 'seu_auth_token_aqui'
225
+
226
+ # Números de envio
227
+ TWILIO_SMS_FROM = '+5511999999999'
228
+ TWILIO_WHATSAPP_FROM = '+5511999999999'
229
+
230
+ # Content SIDs para templates WhatsApp (opcional)
231
+ TWILIO_CONTENT_SIDS = {
232
+ 'whatsapp/welcome': {
233
+ 'whatsapp': 'HXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
234
+ },
235
+ 'whatsapp/order_confirmation': {
236
+ 'whatsapp': 'HXyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
237
+ },
238
+ }
239
+ ```
240
+
241
+ ### 4. Configurar Email
242
+
243
+ ```python
244
+ # settings.py
245
+
246
+ # Configuração padrão do Django para email
247
+ EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
248
+ EMAIL_HOST = 'smtp.gmail.com'
249
+ EMAIL_PORT = 587
250
+ EMAIL_USE_TLS = True
251
+ EMAIL_HOST_USER = 'seu@email.com'
252
+ EMAIL_HOST_PASSWORD = 'sua_senha_app'
253
+ DEFAULT_FROM_EMAIL = 'noreply@seudominio.com'
254
+ ```
255
+
256
+ ### 5. Configurar Tabelas (Opcional)
257
+
258
+ ```python
259
+ # settings.py
260
+
261
+ # Customizar nomes das tabelas (se necessário)
262
+ SHARED_MSG_MESSAGE_TABLE = 'message_message'
263
+ SHARED_MSG_CONTACT_TABLE = 'message_contact'
264
+ SHARED_MSG_EMAIL_TABLE = 'message_email'
265
+ SHARED_MSG_PHONE_TABLE = 'message_phone'
266
+
267
+ # Banco de dados a utilizar
268
+ SHARED_MSG_DEFAULT_DB = 'auth_db'
269
+ ```
270
+
271
+ ---
272
+
273
+ ## 🚀 Uso Básico
274
+
275
+ ### 1. Enviar Mensagem Diretamente
276
+
277
+ ```python
278
+ from shared_msg.message.utils.send_message import send_message
279
+ from shared_msg.message.utils import MessageTypes
280
+
281
+ # Enviar Email
282
+ send_message(
283
+ contacts_ids=[1, 2, 3],
284
+ type=MessageTypes.EMAIL,
285
+ template='emails/welcome.html',
286
+ context={'name': 'João', 'company': 'XYZ'},
287
+ from_email='noreply@empresa.com',
288
+ subject='Bem-vindo à nossa plataforma!',
289
+ )
290
+
291
+ # Enviar SMS
292
+ send_message(
293
+ contacts_ids=1,
294
+ type=MessageTypes.SMS,
295
+ template='sms/verification_code.txt',
296
+ context={'code': '123456'},
297
+ )
298
+
299
+ # Enviar WhatsApp
300
+ send_message(
301
+ contacts_ids=[1, 2],
302
+ type=MessageTypes.WHATSAPP,
303
+ template='whatsapp/order_confirmation.html',
304
+ context={
305
+ 'order_number': 'PED-001',
306
+ 'total': 'R$ 150,00',
307
+ 'twilio_variables': {
308
+ '1': 'PED-001',
309
+ '2': 'R$ 150,00',
310
+ }
311
+ },
312
+ )
313
+ ```
314
+
315
+ ### 2. Usando ContactMixin em Models
316
+
317
+ ```python
318
+ # myapp/models.py
319
+ from django.db import models
320
+ from shared_msg.mixins.contact import ContactMixin
321
+
322
+ class Cliente(ContactMixin, models.Model):
323
+ """Model que possui contato vinculado"""
324
+
325
+ nome = models.CharField(max_length=200)
326
+ empresa = models.CharField(max_length=200)
327
+
328
+ def __str__(self):
329
+ return self.nome
330
+
331
+ # Uso
332
+ cliente = Cliente.objects.get(id=1)
333
+
334
+ # Enviar email para o contato do cliente
335
+ cliente.send_message(
336
+ type=MessageTypes.EMAIL,
337
+ template='emails/invoice.html',
338
+ context={'cliente': cliente.nome, 'valor': 'R$ 500,00'},
339
+ subject='Sua fatura chegou!',
340
+ )
341
+
342
+ # Enviar SMS
343
+ cliente.send_message(
344
+ type=MessageTypes.SMS,
345
+ template='sms/reminder.txt',
346
+ context={'nome': cliente.nome},
347
+ )
348
+ ```
349
+
350
+ ### 3. Templates de Mensagem
351
+
352
+ #### Email Template (HTML)
353
+ ```html
354
+ <!-- templates/emails/welcome.html -->
355
+ <!DOCTYPE html>
356
+ <html>
357
+ <body>
358
+ <h1>Olá, {{ name }}!</h1>
359
+ <p>Bem-vindo à {{ company }}.</p>
360
+ <p>Estamos felizes em tê-lo conosco!</p>
361
+ </body>
362
+ </html>
363
+ ```
364
+
365
+ #### SMS Template (TXT)
366
+ ```
367
+ {# templates/sms/verification_code.txt #}
368
+ Seu código de verificação é: {{ code }}. Válido por 5 minutos.
369
+ ```
370
+
371
+ #### WhatsApp Template (HTML)
372
+ ```html
373
+ <!-- templates/whatsapp/order_confirmation.html -->
374
+ Seu pedido {{ order_number }} foi confirmado! Total: {{ total }}
375
+ ```
376
+
377
+ ---
378
+
379
+ ## 🔍 API Reference
380
+
381
+ ### Models
382
+
383
+ #### Contact
384
+ ```python
385
+ from shared_msg.models import Contact
386
+
387
+ # Campos
388
+ contact.id
389
+ contact.name
390
+ ```
391
+
392
+ #### Email
393
+ ```python
394
+ from shared_msg.models import Email
395
+
396
+ # Campos
397
+ email.id
398
+ email.email # Endereço de email
399
+ email.contact_id # FK para Contact
400
+ ```
401
+
402
+ #### Phone
403
+ ```python
404
+ from shared_msg.models import Phone
405
+
406
+ # Campos
407
+ phone.id
408
+ phone.phone_type # 'whatsapp' ou 'sms'
409
+ phone.number # Número do telefone
410
+ phone.contact_id # FK para Contact
411
+
412
+ # Choices
413
+ Phone.PhoneType.WHATSAPP
414
+ Phone.PhoneType.SMS
415
+ ```
416
+
417
+ #### Message
418
+ ```python
419
+ from shared_msg.models import Message
420
+
421
+ # Campos
422
+ message.id
423
+ message.contact_id # FK para Contact
424
+ message.status # 'pending', 'sent', 'failed'
425
+ message.type # 'email', 'sms', 'whatsapp'
426
+ message.template # Nome do template usado
427
+ message.related_to # ID opcional para vincular a outro objeto
428
+
429
+ # Choices
430
+ Message.Types.EMAIL
431
+ Message.Types.SMS
432
+ Message.Types.WHATSAPP
433
+
434
+ Message.Status.PENDING
435
+ Message.Status.SENT
436
+ Message.Status.FAILED
437
+ ```
438
+
439
+ ### MessageTypes
440
+
441
+ ```python
442
+ from shared_msg.message.utils import MessageTypes
443
+
444
+ MessageTypes.EMAIL # 'email'
445
+ MessageTypes.SMS # 'sms'
446
+ MessageTypes.WHATSAPP # 'whatsapp'
447
+ MessageTypes.TYPES # ['email', 'sms', 'whatsapp']
448
+ ```
449
+
450
+ ### Services
451
+
452
+ #### TwilioService
453
+
454
+ ```python
455
+ from shared_msg.message.services.twilio_service import TwilioService
456
+
457
+ service = TwilioService()
458
+
459
+ # Enviar SMS texto
460
+ service.send_sms_text(
461
+ phone='+5511999999999',
462
+ body='Sua mensagem aqui',
463
+ )
464
+
465
+ # Enviar WhatsApp com template
466
+ service.send_whatsapp_template(
467
+ phone='+5511999999999',
468
+ content_sid='HXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
469
+ variables={'1': 'valor1', '2': 'valor2'},
470
+ body='Texto fallback opcional',
471
+ )
472
+ ```
473
+
474
+ ### Utils
475
+
476
+ #### build_email_message
477
+
478
+ ```python
479
+ from shared_msg.message.utils.build_email_message import build_email_message
480
+
481
+ email_message = build_email_message(
482
+ emails=['user1@email.com', 'user2@email.com'],
483
+ from_email='noreply@empresa.com',
484
+ subject='Assunto do email',
485
+ context={'name': 'João'},
486
+ template='emails/template.html',
487
+ )
488
+
489
+ email_message.send() # Envia o email
490
+ ```
491
+
492
+ #### build_sms_message
493
+
494
+ ```python
495
+ from shared_msg.message.utils.build_sms_message import build_sms_message
496
+
497
+ body = build_sms_message(
498
+ template='sms/verification.txt',
499
+ context={'code': '123456'},
500
+ )
501
+ # Retorna: "Seu código é: 123456. Válido por 5 minutos."
502
+ ```
503
+
504
+ #### build_whatsapp_message
505
+
506
+ ```python
507
+ from shared_msg.message.utils.build_whatsapp_message import build_whatsapp_message
508
+
509
+ content_sid, variables, fallback_body = build_whatsapp_message(
510
+ template='whatsapp/welcome.html',
511
+ message_type='whatsapp',
512
+ context={
513
+ 'name': 'João',
514
+ 'twilio_variables': {'1': 'João'},
515
+ },
516
+ )
517
+ ```
518
+
519
+ ### Mixins
520
+
521
+ #### ContactMixin
522
+
523
+ ```python
524
+ from shared_msg.mixins.contact import ContactMixin
525
+
526
+ class MeuModel(ContactMixin, models.Model):
527
+ # Adiciona campo contact_id ao model
528
+ pass
529
+
530
+ # Uso
531
+ obj = MeuModel.objects.get(id=1)
532
+ obj.contact # Acessa o Contact relacionado
533
+ obj.send_message(...) # Envia mensagem para o contato
534
+ ```
535
+
536
+ ### Router
537
+
538
+ #### SharedMsgRouter
539
+
540
+ ```python
541
+ # settings.py
542
+ DATABASE_ROUTERS = ['shared_msg.router.SharedMsgRouter']
543
+ ```
544
+
545
+ Direciona automaticamente todas as queries dos models `shared_msg` para o banco configurado em `SHARED_MSG_DEFAULT_DB`.
546
+
547
+ ---
548
+
549
+ ## 🔧 Configurações Disponíveis
550
+
551
+ | Configuração | Padrão | Descrição |
552
+ |--------------|--------|-----------|
553
+ | `SHARED_MSG_DEFAULT_DB` | `'auth_db'` | Nome do banco para models shared_msg |
554
+ | `SHARED_MSG_MESSAGE_TABLE` | `'message_message'` | Nome da tabela de mensagens |
555
+ | `SHARED_MSG_CONTACT_TABLE` | `'message_contact'` | Nome da tabela de contatos |
556
+ | `SHARED_MSG_EMAIL_TABLE` | `'message_email'` | Nome da tabela de emails |
557
+ | `SHARED_MSG_PHONE_TABLE` | `'message_phone'` | Nome da tabela de telefones |
558
+ | `TWILIO_ACCOUNT_SID` | - | Account SID do Twilio |
559
+ | `TWILIO_AUTH_TOKEN` | - | Auth Token do Twilio |
560
+ | `TWILIO_SMS_FROM` | - | Número de envio SMS |
561
+ | `TWILIO_WHATSAPP_FROM` | - | Número de envio WhatsApp |
562
+ | `TWILIO_CONTENT_SIDS` | `{}` | Mapa de templates → Content SIDs |
563
+ | `DEFAULT_FROM_EMAIL` | - | Email padrão para envio |
564
+
565
+ ---
566
+
567
+ ## 📝 Licença
568
+
569
+ Este projeto está licenciado sob a Licença MIT - veja o arquivo [LICENSE](LICENSE) para detalhes.