diff --git a/apps/core/migrations/0001_initial.py b/apps/core/migrations/0001_initial.py new file mode 100644 index 0000000..30c7f22 --- /dev/null +++ b/apps/core/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 6.0.2 on 2026-03-16 12:23 + +import django.db.models.deletion +import uuid +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.OAUTH2_PROVIDER_APPLICATION_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='SMSPolicy', + fields=[ + ('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, primary_key=True, serialize=False, unique=True)), + ('created_at', models.DateTimeField(auto_now_add=True, db_index=True)), + ('updated_at', models.DateTimeField(auto_now=True, db_index=True)), + ('preferred', models.CharField(choices=[('fake', 'fake'), ('payam_sms', 'payam_sms'), ('mobin_sms', 'mobin_sms')], default='fake', max_length=16)), + ('application', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to=settings.OAUTH2_PROVIDER_APPLICATION_MODEL, unique=True)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/utils/clients/sms/fake/client.py b/utils/clients/sms/fake/client.py new file mode 100644 index 0000000..cba10bc --- /dev/null +++ b/utils/clients/sms/fake/client.py @@ -0,0 +1,6 @@ +from utils.clients.sms.sms import BaseSMSClient + + +class FakeClient(BaseSMSClient): + def send_sms(self, phone_number, message): + pass diff --git a/utils/clients/sms/mobin_sms/https___panel.mobinsms.com_data_connect-v1.7.json b/utils/clients/sms/mobin_sms/https___panel.mobinsms.com_data_connect-v1.7.json new file mode 100644 index 0000000..5e55ed7 --- /dev/null +++ b/utils/clients/sms/mobin_sms/https___panel.mobinsms.com_data_connect-v1.7.json @@ -0,0 +1,387 @@ +{ + "info": { + "_postman_id": "9cc27226-bee8-4b29-a924-a9e14bb61d14", + "name": "Connect API", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "2960438" + }, + "item": [ + { + "name": "Send by Pattern", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "X-API-Key", + "value": "{{apiKey}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"from\": \"989000xxxx\",\n\t\"to\": [\"989126880345\"],\n\t\"pattern\": \"YOUR_PATTERN_KEY\",\n\t\"data\": {\n\t\t\"0\": \"Var 0\",\n\t\t\"1\": \"Var 1\",\n\t\t\"2\": \"Var 2\",\n\t\t\"3\": \"Var 3\"\n\t}\n}\n", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseURL}}/v1/send/pattern", + "host": [ + "{{baseURL}}" + ], + "path": [ + "v1", + "send", + "pattern" + ] + } + }, + "response": [] + }, + { + "name": "Send Quick", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "X-API-Key", + "value": "{{apiKey}}" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"from\": \"989000xxxx\",\n\t\"to\": [\"989126880345\", \"989127761851\"],\n\t\"body\": \"Your message\",\n \"unique_id\": \"\" // UDH (optional field)\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseURL}}/v1/send/quick", + "host": [ + "{{baseURL}}" + ], + "path": [ + "v1", + "send", + "quick" + ] + } + }, + "response": [] + }, + { + "name": "Get Status", + "protocolProfileBehavior": { + "disableBodyPruning": true, + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "X-API-Key", + "value": "{{apiKey}}" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseURL}}/v1/message/status?message_id=1893", + "host": [ + "{{baseURL}}" + ], + "path": [ + "v1", + "message", + "status" + ], + "query": [ + { + "key": "unique_id", + "value": "20", + "disabled": true + }, + { + "key": "message_id", + "value": "1893" + } + ] + } + }, + "response": [ + { + "name": "Delivered Message", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "User-Agent", + "value": "insomnia/11.6.2" + }, + { + "key": "X-API-Key", + "value": "07e7e9c79652b857aa77b8f3d40cc4314321970e1a5f78b9fc18e497aca2bf40" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"from\": \"9890001777\",\n\t\"to\": [\"989126880345\"],\n\t\"body\": \"Your message\",\n \"unique_id\": \"6\" // UDH (optional field)\n}\n", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseURL}}/v1/message/status?message_id=1852", + "host": [ + "{{baseURL}}" + ], + "path": [ + "v1", + "message", + "status" + ], + "query": [ + { + "key": "message_id", + "value": "1852" + }, + { + "key": "unique_id", + "value": "webengage-message-id", + "disabled": true + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Date", + "value": "Sun, 09 Nov 2025 16:20:37 GMT" + }, + { + "key": "Content-Type", + "value": "application/json", + "description": "", + "type": "text" + }, + { + "key": "Content-Length", + "value": "38" + }, + { + "key": "Connection", + "value": "keep-alive" + } + ], + "cookie": [], + "body": "{\n \"id\": 274,\n \"status\": \"2\", // 0: Pending, 1: Sent, 2: Delivered\n \"unique_id\": \"\"\n}" + } + ] + }, + { + "name": "Webengage", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "X-API-Key", + "value": "{{apiKey}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"version\": \"2.0\",\n \"smsData\": {\n \"toNumber\": \"989195712939\",\n \"fromNumber\": \"9890006950\",\n \"body\": \"Text message body\"\n },\n \"metadata\": {\n \"campaignType\": \"PROMOTIONAL\",\n \"timestamp\": \"2018-01-25T10:24:16+0000\",\n \"messageId\": \"webengage-message-id222\",\n \"custom\": {\n \"key1\": \"val1\",\n \"key2\": \"val2\"\n },\n \"indiaDLT\": {\n \"contentTemplateId\": \"xyz\",\n \"principalEntityId\": \"abc\",\n \"telemarketerId\": \"tm1,tm2\"\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseURL}}/v1/integration/webengage", + "host": [ + "{{baseURL}}" + ], + "path": [ + "v1", + "integration", + "webengage" + ] + } + }, + "response": [] + }, + { + "name": "Send Bulk", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + }, + { + "key": "X-API-Key", + "value": "{{apiKey}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"from\": \"989000xxxx\",\n \"on_duplicate\": \"skip\", // Skip to send only unique ones, reject to stop sending any message even if one is not unique\n \"messages\": [\n {\n \"to\": \"989126880345\",\n \"body\": \"Your message\",\n \"unique_id\": \"1\" // UDH: Optional\n },\n {\n \"to\": \"989127865454\",\n \"body\": \"Your message 2\",\n \"unique_id\": \"20\" // UDH: Optional\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseURL}}/v1/send/bulk", + "host": [ + "{{baseURL}}" + ], + "path": [ + "v1", + "send", + "bulk" + ] + } + }, + "response": [] + }, + { + "name": "Account Balance", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "X-API-Key", + "value": "{{apiKey}}" + } + ], + "url": { + "raw": "{{baseURL}}/v1/account/balance", + "host": [ + "{{baseURL}}" + ], + "path": [ + "v1", + "account", + "balance" + ], + + } + }, + "response": [] + }, + { + "name": "Send vOTP", + "request": { + "method": "POST", + "header": [ + { + "key": "x-api-key", + "value": "{{apiKey}}", + "type": "text" + }, + { + "key": "content-type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"from\": \"9890002999\",\n\t\"to\": \"989126880345\",\n\t\"code\": \"123456\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseURL}}/v1/send/votp", + "host": [ + "{{baseURL}}" + ], + "path": [ + "v1", + "send", + "votp" + ] + } + }, + "response": [] + } + ], + "variable": [ + { + "key": "baseURL", + "value": "", + "type": "default" + }, + { + "key": "apiKey", + "value": "", + "type": "default" + } + ] +} \ No newline at end of file diff --git a/utils/clients/sms/sms.py b/utils/clients/sms/sms.py new file mode 100644 index 0000000..35dd319 --- /dev/null +++ b/utils/clients/sms/sms.py @@ -0,0 +1,3 @@ +class BaseSMSClient: + def send_sms(self, phone_number, message): + raise NotImplementedError() \ No newline at end of file