# Mshastra SMS Integration Plan

## Files to modify:
1. `.env` - Add Mshastra credentials
2. `.env.example` - Add Mshastra credential placeholders
3. `config/settings/base.py` - Add Mshastra settings (~line 370)
4. `apps/notifications/services.py` - Add `_send_sms_mshastra()` and update routing
5. `apps/notifications/management/commands/test_sms.py` - New management command

---

## 1. `.env` — Add after last line (after `SMS_API_KEY=simulator-test-key`):

```
# Mshastra SMS API
MSHASTRA_USERNAME=
MSHASTRA_PASSWORD=
MSHASTRA_SENDER_ID=
```

## 2. `.env.example` — Add before the `# Simulator API` comment block (around line 67):

```
# Mshastra SMS API
# Set SMS_PROVIDER=mshastra and fill in credentials to send real SMS via Mshastra
MSHASTRA_USERNAME=
MSHASTRA_PASSWORD=
MSHASTRA_SENDER_ID=
```

## 3. `config/settings/base.py` — Add after TWILIO settings block (after line 370):

```python
# Mshastra SMS Configuration
MSHASTRA_USERNAME = env("MSHASTRA_USERNAME", default="")
MSHASTRA_PASSWORD = env("MSHASTRA_PASSWORD", default="")
MSHASTRA_SENDER_ID = env("MSHASTRA_SENDER_ID", default="")
```

## 4. `apps/notifications/services.py` — Changes:

### 4a. Update `send_sms()` method (lines 55-72)
Replace the provider routing section to add `mshastra` check:

Current code (lines 55-72):
```python
        sms_config = settings.NOTIFICATION_CHANNELS.get("sms", {})
        provider = sms_config.get("provider", "console")

        log = NotificationLog.objects.create(
            channel="sms",
            recipient=phone,
            message=message,
            content_object=related_object,
            provider=provider,
            metadata=metadata or {},
        )

        if provider == "twilio":
            return NotificationService._send_sms_twilio(log, phone, message)

        logger.info(f"[SMS Console] To: {phone} | Message: {message}")
        log.mark_sent()
        return log
```

New code:
```python
        sms_config = settings.NOTIFICATION_CHANNELS.get("sms", {})
        provider = sms_config.get("provider", "console")

        log = NotificationLog.objects.create(
            channel="sms",
            recipient=phone,
            message=message,
            content_object=related_object,
            provider=provider,
            metadata=metadata or {},
        )

        if provider == "mshastra":
            return NotificationService._send_sms_mshastra(log, phone, message)

        if provider == "twilio":
            return NotificationService._send_sms_twilio(log, phone, message)

        logger.info(f"[SMS Console] To: {phone} | Message: {message}")
        log.mark_sent()
        return log
```

### 4b. Add `_send_sms_mshastra()` method after `_send_sms_twilio()` (after line 138):

```python
    @staticmethod
    def _send_sms_mshastra(log, phone, message):
        """
        Send SMS via Mshastra API.

        Requires: MSHASTRA_USERNAME, MSHASTRA_PASSWORD, and MSHASTRA_SENDER_ID.
        API: https://mshastra.com/sendurl.aspx
        """
        import requests

        username = settings.MSHASTRA_USERNAME
        password = settings.MSHASTRA_PASSWORD
        sender_id = settings.MSHASTRA_SENDER_ID

        if not username or not password:
            logger.warning("Mshastra credentials not configured, falling back to console")
            log.provider = "console"
            log.save(update_fields=["provider"])
            logger.info(f"[SMS Console] To: {phone} | Message: {message}")
            log.mark_sent()
            return log

        try:
            url = "https://mshastra.com/sendurl.aspx"
            params = {
                "user": username,
                "pwd": password,
                "senderid": sender_id,
                "mobileno": phone,
                "msgtext": message,
                "priority": "High",
                "CountryCode": "ALL",
            }

            response = requests.get(url, params=params, timeout=30)
            response_text = response.text.strip()

            log.provider_response = {"status_code": response.status_code, "response": response_text}
            log.save(update_fields=["provider_response"])

            if "Send Successful" in response_text:
                log.mark_sent()
                logger.info(f"SMS sent via Mshastra to {phone}: {response_text}")
            else:
                log.mark_failed(response_text)
                logger.warning(f"Mshastra SMS failed for {phone}: {response_text}")

            return log

        except requests.exceptions.Timeout:
            logger.error(f"Mshastra API timeout for {phone}")
            log.mark_failed("Request timeout")
            return log

        except requests.exceptions.ConnectionError:
            logger.error(f"Mshastra API connection error for {phone}")
            log.mark_failed("Connection error")
            return log

        except Exception as e:
            logger.error(f"Unexpected error sending SMS via Mshastra to {phone}: {e}", exc_info=True)
            log.mark_failed(str(e))
            return log
```

## 5. Create `apps/notifications/management/commands/test_sms.py`:

```python
"""
Management command to test SMS sending.

Usage:
    python manage.py test_sms 966501234567
    python manage.py test_sms 966501234567 --message "Custom test message"
"""

from django.core.management.base import BaseCommand

from apps.notifications.services import NotificationService


class Command(BaseCommand):
    help = "Send a test SMS to a phone number"

    def add_arguments(self, parser):
        parser.add_argument("phone", type=str, help="Phone number in international format (e.g. 966501234567)")
        parser.add_argument("--message", type=str, default="Test SMS from PX360", help="Custom message text")

    def handle(self, *args, **options):
        phone = options["phone"]
        message = options["message"]

        self.stdout.write(f"Sending SMS to {phone}...")
        self.stdout.write(f"Message: {message}")
        self.stdout.write("")

        log = NotificationService.send_sms(phone, message)

        self.stdout.write(f"Status: {log.status}")
        self.stdout.write(f"Provider: {log.provider}")
        if log.error:
            self.stdout.write(self.style.ERROR(f"Error: {log.error}"))
        if log.provider_response:
            self.stdout.write(f"Provider Response: {log.provider_response}")

        if log.status == "sent":
            self.stdout.write(self.style.SUCCESS(f"SMS sent successfully to {phone}"))
        elif log.status == "failed":
            self.stdout.write(self.style.ERROR(f"SMS failed for {phone}"))
        else:
            self.stdout.write(self.style.WARNING(f"SMS status: {log.status} for {phone}"))
```
