ccai-python 1.0.0__tar.gz → 1.0.1__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.
- ccai_python-1.0.1/PKG-INFO +312 -0
- ccai_python-1.0.1/README.md +291 -0
- {ccai_python-1.0.0 → ccai_python-1.0.1}/pyproject.toml +1 -1
- ccai_python-1.0.1/setup.py +26 -0
- ccai_python-1.0.1/src/ccai_python/__init__.py +39 -0
- ccai_python-1.0.1/src/ccai_python/ccai.py +205 -0
- ccai_python-1.0.1/src/ccai_python/contact_service.py +33 -0
- ccai_python-1.0.1/src/ccai_python/contact_test.py +30 -0
- ccai_python-1.0.1/src/ccai_python/email_send.py +30 -0
- ccai_python-1.0.1/src/ccai_python/email_service.py +202 -0
- ccai_python-1.0.1/src/ccai_python/mms_send.py +30 -0
- {ccai_python-1.0.0 → ccai_python-1.0.1}/src/ccai_python/sms/__init__.py +2 -1
- ccai_python-1.0.1/src/ccai_python/sms/mms.py +452 -0
- {ccai_python-1.0.0 → ccai_python-1.0.1}/src/ccai_python/sms/sms.py +38 -88
- ccai_python-1.0.1/src/ccai_python/sms_send.py +27 -0
- ccai_python-1.0.1/src/ccai_python/webhook.py +110 -0
- ccai_python-1.0.1/src/ccai_python/webhook_handler_example.py +46 -0
- ccai_python-1.0.1/src/ccai_python/webhook_test.py +37 -0
- ccai_python-1.0.1/src/ccai_python.egg-info/PKG-INFO +312 -0
- {ccai_python-1.0.0 → ccai_python-1.0.1}/src/ccai_python.egg-info/SOURCES.txt +13 -0
- ccai_python-1.0.1/src/ccai_python.egg-info/top_level.txt +1 -0
- ccai_python-1.0.1/tests/test_contact.py +115 -0
- ccai_python-1.0.1/tests/test_mms.py +527 -0
- {ccai_python-1.0.0 → ccai_python-1.0.1}/tests/test_sms.py +10 -9
- ccai_python-1.0.0/PKG-INFO +0 -83
- ccai_python-1.0.0/README.md +0 -63
- ccai_python-1.0.0/src/ccai_python/__init__.py +0 -21
- ccai_python-1.0.0/src/ccai_python/ccai.py +0 -149
- ccai_python-1.0.0/src/ccai_python.egg-info/PKG-INFO +0 -83
- ccai_python-1.0.0/src/ccai_python.egg-info/top_level.txt +0 -3
- {ccai_python-1.0.0 → ccai_python-1.0.1}/setup.cfg +0 -0
- {ccai_python-1.0.0 → ccai_python-1.0.1}/src/ccai_python/examples/async_example.py +0 -0
- {ccai_python-1.0.0 → ccai_python-1.0.1}/src/ccai_python/examples/basic_example.py +0 -0
- {ccai_python-1.0.0 → ccai_python-1.0.1}/src/ccai_python.egg-info/dependency_links.txt +0 -0
- {ccai_python-1.0.0 → ccai_python-1.0.1}/src/ccai_python.egg-info/requires.txt +0 -0
- {ccai_python-1.0.0 → ccai_python-1.0.1}/tests/test_ccai.py +0 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ccai-python
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Python client for CloudContactAI API
|
|
5
|
+
Author: CloudContactAI LLC
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cloudcontactai/ccai-python
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/cloudcontactai/ccai-python/issues
|
|
9
|
+
Keywords: sms,api,client,cloud,contact,ai,cloudcontactai
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: requests>=2.31.0
|
|
19
|
+
Requires-Dist: pydantic>=2.5.0
|
|
20
|
+
Dynamic: requires-python
|
|
21
|
+
|
|
22
|
+
# CCAI Python Client
|
|
23
|
+
|
|
24
|
+
Version: 1.0.1
|
|
25
|
+
|
|
26
|
+
A Python client for interacting with the CloudContactAI API.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install ccai-python
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
### SMS
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from ccai_python import CCAI
|
|
40
|
+
|
|
41
|
+
# Initialize the client
|
|
42
|
+
ccai = CCAI(
|
|
43
|
+
client_id="YOUR-CLIENT-ID",
|
|
44
|
+
api_key="YOUR-API-KEY"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Send a single SMS
|
|
48
|
+
response = ccai.sms.send_single(
|
|
49
|
+
first_name="John",
|
|
50
|
+
last_name="Doe",
|
|
51
|
+
phone="+15551234567",
|
|
52
|
+
message="Hello ${first_name}, this is a test message!",
|
|
53
|
+
title="Test Campaign"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
print(f"Message sent with ID: {response.id}")
|
|
57
|
+
|
|
58
|
+
# Send to multiple recipients
|
|
59
|
+
accounts = [
|
|
60
|
+
{"first_name": "John", "last_name": "Doe", "phone": "+15551234567"},
|
|
61
|
+
{"first_name": "Jane", "last_name": "Smith", "phone": "+15559876543"}
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
campaign_response = ccai.sms.send(
|
|
65
|
+
accounts=accounts,
|
|
66
|
+
message="Hello ${first_name} ${last_name}, this is a test message!",
|
|
67
|
+
title="Bulk Test Campaign"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
print(f"Campaign sent with ID: {campaign_response.campaign_id}")
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### MMS
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from ccai_python import CCAI, Account, SMSOptions
|
|
77
|
+
|
|
78
|
+
# Initialize the client
|
|
79
|
+
ccai = CCAI(
|
|
80
|
+
client_id="YOUR-CLIENT-ID",
|
|
81
|
+
api_key="YOUR-API-KEY"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Define a progress callback
|
|
85
|
+
def track_progress(status):
|
|
86
|
+
print(f"Progress: {status}")
|
|
87
|
+
|
|
88
|
+
# Create options with progress tracking
|
|
89
|
+
options = SMSOptions(
|
|
90
|
+
timeout=60,
|
|
91
|
+
retries=3,
|
|
92
|
+
on_progress=track_progress
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
# Complete MMS workflow (get URL, upload image, send MMS)
|
|
96
|
+
image_path = "path/to/your/image.jpg"
|
|
97
|
+
content_type = "image/jpeg"
|
|
98
|
+
|
|
99
|
+
# Define recipient
|
|
100
|
+
account = Account(
|
|
101
|
+
first_name="John",
|
|
102
|
+
last_name="Doe",
|
|
103
|
+
phone="+15551234567" # Use E.164 format
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Send MMS with image in one step
|
|
107
|
+
response = ccai.mms.send_with_image(
|
|
108
|
+
image_path=image_path,
|
|
109
|
+
content_type=content_type,
|
|
110
|
+
accounts=[account],
|
|
111
|
+
message="Hello ${first_name}, check out this image!",
|
|
112
|
+
title="MMS Campaign Example",
|
|
113
|
+
options=options
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
print(f"MMS sent! Campaign ID: {response.campaign_id}")
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Email
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from ccai_python import CCAI, EmailAccount, EmailCampaign
|
|
123
|
+
from datetime import datetime, timedelta
|
|
124
|
+
|
|
125
|
+
# Initialize the client
|
|
126
|
+
ccai = CCAI(
|
|
127
|
+
client_id="YOUR-CLIENT-ID",
|
|
128
|
+
api_key="YOUR-API-KEY"
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
# Send a single email
|
|
132
|
+
response = ccai.email.send_single(
|
|
133
|
+
first_name="John",
|
|
134
|
+
last_name="Doe",
|
|
135
|
+
email="john@example.com",
|
|
136
|
+
subject="Welcome to Our Service",
|
|
137
|
+
message="<p>Hello John,</p><p>Thank you for signing up!</p>",
|
|
138
|
+
sender_email="noreply@yourcompany.com",
|
|
139
|
+
reply_email="support@yourcompany.com",
|
|
140
|
+
sender_name="Your Company",
|
|
141
|
+
title="Welcome Email"
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
print(f"Email sent with ID: {response.id}")
|
|
145
|
+
|
|
146
|
+
# Send email campaign to multiple recipients
|
|
147
|
+
accounts = [
|
|
148
|
+
EmailAccount(
|
|
149
|
+
first_name="John",
|
|
150
|
+
last_name="Doe",
|
|
151
|
+
email="john@example.com",
|
|
152
|
+
phone=""
|
|
153
|
+
),
|
|
154
|
+
EmailAccount(
|
|
155
|
+
first_name="Jane",
|
|
156
|
+
last_name="Smith",
|
|
157
|
+
email="jane@example.com",
|
|
158
|
+
phone=""
|
|
159
|
+
)
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
campaign = EmailCampaign(
|
|
163
|
+
subject="Monthly Newsletter",
|
|
164
|
+
title="July 2025 Newsletter",
|
|
165
|
+
message="<h1>Hello ${firstName}!</h1><p>Here's our monthly update...</p>",
|
|
166
|
+
sender_email="newsletter@yourcompany.com",
|
|
167
|
+
reply_email="support@yourcompany.com",
|
|
168
|
+
sender_name="Your Company Newsletter",
|
|
169
|
+
accounts=accounts
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
response = ccai.email.send_campaign(campaign)
|
|
173
|
+
print(f"Email campaign sent: {response}")
|
|
174
|
+
|
|
175
|
+
# Schedule an email for future delivery
|
|
176
|
+
tomorrow = datetime.now() + timedelta(days=1)
|
|
177
|
+
tomorrow = tomorrow.replace(hour=10, minute=0, second=0, microsecond=0)
|
|
178
|
+
|
|
179
|
+
scheduled_campaign = EmailCampaign(
|
|
180
|
+
subject="Scheduled Email",
|
|
181
|
+
title="Future Email",
|
|
182
|
+
message="<p>This email was scheduled in advance!</p>",
|
|
183
|
+
sender_email="scheduled@yourcompany.com",
|
|
184
|
+
reply_email="support@yourcompany.com",
|
|
185
|
+
sender_name="Your Company",
|
|
186
|
+
accounts=[accounts[0]],
|
|
187
|
+
scheduled_timestamp=tomorrow.isoformat(),
|
|
188
|
+
scheduled_timezone="America/New_York"
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
response = ccai.email.send_campaign(scheduled_campaign)
|
|
192
|
+
print(f"Email scheduled: {response}")
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Contacts
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from ccai_python import CCAI
|
|
199
|
+
|
|
200
|
+
# Initialize the client
|
|
201
|
+
ccai = CCAI(
|
|
202
|
+
client_id="YOUR-CLIENT-ID",
|
|
203
|
+
api_key="YOUR-API-KEY"
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
# Set do not text status using contact ID
|
|
207
|
+
response = ccai.contact.set_do_not_text(
|
|
208
|
+
do_not_text=True,
|
|
209
|
+
contact_id="your-contact-id"
|
|
210
|
+
)
|
|
211
|
+
print(f"Contact {response.contact_id} do not text set to {response.do_not_text}")
|
|
212
|
+
|
|
213
|
+
# Set do not text status using phone number
|
|
214
|
+
response = ccai.contact.set_do_not_text(
|
|
215
|
+
do_not_text=True,
|
|
216
|
+
phone="+15551234567"
|
|
217
|
+
)
|
|
218
|
+
print(f"Contact {response.contact_id} ({response.phone}) do not text set to {response.do_not_text}")
|
|
219
|
+
|
|
220
|
+
# Remove do not text status from a contact
|
|
221
|
+
response = ccai.contact.set_do_not_text(
|
|
222
|
+
do_not_text=False,
|
|
223
|
+
contact_id="your-contact-id"
|
|
224
|
+
)
|
|
225
|
+
print(f"Contact {response.contact_id} do not text removed: {response.do_not_text}")
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Webhooks
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from ccai_python import CCAI, WebhookConfig, WebhookEventType
|
|
232
|
+
|
|
233
|
+
# Initialize the client
|
|
234
|
+
ccai = CCAI(
|
|
235
|
+
client_id="YOUR-CLIENT-ID",
|
|
236
|
+
api_key="YOUR-API-KEY"
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
# Register a webhook
|
|
240
|
+
config = WebhookConfig(
|
|
241
|
+
url="https://your-domain.com/api/ccai-webhook",
|
|
242
|
+
events=[WebhookEventType.MESSAGE_SENT, WebhookEventType.MESSAGE_RECEIVED],
|
|
243
|
+
secret="your-webhook-secret"
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
webhook = ccai.webhook.register(config)
|
|
247
|
+
print(f"Webhook registered with ID: {webhook.id}")
|
|
248
|
+
|
|
249
|
+
# List all webhooks
|
|
250
|
+
webhooks = ccai.webhook.list()
|
|
251
|
+
print(f"Found {len(webhooks)} webhooks")
|
|
252
|
+
|
|
253
|
+
# Update a webhook
|
|
254
|
+
update_data = {
|
|
255
|
+
"events": [WebhookEventType.MESSAGE_RECEIVED]
|
|
256
|
+
}
|
|
257
|
+
updated_webhook = ccai.webhook.update(webhook.id, update_data)
|
|
258
|
+
print(f"Webhook updated: {updated_webhook}")
|
|
259
|
+
|
|
260
|
+
# Delete a webhook
|
|
261
|
+
result = ccai.webhook.delete(webhook.id)
|
|
262
|
+
print(f"Webhook deleted: {result}")
|
|
263
|
+
|
|
264
|
+
# Create a webhook handler for web frameworks
|
|
265
|
+
def handle_message_sent(event):
|
|
266
|
+
print(f"Message sent: {event.message} to {event.to}")
|
|
267
|
+
|
|
268
|
+
def handle_message_received(event):
|
|
269
|
+
print(f"Message received: {event.message} from {event.from_}")
|
|
270
|
+
|
|
271
|
+
handlers = {
|
|
272
|
+
'on_message_sent': handle_message_sent,
|
|
273
|
+
'on_message_received': handle_message_received
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
webhook_handler = ccai.webhook.create_handler(handlers)
|
|
277
|
+
|
|
278
|
+
# Use with Flask
|
|
279
|
+
from flask import Flask, request, jsonify
|
|
280
|
+
|
|
281
|
+
app = Flask(__name__)
|
|
282
|
+
|
|
283
|
+
@app.route('/api/ccai-webhook', methods=['POST'])
|
|
284
|
+
def handle_webhook():
|
|
285
|
+
payload = request.get_json()
|
|
286
|
+
result = webhook_handler(payload)
|
|
287
|
+
return jsonify(result)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Features
|
|
291
|
+
|
|
292
|
+
- Send SMS messages to single or multiple recipients
|
|
293
|
+
- Send MMS messages with images
|
|
294
|
+
- Send Email campaigns with HTML content
|
|
295
|
+
- Schedule emails for future delivery
|
|
296
|
+
- Webhook management (register, update, list, delete)
|
|
297
|
+
- Webhook event handling for web frameworks
|
|
298
|
+
- Upload images to S3 with signed URLs
|
|
299
|
+
- Variable substitution in messages
|
|
300
|
+
- Progress tracking callbacks
|
|
301
|
+
- Type hints for better IDE integration
|
|
302
|
+
- Comprehensive error handling
|
|
303
|
+
|
|
304
|
+
## Requirements
|
|
305
|
+
|
|
306
|
+
- Python 3.10 or higher
|
|
307
|
+
- `requests` library
|
|
308
|
+
- `pydantic` library
|
|
309
|
+
|
|
310
|
+
## License
|
|
311
|
+
|
|
312
|
+
MIT
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# CCAI Python Client
|
|
2
|
+
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
|
|
5
|
+
A Python client for interacting with the CloudContactAI API.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install ccai-python
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### SMS
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from ccai_python import CCAI
|
|
19
|
+
|
|
20
|
+
# Initialize the client
|
|
21
|
+
ccai = CCAI(
|
|
22
|
+
client_id="YOUR-CLIENT-ID",
|
|
23
|
+
api_key="YOUR-API-KEY"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
# Send a single SMS
|
|
27
|
+
response = ccai.sms.send_single(
|
|
28
|
+
first_name="John",
|
|
29
|
+
last_name="Doe",
|
|
30
|
+
phone="+15551234567",
|
|
31
|
+
message="Hello ${first_name}, this is a test message!",
|
|
32
|
+
title="Test Campaign"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
print(f"Message sent with ID: {response.id}")
|
|
36
|
+
|
|
37
|
+
# Send to multiple recipients
|
|
38
|
+
accounts = [
|
|
39
|
+
{"first_name": "John", "last_name": "Doe", "phone": "+15551234567"},
|
|
40
|
+
{"first_name": "Jane", "last_name": "Smith", "phone": "+15559876543"}
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
campaign_response = ccai.sms.send(
|
|
44
|
+
accounts=accounts,
|
|
45
|
+
message="Hello ${first_name} ${last_name}, this is a test message!",
|
|
46
|
+
title="Bulk Test Campaign"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
print(f"Campaign sent with ID: {campaign_response.campaign_id}")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### MMS
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from ccai_python import CCAI, Account, SMSOptions
|
|
56
|
+
|
|
57
|
+
# Initialize the client
|
|
58
|
+
ccai = CCAI(
|
|
59
|
+
client_id="YOUR-CLIENT-ID",
|
|
60
|
+
api_key="YOUR-API-KEY"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Define a progress callback
|
|
64
|
+
def track_progress(status):
|
|
65
|
+
print(f"Progress: {status}")
|
|
66
|
+
|
|
67
|
+
# Create options with progress tracking
|
|
68
|
+
options = SMSOptions(
|
|
69
|
+
timeout=60,
|
|
70
|
+
retries=3,
|
|
71
|
+
on_progress=track_progress
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Complete MMS workflow (get URL, upload image, send MMS)
|
|
75
|
+
image_path = "path/to/your/image.jpg"
|
|
76
|
+
content_type = "image/jpeg"
|
|
77
|
+
|
|
78
|
+
# Define recipient
|
|
79
|
+
account = Account(
|
|
80
|
+
first_name="John",
|
|
81
|
+
last_name="Doe",
|
|
82
|
+
phone="+15551234567" # Use E.164 format
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# Send MMS with image in one step
|
|
86
|
+
response = ccai.mms.send_with_image(
|
|
87
|
+
image_path=image_path,
|
|
88
|
+
content_type=content_type,
|
|
89
|
+
accounts=[account],
|
|
90
|
+
message="Hello ${first_name}, check out this image!",
|
|
91
|
+
title="MMS Campaign Example",
|
|
92
|
+
options=options
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
print(f"MMS sent! Campaign ID: {response.campaign_id}")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Email
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from ccai_python import CCAI, EmailAccount, EmailCampaign
|
|
102
|
+
from datetime import datetime, timedelta
|
|
103
|
+
|
|
104
|
+
# Initialize the client
|
|
105
|
+
ccai = CCAI(
|
|
106
|
+
client_id="YOUR-CLIENT-ID",
|
|
107
|
+
api_key="YOUR-API-KEY"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Send a single email
|
|
111
|
+
response = ccai.email.send_single(
|
|
112
|
+
first_name="John",
|
|
113
|
+
last_name="Doe",
|
|
114
|
+
email="john@example.com",
|
|
115
|
+
subject="Welcome to Our Service",
|
|
116
|
+
message="<p>Hello John,</p><p>Thank you for signing up!</p>",
|
|
117
|
+
sender_email="noreply@yourcompany.com",
|
|
118
|
+
reply_email="support@yourcompany.com",
|
|
119
|
+
sender_name="Your Company",
|
|
120
|
+
title="Welcome Email"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
print(f"Email sent with ID: {response.id}")
|
|
124
|
+
|
|
125
|
+
# Send email campaign to multiple recipients
|
|
126
|
+
accounts = [
|
|
127
|
+
EmailAccount(
|
|
128
|
+
first_name="John",
|
|
129
|
+
last_name="Doe",
|
|
130
|
+
email="john@example.com",
|
|
131
|
+
phone=""
|
|
132
|
+
),
|
|
133
|
+
EmailAccount(
|
|
134
|
+
first_name="Jane",
|
|
135
|
+
last_name="Smith",
|
|
136
|
+
email="jane@example.com",
|
|
137
|
+
phone=""
|
|
138
|
+
)
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
campaign = EmailCampaign(
|
|
142
|
+
subject="Monthly Newsletter",
|
|
143
|
+
title="July 2025 Newsletter",
|
|
144
|
+
message="<h1>Hello ${firstName}!</h1><p>Here's our monthly update...</p>",
|
|
145
|
+
sender_email="newsletter@yourcompany.com",
|
|
146
|
+
reply_email="support@yourcompany.com",
|
|
147
|
+
sender_name="Your Company Newsletter",
|
|
148
|
+
accounts=accounts
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
response = ccai.email.send_campaign(campaign)
|
|
152
|
+
print(f"Email campaign sent: {response}")
|
|
153
|
+
|
|
154
|
+
# Schedule an email for future delivery
|
|
155
|
+
tomorrow = datetime.now() + timedelta(days=1)
|
|
156
|
+
tomorrow = tomorrow.replace(hour=10, minute=0, second=0, microsecond=0)
|
|
157
|
+
|
|
158
|
+
scheduled_campaign = EmailCampaign(
|
|
159
|
+
subject="Scheduled Email",
|
|
160
|
+
title="Future Email",
|
|
161
|
+
message="<p>This email was scheduled in advance!</p>",
|
|
162
|
+
sender_email="scheduled@yourcompany.com",
|
|
163
|
+
reply_email="support@yourcompany.com",
|
|
164
|
+
sender_name="Your Company",
|
|
165
|
+
accounts=[accounts[0]],
|
|
166
|
+
scheduled_timestamp=tomorrow.isoformat(),
|
|
167
|
+
scheduled_timezone="America/New_York"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
response = ccai.email.send_campaign(scheduled_campaign)
|
|
171
|
+
print(f"Email scheduled: {response}")
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Contacts
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
from ccai_python import CCAI
|
|
178
|
+
|
|
179
|
+
# Initialize the client
|
|
180
|
+
ccai = CCAI(
|
|
181
|
+
client_id="YOUR-CLIENT-ID",
|
|
182
|
+
api_key="YOUR-API-KEY"
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
# Set do not text status using contact ID
|
|
186
|
+
response = ccai.contact.set_do_not_text(
|
|
187
|
+
do_not_text=True,
|
|
188
|
+
contact_id="your-contact-id"
|
|
189
|
+
)
|
|
190
|
+
print(f"Contact {response.contact_id} do not text set to {response.do_not_text}")
|
|
191
|
+
|
|
192
|
+
# Set do not text status using phone number
|
|
193
|
+
response = ccai.contact.set_do_not_text(
|
|
194
|
+
do_not_text=True,
|
|
195
|
+
phone="+15551234567"
|
|
196
|
+
)
|
|
197
|
+
print(f"Contact {response.contact_id} ({response.phone}) do not text set to {response.do_not_text}")
|
|
198
|
+
|
|
199
|
+
# Remove do not text status from a contact
|
|
200
|
+
response = ccai.contact.set_do_not_text(
|
|
201
|
+
do_not_text=False,
|
|
202
|
+
contact_id="your-contact-id"
|
|
203
|
+
)
|
|
204
|
+
print(f"Contact {response.contact_id} do not text removed: {response.do_not_text}")
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Webhooks
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
from ccai_python import CCAI, WebhookConfig, WebhookEventType
|
|
211
|
+
|
|
212
|
+
# Initialize the client
|
|
213
|
+
ccai = CCAI(
|
|
214
|
+
client_id="YOUR-CLIENT-ID",
|
|
215
|
+
api_key="YOUR-API-KEY"
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# Register a webhook
|
|
219
|
+
config = WebhookConfig(
|
|
220
|
+
url="https://your-domain.com/api/ccai-webhook",
|
|
221
|
+
events=[WebhookEventType.MESSAGE_SENT, WebhookEventType.MESSAGE_RECEIVED],
|
|
222
|
+
secret="your-webhook-secret"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
webhook = ccai.webhook.register(config)
|
|
226
|
+
print(f"Webhook registered with ID: {webhook.id}")
|
|
227
|
+
|
|
228
|
+
# List all webhooks
|
|
229
|
+
webhooks = ccai.webhook.list()
|
|
230
|
+
print(f"Found {len(webhooks)} webhooks")
|
|
231
|
+
|
|
232
|
+
# Update a webhook
|
|
233
|
+
update_data = {
|
|
234
|
+
"events": [WebhookEventType.MESSAGE_RECEIVED]
|
|
235
|
+
}
|
|
236
|
+
updated_webhook = ccai.webhook.update(webhook.id, update_data)
|
|
237
|
+
print(f"Webhook updated: {updated_webhook}")
|
|
238
|
+
|
|
239
|
+
# Delete a webhook
|
|
240
|
+
result = ccai.webhook.delete(webhook.id)
|
|
241
|
+
print(f"Webhook deleted: {result}")
|
|
242
|
+
|
|
243
|
+
# Create a webhook handler for web frameworks
|
|
244
|
+
def handle_message_sent(event):
|
|
245
|
+
print(f"Message sent: {event.message} to {event.to}")
|
|
246
|
+
|
|
247
|
+
def handle_message_received(event):
|
|
248
|
+
print(f"Message received: {event.message} from {event.from_}")
|
|
249
|
+
|
|
250
|
+
handlers = {
|
|
251
|
+
'on_message_sent': handle_message_sent,
|
|
252
|
+
'on_message_received': handle_message_received
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
webhook_handler = ccai.webhook.create_handler(handlers)
|
|
256
|
+
|
|
257
|
+
# Use with Flask
|
|
258
|
+
from flask import Flask, request, jsonify
|
|
259
|
+
|
|
260
|
+
app = Flask(__name__)
|
|
261
|
+
|
|
262
|
+
@app.route('/api/ccai-webhook', methods=['POST'])
|
|
263
|
+
def handle_webhook():
|
|
264
|
+
payload = request.get_json()
|
|
265
|
+
result = webhook_handler(payload)
|
|
266
|
+
return jsonify(result)
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Features
|
|
270
|
+
|
|
271
|
+
- Send SMS messages to single or multiple recipients
|
|
272
|
+
- Send MMS messages with images
|
|
273
|
+
- Send Email campaigns with HTML content
|
|
274
|
+
- Schedule emails for future delivery
|
|
275
|
+
- Webhook management (register, update, list, delete)
|
|
276
|
+
- Webhook event handling for web frameworks
|
|
277
|
+
- Upload images to S3 with signed URLs
|
|
278
|
+
- Variable substitution in messages
|
|
279
|
+
- Progress tracking callbacks
|
|
280
|
+
- Type hints for better IDE integration
|
|
281
|
+
- Comprehensive error handling
|
|
282
|
+
|
|
283
|
+
## Requirements
|
|
284
|
+
|
|
285
|
+
- Python 3.10 or higher
|
|
286
|
+
- `requests` library
|
|
287
|
+
- `pydantic` library
|
|
288
|
+
|
|
289
|
+
## License
|
|
290
|
+
|
|
291
|
+
MIT
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name='ccai', # 🟢 CLI command will be `ccai`
|
|
5
|
+
version='1.0.1',
|
|
6
|
+
description='A CLI and Python client for sending SMS via CloudContactAI',
|
|
7
|
+
author='CloudContactAI LLC',
|
|
8
|
+
license='MIT',
|
|
9
|
+
packages=find_packages(where='src'),
|
|
10
|
+
package_dir={'': 'src'},
|
|
11
|
+
install_requires=[
|
|
12
|
+
'requests>=2.31.0',
|
|
13
|
+
'pydantic>=2.5.0'
|
|
14
|
+
],
|
|
15
|
+
entry_points={
|
|
16
|
+
'console_scripts': [
|
|
17
|
+
'ccai = ccai_python.ccai:main',
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
classifiers=[
|
|
21
|
+
'Programming Language :: Python :: 3',
|
|
22
|
+
'License :: OSI Approved :: MIT License',
|
|
23
|
+
'Operating System :: OS Independent',
|
|
24
|
+
],
|
|
25
|
+
python_requires='>=3.8',
|
|
26
|
+
)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Main export file for the CCAI Python module
|
|
3
|
+
|
|
4
|
+
:license: MIT
|
|
5
|
+
:copyright: 2025 CloudContactAI LLC
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .ccai import CCAI, Account, CCAIConfig
|
|
9
|
+
from .sms.sms import SMS, SMSCampaign, SMSResponse, SMSOptions
|
|
10
|
+
from .sms.mms import MMS
|
|
11
|
+
from .email_service import Email, EmailAccount, EmailCampaign, EmailResponse, EmailOptions
|
|
12
|
+
from .webhook import Webhook, WebhookConfig, WebhookEventType, MessageSentEvent, MessageReceivedEvent
|
|
13
|
+
from .contact_service import Contact, ContactDoNotTextRequest, ContactDoNotTextResponse
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
'CCAI',
|
|
17
|
+
'SMS',
|
|
18
|
+
'MMS',
|
|
19
|
+
'Email',
|
|
20
|
+
'Webhook',
|
|
21
|
+
'Account',
|
|
22
|
+
'EmailAccount',
|
|
23
|
+
'CCAIConfig',
|
|
24
|
+
'SMSCampaign',
|
|
25
|
+
'SMSResponse',
|
|
26
|
+
'SMSOptions',
|
|
27
|
+
'EmailCampaign',
|
|
28
|
+
'EmailResponse',
|
|
29
|
+
'EmailOptions',
|
|
30
|
+
'WebhookConfig',
|
|
31
|
+
'WebhookEventType',
|
|
32
|
+
'MessageSentEvent',
|
|
33
|
+
'MessageReceivedEvent',
|
|
34
|
+
'Contact',
|
|
35
|
+
'ContactDoNotTextRequest',
|
|
36
|
+
'ContactDoNotTextResponse'
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
__version__ = '1.0.1'
|