diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..9e4ba06 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,54 @@ +name: Documentation + +on: + push: + branches: [main, develop] + pull_request: + branches: [main] + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e ".[docs]" + + - name: Build documentation + run: | + mkdocs build --clean --strict + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: site + + deploy: + needs: build + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/README.md b/README.md index d6940bc..446ac02 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![PyPI version](https://badge.fury.io/py/devo-global-comms-python.svg)](https://badge.fury.io/py/devo-global-comms-python) [![Python Support](https://img.shields.io/pypi/pyversions/devo-global-comms-python.svg)](https://pypi.org/project/devo-global-comms-python/) +[![Documentation](https://img.shields.io/badge/docs-github%20pages-blue)](https://devotel.github.io/devo-global-comms-python/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) A Python SDK for the Devo Global Communications API, supporting SMS, Email, WhatsApp, RCS, and Contact management. @@ -14,7 +15,6 @@ A Python SDK for the Devo Global Communications API, supporting SMS, Email, What - **Sync-first design**: Simple, blocking API calls - **Type safety**: Full Pydantic model support with type hints - **Minimal dependencies**: Only requires `requests` and `pydantic` -- **Resource-based pattern**: Familiar API design - **Python 3.8+ support**: Compatible with modern Python versions ## Installation @@ -32,26 +32,28 @@ from devo_global_comms_python import DevoClient client = DevoClient(api_key="your-api-key") # Send an SMS -sms = client.sms.send( - to="+1234567890", - body="Hello, World!" +sms_response = client.sms.send_sms( + recipient="+1234567890", + message="Hello, World!", + sender="+1987654321" ) -print(f"SMS sent with SID: {sms.sid}") +print(f"SMS sent with ID: {sms_response.id}") # Send an email -email = client.email.send( - to="recipient@example.com", +email_response = client.email.send_email( + recipient="recipient@example.com", subject="Hello from Devo!", - body="This is a test email from the Devo SDK." + content="This is a test email from the Devo SDK.", + sender_email="sender@example.com" ) -print(f"Email sent with ID: {email.id}") +print(f"Email sent with ID: {email_response.id}") # Send a WhatsApp message -whatsapp = client.whatsapp.send_text( - to="+1234567890", - text="Hello via WhatsApp!" +whatsapp_response = client.whatsapp.send_text_message( + recipient="+1234567890", + message="Hello via WhatsApp!" ) -print(f"WhatsApp message sent with ID: {whatsapp.id}") +print(f"WhatsApp message sent with ID: {whatsapp_response.id}") ``` ## Authentication @@ -64,205 +66,6 @@ from devo_global_comms_python import DevoClient client = DevoClient(api_key="your-api-key") ``` -## Usage Examples - -### SMS Messages - -```python -# Send a simple SMS -message = client.sms.send( - to="+1234567890", - body="Your verification code is: 123456" -) - -# Send SMS with custom sender and callback -message = client.sms.send( - to="+1234567890", - body="Hello from Devo!", - from_="+1987654321", - callback_url="https://your-app.com/webhook", - metadata={"campaign": "welcome_series"} -) - -# Get message details -message = client.sms.get("message_sid") -print(f"Status: {message.status}") - -# List recent messages -messages = client.sms.list( - date_sent_after="2024-01-01", - status="delivered", - limit=10 -) -``` - -### Email Messages - -```python -# Send a simple email -email = client.email.send( - to="user@example.com", - subject="Welcome to Devo!", - body="Thank you for signing up for our service." -) - -# Send HTML email with CC and attachments -email = client.email.send( - to="user@example.com", - subject="Monthly Newsletter", - body="Check out our latest updates!", - html_body="

Monthly Newsletter

Check out our latest updates!

", - cc=["manager@example.com"], - reply_to="noreply@example.com", - attachments=[ - { - "filename": "newsletter.pdf", - "content": "base64-encoded-content", - "content_type": "application/pdf" - } - ] -) - -# List emails by recipient -emails = client.email.list( - to="user@example.com", - limit=20 -) -``` - -### WhatsApp Messages - -```python -# Send a text message -message = client.whatsapp.send_text( - to="+1234567890", - text="Hello from WhatsApp!" -) - -# Send a template message -message = client.whatsapp.send_template( - to="+1234567890", - template_name="welcome_message", - language="en", - parameters=["John", "Devo Platform"] -) - -# Get message status -message = client.whatsapp.get("message_id") -print(f"Status: {message.status}") -``` - -### RCS Messages - -```python -# Send a text message -message = client.rcs.send_text( - to="+1234567890", - text="Hello from RCS!" -) - -# Send a rich card -message = client.rcs.send_rich_card( - to="+1234567890", - title="Special Offer", - description="Get 50% off your next purchase!", - media_url="https://example.com/image.jpg", - actions=[ - { - "type": "url", - "text": "Shop Now", - "url": "https://example.com/shop" - } - ] -) -``` - -### Contact Management - -```python -# Create a contact -contact = client.contacts.create( - phone_number="+1234567890", - email="user@example.com", - first_name="John", - last_name="Doe", - company="Acme Corp", - metadata={"source": "website_signup"} -) - -# Update a contact -updated_contact = client.contacts.update( - contact_id=contact.id, - company="New Company Inc.", - metadata={"updated": "2024-01-15"} -) - -# Get contact details -contact = client.contacts.get("contact_id") - -# List contacts -contacts = client.contacts.list( - company="Acme Corp", - limit=50 -) - -# Delete a contact -success = client.contacts.delete("contact_id") -``` - -### Unified Message Management - -```python -# Get any message by ID -message = client.messages.get("message_id") -print(f"Channel: {message.channel}, Status: {message.status}") - -# List messages across all channels -messages = client.messages.list( - channel="sms", # Filter by channel - status="delivered", - date_sent_after="2024-01-01", - limit=100 -) - -# Get detailed delivery status -delivery_status = client.messages.get_delivery_status("message_id") - -# Resend a failed message -resent_message = client.messages.resend("failed_message_id") -``` - -## Error Handling - -The SDK provides specific exception types for different error scenarios: - -```python -from devo_global_comms_python import ( - DevoException, - DevoAPIException, - DevoAuthenticationException, - DevoValidationException, - DevoRateLimitException, - DevoTimeoutException, -) - -try: - message = client.sms.send( - to="invalid-number", - body="Test message" - ) -except DevoValidationException as e: - print(f"Validation error: {e}") -except DevoAuthenticationException as e: - print(f"Authentication failed: {e}") -except DevoRateLimitException as e: - print(f"Rate limit exceeded. Retry after: {e.retry_after}") -except DevoAPIException as e: - print(f"API error [{e.status_code}]: {e}") -except DevoException as e: - print(f"General error: {e}") -``` - ## Configuration ### Client Configuration @@ -270,8 +73,8 @@ except DevoException as e: ```python client = DevoClient( api_key="your-api-key", - timeout=30.0, - max_retries=3, + base_url="https://api.devo.com", # Optional: custom base URL + timeout=30.0, # Optional: request timeout ) ``` @@ -294,36 +97,21 @@ client = DevoClient( ## Models -All API responses are returned as Pydantic models with full type support: +All API responses are returned as Pydantic models with full type support. The SDK includes models for: + +- **SMS**: `SMSQuickSendResponse`, `SenderInfo`, `AvailableNumber` +- **Email**: `EmailSendResponse`, `EmailTemplateResponse` +- **WhatsApp**: `WhatsAppTextResponse`, `WhatsAppMediaResponse` +- **RCS**: `RCSMessage`, `RcsSendMessageSerializer` +- **Contacts**: `ContactSerializer`, `CreateContactDto`, `UpdateContactDto` +- **Contact Groups**: `ContactsGroup`, `CreateContactsGroupDto` +Example usage: ```python -# SMS Message model -class SMSMessage(BaseModel): - sid: str - to: str - from_: Optional[str] - body: str - status: str - date_created: Optional[datetime] - # ... other fields - -# Email Message model -class EmailMessage(BaseModel): - id: str - to: str - subject: str - body: str - status: str - # ... other fields - -# Contact model -class Contact(BaseModel): - id: str - phone_number: Optional[str] - email: Optional[str] - first_name: Optional[str] - last_name: Optional[str] - # ... other fields +# All responses are typed Pydantic models +sms_response = client.sms.send_sms(recipient="+1234567890", message="Hello", sender="+1987654321") +print(f"Message ID: {sms_response.id}") # Type-safe access +print(f"Status: {sms_response.status}") ``` ## Development @@ -384,7 +172,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file ## Support -- **Documentation**: [https://devo-global-comms-python.readthedocs.io](https://devo-global-comms-python.readthedocs.io) +- **Documentation**: [https://devotel.github.io/devo-global-comms-python/](https://devotel.github.io/devo-global-comms-python/) - **Issues**: [GitHub Issues](https://github.com/devotel/devo-global-comms-python/issues) - **Email**: [support@devotel.io](mailto:support@devotel.io) diff --git a/docs/error_handling.md b/docs/error_handling.md new file mode 100644 index 0000000..fc9f608 --- /dev/null +++ b/docs/error_handling.md @@ -0,0 +1,275 @@ +# Error Handling + +The Devo SDK provides comprehensive error handling to help you build robust applications. + +## Exception Types + +The SDK uses a hierarchy of exceptions for different error scenarios: + +```python +from devo_global_comms_python.exceptions import DevoException +``` + +All SDK exceptions inherit from `DevoException`, making it easy to catch any SDK-related error. + +## Basic Error Handling + +### Simple Try-Catch + +```python +from devo_global_comms_python.exceptions import DevoException + +try: + sms_response = client.sms.send_sms( + recipient="+1234567890", + message="Hello!", + sender="+1987654321" + ) + print(f"Success: {sms_response.id}") +except DevoException as e: + print(f"Error: {e}") +``` + +### Checking Response Status + +```python +# Some API responses include status information +sms_response = client.sms.send_sms( + recipient="+1234567890", + message="Hello!", + sender="+1987654321" +) + +# Check if the response indicates an error +if hasattr(sms_response, 'is_error') and sms_response.is_error(): + print(f"API returned error: {sms_response.statusCode}") +else: + print(f"Message sent successfully: {sms_response.id}") +``` + +## Common Error Scenarios + +### Invalid Phone Numbers + +```python +try: + response = client.sms.send_sms( + recipient="invalid-number", # Invalid format + message="Test", + sender="+1987654321" + ) +except DevoException as e: + print(f"Invalid phone number: {e}") +``` + +### Authentication Errors + +```python +# Wrong API key +client = DevoClient(api_key="invalid-key") + +try: + response = client.sms.send_sms( + recipient="+1234567890", + message="Test", + sender="+1987654321" + ) +except DevoException as e: + print(f"Authentication failed: {e}") +``` + +### Missing Required Fields + +```python +from devo_global_comms_python.models.contacts import CreateContactDto + +try: + # Missing required data + contact_data = CreateContactDto() # No required fields + contact = client.services.contacts.create(contact_data) +except DevoException as e: + print(f"Validation error: {e}") +``` + +## Retry Logic + +### Simple Retry Pattern + +```python +import time +from devo_global_comms_python.exceptions import DevoException + +def send_with_retry(client, recipient, message, max_retries=3): + for attempt in range(max_retries): + try: + return client.sms.send_sms( + recipient=recipient, + message=message, + sender="+1987654321" + ) + except DevoException as e: + print(f"Attempt {attempt + 1} failed: {e}") + + if attempt < max_retries - 1: + time.sleep(1) # Wait 1 second before retry + continue + else: + raise # Re-raise the last exception +``` + +### Exponential Backoff + +```python +import time +import random +from devo_global_comms_python.exceptions import DevoException + +def send_with_backoff(client, recipient, message, max_retries=3): + for attempt in range(max_retries): + try: + return client.sms.send_sms( + recipient=recipient, + message=message, + sender="+1987654321" + ) + except DevoException as e: + if attempt < max_retries - 1: + # Exponential backoff with jitter + delay = (2 ** attempt) + random.uniform(0, 1) + print(f"Attempt {attempt + 1} failed, retrying in {delay:.2f}s: {e}") + time.sleep(delay) + continue + else: + raise +``` + +## Graceful Degradation + +### Fallback to Alternative Channels + +```python +from devo_global_comms_python.exceptions import DevoException + +def send_message_with_fallback(client, recipient, message): + """Try SMS first, fallback to WhatsApp if SMS fails.""" + + # Try SMS first + try: + response = client.sms.send_sms( + recipient=recipient, + message=message, + sender="+1987654321" + ) + return {"channel": "sms", "response": response} + + except DevoException as sms_error: + print(f"SMS failed: {sms_error}") + + # Fallback to WhatsApp + try: + response = client.whatsapp.send_text_message( + recipient=recipient, + message=message + ) + return {"channel": "whatsapp", "response": response} + + except DevoException as whatsapp_error: + print(f"WhatsApp also failed: {whatsapp_error}") + raise DevoException("All channels failed") from whatsapp_error + +# Usage +try: + result = send_message_with_fallback(client, "+1234567890", "Important message!") + print(f"Message sent via {result['channel']}: {result['response'].id}") +except DevoException as e: + print(f"Could not send message: {e}") +``` + +## Logging Errors + +### Basic Logging + +```python +import logging +from devo_global_comms_python.exceptions import DevoException + +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +def send_message_with_logging(client, recipient, message): + try: + logger.info(f"Sending SMS to {recipient}") + response = client.sms.send_sms( + recipient=recipient, + message=message, + sender="+1987654321" + ) + logger.info(f"SMS sent successfully: {response.id}") + return response + + except DevoException as e: + logger.error(f"SMS sending failed: {e}", exc_info=True) + raise +``` + +## Best Practices + +### 1. Always Use Try-Catch + +```python +# Good +try: + response = client.sms.send_sms(recipient, message, sender) +except DevoException as e: + handle_error(e) + +# Bad - no error handling +response = client.sms.send_sms(recipient, message, sender) +``` + +### 2. Validate Input Early + +```python +def send_sms_safe(client, recipient, message, sender): + # Validate inputs before making API call + if not recipient or not recipient.startswith('+'): + raise ValueError("Recipient must be in E.164 format") + + if not message or len(message.strip()) == 0: + raise ValueError("Message cannot be empty") + + if not sender or not sender.startswith('+'): + raise ValueError("Sender must be in E.164 format") + + try: + return client.sms.send_sms(recipient, message, sender) + except DevoException as e: + logger.error(f"SMS API error: {e}") + raise +``` + +### 3. Handle Partial Failures + +```python +def send_bulk_messages(client, recipients, message): + results = [] + failed = [] + + for recipient in recipients: + try: + response = client.sms.send_sms(recipient, message, "+1987654321") + results.append({"recipient": recipient, "status": "success", "id": response.id}) + except DevoException as e: + failed.append({"recipient": recipient, "error": str(e)}) + + return { + "successful": results, + "failed": failed, + "total": len(recipients), + "success_rate": len(results) / len(recipients) + } +``` + +!!! warning "Rate Limits" + Be mindful of API rate limits when implementing retry logic. Use exponential backoff to avoid overwhelming the API. diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 0000000..744ddfd --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,189 @@ +# Examples + +This page contains practical examples to help you get started with the Devo SDK. + +## Complete Working Examples + +For detailed, working examples of each feature, check out the `examples/` directory in the SDK repository: + +- **SMS Example**: `examples/sms_example.py` +- **Email Example**: `examples/email_example.py` +- **WhatsApp Example**: `examples/whatsapp_example.py` +- **RCS Example**: `examples/rcs_example.py` +- **Contacts Example**: `examples/contacts_example.py` +- **Contact Groups Example**: `examples/contact_groups_example.py` + +## Multi-Channel Messaging + +### Send the Same Message Across All Channels + +```python +from devo_global_comms_python import DevoClient +from devo_global_comms_python.exceptions import DevoException + +client = DevoClient(api_key="your-api-key") +recipient = "+1234567890" +message = "Hello from Devo SDK!" + +# Send via SMS +try: + sms = client.sms.send_sms( + recipient=recipient, + message=message, + sender="+1987654321" + ) + print(f"SMS sent: {sms.id}") +except DevoException as e: + print(f"SMS failed: {e}") + +# Send via WhatsApp +try: + whatsapp = client.whatsapp.send_text_message( + recipient=recipient, + message=message + ) + print(f"WhatsApp sent: {whatsapp.id}") +except DevoException as e: + print(f"WhatsApp failed: {e}") + +# Send via RCS +try: + rcs = client.rcs.send_text( + recipient=recipient, + message=message + ) + print(f"RCS sent: {rcs.id}") +except DevoException as e: + print(f"RCS failed: {e}") +``` + +## Contact Management Workflow + +### Complete Contact Lifecycle + +```python +from devo_global_comms_python.models.contacts import CreateContactDto, UpdateContactDto +from devo_global_comms_python.models.contact_groups import CreateContactsGroupDto + +# 1. Create a contact +contact_data = CreateContactDto( + phone_number="+1234567890", + email="customer@example.com", + first_name="Jane", + last_name="Smith", + company="Example Corp" +) + +contact = client.services.contacts.create(contact_data) +print(f"Created contact: {contact.id}") + +# 2. Create a contact group +group_data = CreateContactsGroupDto( + name="New Customers", + description="Recently onboarded customers" +) + +group = client.services.contact_groups.create(group_data) +print(f"Created group: {group.id}") + +# 3. Add contact to group +from devo_global_comms_python.models.contacts import AssignToContactsGroupDto + +assignment = AssignToContactsGroupDto( + contact_ids=[contact.id], + contacts_group_id=group.id +) + +client.services.contacts.assign_to_group(assignment) +print("Contact added to group") + +# 4. Send welcome message +welcome_sms = client.sms.send_sms( + recipient=contact.phone_number, + message=f"Welcome {contact.first_name}! Thanks for joining {group.name}.", + sender="+1987654321" +) +print(f"Welcome SMS sent: {welcome_sms.id}") +``` + +## Error Handling Best Practices + +### Robust Message Sending + +```python +import time +from devo_global_comms_python.exceptions import DevoException + +def send_message_with_retry(client, recipient, message, max_retries=3): + """Send a message with retry logic.""" + + for attempt in range(max_retries): + try: + # Try SMS first + response = client.sms.send_sms( + recipient=recipient, + message=message, + sender="+1987654321" + ) + print(f"SMS sent successfully: {response.id}") + return response + + except DevoException as e: + print(f"Attempt {attempt + 1} failed: {e}") + + if attempt < max_retries - 1: + # Wait before retrying + time.sleep(2 ** attempt) # Exponential backoff + continue + else: + # Try alternative channel on final failure + try: + response = client.whatsapp.send_text_message( + recipient=recipient, + message=message + ) + print(f"Fallback WhatsApp sent: {response.id}") + return response + except DevoException as fallback_error: + print(f"All channels failed: {fallback_error}") + raise + +# Usage +response = send_message_with_retry(client, "+1234567890", "Important message!") +``` + +## Environment Configuration + +### Using Environment Variables + +```python +import os +from devo_global_comms_python import DevoClient + +# Set environment variables +# export DEVO_API_KEY="your-api-key" +# export DEVO_DEFAULT_SENDER="+1987654321" + +def create_client(): + api_key = os.getenv("DEVO_API_KEY") + if not api_key: + raise ValueError("DEVO_API_KEY environment variable is required") + + return DevoClient(api_key=api_key) + +def send_notification(recipient, message): + client = create_client() + default_sender = os.getenv("DEVO_DEFAULT_SENDER", "+1234567890") + + return client.sms.send_sms( + recipient=recipient, + message=message, + sender=default_sender + ) + +# Usage +response = send_notification("+1234567890", "Hello from environment config!") +``` + +!!! tip "Running Examples" + All examples in the `examples/` directory can be run directly after setting your `DEVO_API_KEY` environment variable. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..0ac38f3 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,56 @@ +# Devo Global Communications Python SDK + +A Python SDK for the Devo Global Communications API, supporting SMS, Email, WhatsApp, RCS, and Contact management. + +## Features + +- **Multi-channel communication**: SMS, Email, WhatsApp, RCS +- **Contact management**: Create, update, and manage contacts +- **Type safety**: Full Pydantic model support with type hints +- **Minimal dependencies**: Only requires `requests` and `pydantic` +- **Python 3.8+ support**: Compatible with modern Python versions + +## Installation + +```bash +pip install devo-global-comms-python +``` + +## Quick Example + +```python +from devo_global_comms_python import DevoClient + +# Initialize the client +client = DevoClient(api_key="your-api-key") + +# Send an SMS +sms_response = client.sms.send_sms( + recipient="+1234567890", + message="Hello, World!", + sender="+1987654321" +) +print(f"SMS sent with ID: {sms_response.id}") +``` + +## Getting Started + +Continue to the [Quick Start](quickstart.md) guide to learn how to use the SDK. + +## SDK Overview + +The Devo SDK is organized into logical resources: + +| Resource | Purpose | Example Usage | +|----------|---------|---------------| +| **SMS** | Send text messages | `client.sms.send_sms()` | +| **Email** | Send emails | `client.email.send_email()` | +| **WhatsApp** | Send WhatsApp messages | `client.whatsapp.send_text_message()` | +| **RCS** | Send rich RCS messages | `client.rcs.send_text()` | +| **Contacts** | Manage contacts | `client.services.contacts.create()` | +| **Contact Groups** | Manage contact groups | `client.services.contact_groups.create()` | + +## Support + +- **Issues**: [GitHub Issues](https://github.com/devotel/devo-global-comms-python/issues) +- **Email**: [support@devotel.io](mailto:support@devotel.io) diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 0000000..2ebe5f2 --- /dev/null +++ b/docs/quickstart.md @@ -0,0 +1,83 @@ +# Quick Start + +This guide will help you get started with the Devo Global Communications Python SDK. + +## Installation + +Install the SDK using pip: + +```bash +pip install devo-global-comms-python +``` + +## Authentication + +Initialize the client with your API key: + +```python +from devo_global_comms_python import DevoClient + +client = DevoClient(api_key="your-api-key") +``` + +!!! tip "Getting Your API Key" + You can get your API key from the Devo dashboard after creating an account. + +## Your First Message + +### Send an SMS + +```python +sms_response = client.sms.send_sms( + recipient="+1234567890", + message="Hello from Devo SDK!", + sender="+1987654321" +) +print(f"SMS sent with ID: {sms_response.id}") +``` + +### Send an Email + +```python +email_response = client.email.send_email( + recipient="user@example.com", + subject="Welcome!", + content="Thank you for using Devo SDK.", + sender_email="welcome@example.com" +) +print(f"Email sent with ID: {email_response.id}") +``` + +### Send a WhatsApp Message + +```python +whatsapp_response = client.whatsapp.send_text_message( + recipient="+1234567890", + message="Hello via WhatsApp!" +) +print(f"WhatsApp message sent with ID: {whatsapp_response.id}") +``` + +## Error Handling + +Always wrap your API calls in try-catch blocks: + +```python +from devo_global_comms_python.exceptions import DevoException + +try: + sms_response = client.sms.send_sms( + recipient="+1234567890", + message="Hello!", + sender="+1987654321" + ) + print(f"Success: {sms_response.id}") +except DevoException as e: + print(f"Error: {e}") +``` + +## Next Steps + +- Explore the [SDK Reference](sdk/sms.md) for detailed usage +- Check out more [Examples](examples.md) +- Learn about [Error Handling](error_handling.md) diff --git a/docs/sdk/contact_groups.md b/docs/sdk/contact_groups.md new file mode 100644 index 0000000..b31a6c3 --- /dev/null +++ b/docs/sdk/contact_groups.md @@ -0,0 +1,113 @@ +# Contact Groups + +The Contact Groups resource allows you to organize contacts into groups for easier management. + +## Creating Contact Groups + +```python +from devo_global_comms_python.models.contact_groups import CreateContactsGroupDto + +# Create a contact group +group_data = CreateContactsGroupDto( + name="VIP Customers", + description="High-value customers", + contact_ids=["contact_1", "contact_2"] # Optional initial contacts +) + +group = client.services.contact_groups.create(group_data) +print(f"Contact group created with ID: {group.id}") +``` + +## Listing Contact Groups + +```python +# List contact groups with pagination +groups_response = client.services.contact_groups.list(page=1, limit=10) +print(f"Found {groups_response.total} contact groups") + +for group in groups_response.groups: + print(f"Group: {group.name} - {group.description}") + print(f"Contacts: {len(group.contact_ids or [])} members") +``` + +## Updating Contact Groups + +```python +from devo_global_comms_python.models.contact_groups import UpdateContactsGroupDto + +# Update a contact group +update_data = UpdateContactsGroupDto( + name="Premium VIP Customers", + description="Updated description for high-value customers" +) + +updated_group = client.services.contact_groups.update(group.id, update_data) +print(f"Group updated: {updated_group.name}") +``` + +## Managing Group Membership + +### Adding Contacts to Group + +```python +# Add contacts to an existing group +add_data = UpdateContactsGroupDto( + contact_ids=["new_contact_1", "new_contact_2"] +) + +client.services.contact_groups.update(group.id, add_data) +print("Contacts added to group") +``` + +### Removing Contacts from Group + +```python +# Remove specific contacts from group +remove_data = UpdateContactsGroupDto( + contact_ids=[] # Empty list removes all contacts +) + +client.services.contact_groups.update(group.id, remove_data) +print("Contacts removed from group") +``` + +## Searching Contact Groups + +```python +# Search contact groups by name +search_results = client.services.contact_groups.list( + page=1, + limit=5, + search="VIP" +) +print(f"Found {search_results.total} groups matching 'VIP'") +``` + +## Deleting Contact Groups + +```python +from devo_global_comms_python.models.contact_groups import DeleteContactsGroupsDto + +# Delete contact groups +delete_data = DeleteContactsGroupsDto( + group_ids=[group.id], + transfer_contacts_to="another_group_id" # Optional: transfer contacts before deletion +) + +client.services.contact_groups.delete_bulk(delete_data) +print("Contact group deleted successfully") +``` + +## Error Handling + +```python +from devo_global_comms_python.exceptions import DevoException + +try: + group = client.services.contact_groups.create(group_data) +except DevoException as e: + print(f"Contact group creation failed: {e}") +``` + +!!! tip "Group Organization" + Use contact groups to segment your audience for targeted messaging campaigns and better contact management. diff --git a/docs/sdk/contacts.md b/docs/sdk/contacts.md new file mode 100644 index 0000000..beb0b6b --- /dev/null +++ b/docs/sdk/contacts.md @@ -0,0 +1,136 @@ +# Contacts + +The Contacts resource allows you to manage contact information through the services namespace. + +## Creating Contacts + +```python +from devo_global_comms_python.models.contacts import CreateContactDto + +# Create a contact +contact_data = CreateContactDto( + phone_number="+1234567890", + email="user@example.com", + first_name="John", + last_name="Doe", + company="Acme Corp" +) + +contact = client.services.contacts.create(contact_data) +print(f"Contact created with ID: {contact.id}") +``` + +## Listing Contacts + +```python +# List contacts with pagination +contacts_response = client.services.contacts.list(page=1, limit=10) +print(f"Found {contacts_response.total} total contacts") +print(f"Page: {contacts_response.page}/{contacts_response.total_pages}") + +for contact in contacts_response.contacts: + name = f"{contact.first_name or ''} {contact.last_name or ''}".strip() + print(f"Contact: {name} ({contact.email})") +``` + +## Updating Contacts + +```python +from devo_global_comms_python.models.contacts import UpdateContactDto + +# Update a contact +update_data = UpdateContactDto( + company="New Company Inc.", + tags=["updated", "important"] +) + +updated_contact = client.services.contacts.update(contact.id, update_data) +print(f"Contact updated: {updated_contact.company}") +``` + +## Filtering Contacts + +```python +# Search and filter contacts +filtered_contacts = client.services.contacts.list( + page=1, + limit=10, + search="Acme", + is_email_subscribed=True, + tags=["customer"] +) +print(f"Found {filtered_contacts.total} contacts matching filters") +``` + +## Custom Fields + +### Create Custom Field + +```python +from devo_global_comms_python.models.contacts import CreateCustomFieldDto + +field_data = CreateCustomFieldDto( + name="Department", + field_type="text", + description="Employee department", + is_required=False +) + +new_field = client.services.contacts.create_custom_field(field_data) +print(f"Custom field created: {new_field.name}") +``` + +### List Custom Fields + +```python +custom_fields = client.services.contacts.list_custom_fields(page=1, limit=5) +print(f"Found {custom_fields.total} custom fields") +``` + +## Contact Group Operations + +### Assign to Group + +```python +from devo_global_comms_python.models.contacts import AssignToContactsGroupDto + +assignment_data = AssignToContactsGroupDto( + contact_ids=[contact.id], + contacts_group_id="group_id_123" +) + +client.services.contacts.assign_to_group(assignment_data) +print("Contact assigned to group") +``` + +### Unassign from Group + +```python +client.services.contacts.unassign_from_group(assignment_data) +print("Contact unassigned from group") +``` + +## Deleting Contacts + +```python +from devo_global_comms_python.models.contacts import DeleteContactsDto + +# Delete contacts +delete_data = DeleteContactsDto(contact_ids=[contact.id]) +client.services.contacts.delete_bulk(delete_data) +print("Contact deleted successfully") +``` + +## Error Handling + +```python +from devo_global_comms_python.exceptions import DevoException + +try: + contact = client.services.contacts.create(contact_data) +except DevoException as e: + print(f"Contact creation failed: {e}") +``` + +!!! note "Services Namespace" + Contacts are accessed through `client.services.contacts` to separate data management from messaging operations. diff --git a/docs/sdk/email.md b/docs/sdk/email.md new file mode 100644 index 0000000..8d9b62a --- /dev/null +++ b/docs/sdk/email.md @@ -0,0 +1,58 @@ +# Email + +The Email resource allows you to send email messages using various methods. + +## Sending Email + +### Basic Email + +```python +email_response = client.email.send_email( + recipient="user@example.com", + subject="Welcome to Devo!", + content="Thank you for signing up for our service.", + sender_email="welcome@example.com" +) +print(f"Email sent with ID: {email_response.id}") +``` + +### Template Email + +```python +template_response = client.email.send_template_email( + recipient="user@example.com", + template_id="welcome_template", + template_data={"name": "John", "company": "Acme Corp"}, + sender_email="noreply@example.com" +) +print(f"Template email sent with ID: {template_response.id}") +``` + +## Response Structure + +Email methods return response objects with fields like: + +- `id`: Unique email identifier +- `status`: Email status +- `recipient`: Recipient email address +- `sender_email`: Sender email address +- `subject`: Email subject line + +## Error Handling + +```python +from devo_global_comms_python.exceptions import DevoException + +try: + email_response = client.email.send_email( + recipient="user@example.com", + subject="Test", + content="Test message", + sender_email="test@example.com" + ) +except DevoException as e: + print(f"Email sending failed: {e}") +``` + +!!! tip "Email Templates" + Using templates allows for consistent branding and easier content management. diff --git a/docs/sdk/rcs.md b/docs/sdk/rcs.md new file mode 100644 index 0000000..56e34d7 --- /dev/null +++ b/docs/sdk/rcs.md @@ -0,0 +1,81 @@ +# RCS + +The RCS (Rich Communication Services) resource allows you to send enhanced messages with rich media and interactive elements. + +## Sending RCS Messages + +### Text Message + +```python +message = client.rcs.send_text( + recipient="+1234567890", + message="Hello from RCS!" +) +print(f"RCS message sent with ID: {message.id}") +``` + +### Rich Card Message + +```python +rich_card = client.rcs.send_rich_card( + recipient="+1234567890", + title="Special Offer", + description="Get 50% off your next purchase!", + media_url="https://example.com/image.jpg" +) +print(f"Rich card sent with ID: {rich_card.id}") +``` + +### General Message (Alternative API) + +```python +# Using the general send_message method +from devo_global_comms_python.models.rcs import RcsSendMessageSerializer + +message_data = RcsSendMessageSerializer( + recipient="+1234567890", + message="Hello via general API!" +) + +response = client.rcs.send_message(message_data) +print(f"Message sent with ID: {response.id}") +``` + +## Listing Messages + +```python +messages = client.rcs.list_messages(limit=10) +print(f"Found {len(messages)} RCS messages") + +for message in messages: + print(f"Message ID: {message.id}") + print(f"Status: {message.status}") + print(f"Date: {message.date_created}") +``` + +## Response Structure + +RCS methods return response objects with fields like: + +- `id`: Unique message identifier +- `status`: Message status +- `recipient`: Recipient phone number +- `date_created`: Message creation timestamp +- `date_sent`: Message sent timestamp + +## Error Handling + +```python +from devo_global_comms_python.exceptions import DevoException + +try: + message = client.rcs.send_text( + recipient="+1234567890", + message="Hello!" + ) +except DevoException as e: + print(f"RCS message failed: {e}") +``` + +!!! info "RCS Capabilities" + RCS supports rich media, read receipts, typing indicators, and interactive elements like buttons and carousels. diff --git a/docs/sdk/sms.md b/docs/sdk/sms.md new file mode 100644 index 0000000..ad04e9b --- /dev/null +++ b/docs/sdk/sms.md @@ -0,0 +1,71 @@ +# SMS + +The SMS resource allows you to send text messages and manage SMS-related functionality. + +## Sending SMS + +### Basic SMS + +```python +sms_response = client.sms.send_sms( + recipient="+1234567890", + message="Your verification code is: 123456", + sender="+1987654321" +) +print(f"SMS sent with ID: {sms_response.id}") +print(f"Status: {sms_response.status}") +``` + +### Response Structure + +The `send_sms()` method returns an `SMSQuickSendResponse` object with the following key fields: + +- `id`: Unique message identifier +- `status`: Message status +- `recipient`: Recipient phone number +- `sender_id`: Sender identifier +- `sent_date`: Date message was sent + +## Getting Available Senders + +```python +senders = client.sms.get_senders() +for sender in senders.senders: + print(f"Sender: {sender.phone_number} (Type: {sender.type})") +``` + +## Getting Available Numbers + +```python +numbers = client.sms.get_available_numbers( + region="US", + type="mobile", + limit=5 +) +print(f"Found {len(numbers.numbers)} available numbers") + +for number_info in numbers.numbers: + if number_info.features: + for feature in number_info.features: + print(f"Number: {feature.phone_number}") + print(f"Region: {feature.region_information}") + print(f"Cost: {feature.cost_information}") +``` + +## Error Handling + +```python +from devo_global_comms_python.exceptions import DevoException + +try: + sms_response = client.sms.send_sms( + recipient="+1234567890", + message="Test message", + sender="+1987654321" + ) +except DevoException as e: + print(f"SMS sending failed: {e}") +``` + +!!! note "Phone Number Format" + All phone numbers must be in E.164 format (starting with +). diff --git a/docs/sdk/whatsapp.md b/docs/sdk/whatsapp.md new file mode 100644 index 0000000..e6027b8 --- /dev/null +++ b/docs/sdk/whatsapp.md @@ -0,0 +1,56 @@ +# WhatsApp + +The WhatsApp resource enables sending messages through WhatsApp Business API. + +## Sending Messages + +### Text Message + +```python +message = client.whatsapp.send_text_message( + recipient="+1234567890", + message="Hello from WhatsApp!" +) +print(f"Message sent with ID: {message.id}") +``` + +### Media Message + +```python +media_message = client.whatsapp.send_media_message( + recipient="+1234567890", + media_url="https://example.com/image.jpg", + media_type="image", + caption="Check out this image!" +) +print(f"Media message sent with ID: {media_message.id}") +``` + +## Response Structure + +WhatsApp methods return response objects with fields like: + +- `id`: Unique message identifier +- `status`: Message status +- `recipient`: Recipient phone number +- `message_type`: Type of message sent +- `sent_date`: When the message was sent + +## Error Handling + +```python +from devo_global_comms_python.exceptions import DevoException + +try: + message = client.whatsapp.send_text_message( + recipient="+1234567890", + message="Hello!" + ) +except DevoException as e: + print(f"WhatsApp message failed: {e}") +``` + +!!! note "WhatsApp Requirements" + - Recipients must have opted-in to receive WhatsApp messages + - Phone numbers must be in E.164 format + - Media files must be accessible via public URLs diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..573b77d --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,64 @@ +site_name: Devo Global Communications Python SDK +site_description: Python SDK for Devo Global Communications API +site_url: https://devotel.github.io/devo-global-comms-python/ +repo_url: https://github.com/devotel/devo-global-comms-python +repo_name: devotel/devo-global-comms-python + +theme: + name: material + palette: + - scheme: default + primary: blue + accent: blue + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - scheme: slate + primary: blue + accent: blue + toggle: + icon: material/brightness-4 + name: Switch to light mode + features: + - navigation.tabs + - navigation.sections + - navigation.expand + - search.highlight + - content.code.copy + +nav: + - Home: index.md + - Quick Start: quickstart.md + - SDK Reference: + - SMS: sdk/sms.md + - Email: sdk/email.md + - WhatsApp: sdk/whatsapp.md + - RCS: sdk/rcs.md + - Contacts: sdk/contacts.md + - Contact Groups: sdk/contact_groups.md + - Examples: examples.md + - Error Handling: error_handling.md + +markdown_extensions: + - admonition + - pymdownx.details + - pymdownx.superfences + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.tabbed: + alternate_style: true + - toc: + permalink: true + +plugins: + - search + - mkdocstrings: + handlers: + python: + options: + docstring_style: google + show_source: false + show_root_heading: true + show_category_heading: true