https://github.com/boxlinknet/kwtsms-supabase
kwtSMS SMS gateway integration for Supabase. Phone OTP authentication, event-driven notifications, multilingual templates, and SMS queue processing.
https://github.com/boxlinknet/kwtsms-supabase
a2p-sms arabic authentication deno edge-functions kuwait kwtsms notifications otp sms sms-gateway supabase typescript
Last synced: about 1 month ago
JSON representation
kwtSMS SMS gateway integration for Supabase. Phone OTP authentication, event-driven notifications, multilingual templates, and SMS queue processing.
- Host: GitHub
- URL: https://github.com/boxlinknet/kwtsms-supabase
- Owner: boxlinknet
- Created: 2026-03-26T06:40:57.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-02T15:46:22.000Z (2 months ago)
- Last Synced: 2026-04-03T03:51:22.259Z (2 months ago)
- Topics: a2p-sms, arabic, authentication, deno, edge-functions, kuwait, kwtsms, notifications, otp, sms, sms-gateway, supabase, typescript
- Language: TypeScript
- Homepage: https://www.kwtsms.com/integrations.html
- Size: 36.1 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Security: SECURITY.md
Awesome Lists containing this project
README
kwtSMS for Supabase
SMS gateway integration for Supabase using kwtSMS
---
## About kwtSMS
[kwtSMS](https://www.kwtsms.com) is a Kuwait-based SMS gateway providing A2P (application-to-person) messaging across 200+ countries. It supports transactional and promotional sender IDs, Arabic and English messages, and a REST/JSON API for programmatic SMS delivery.
This integration connects kwtSMS to your Supabase project, replacing the default SMS provider for phone authentication and adding event-driven SMS notifications through a simple queue-based architecture.
## Features
- **Phone OTP login** using the Supabase Auth Send SMS Hook
- **Event-driven notifications** through an `sms_queue` table (INSERT to send)
- **Multilingual templates** with `{{placeholder}}` support (English and Arabic)
- **Customer and admin recipients** from a single queue
- **Phone normalization** with Arabic digit conversion, prefix stripping, and country code prepend
- **Message cleaning** strips emoji, hidden characters, and HTML tags before send
- **Balance, sender ID, and coverage sync** cached locally, updated daily
- **SMS audit log** with full API response history
- **Gateway test mode** for development without consuming credits
## Architecture
```
Supabase Auth ──> sms-auth-hook ──> kwtSMS API
^
App / DB ──> sms_queue table |
| |
pg_cron (30s) ──> send-sms ──┘
sms-admin ──> settings, templates, logs
sms-cron ──> daily balance/coverage sync
```
Four Edge Functions, five database tables, PL/pgSQL triggers for normalization and template rendering, and pg_cron for queue processing.
## Quick start
### Prerequisites
- Supabase project (local or hosted)
- [Supabase CLI](https://supabase.com/docs/guides/cli) installed
- [kwtSMS account](https://www.kwtsms.com) with API access
### Install
1. Clone this repo:
```bash
git clone https://github.com/boxlinknet/kwtsms-supabase.git
cd kwtsms-supabase
```
2. Link to your Supabase project:
```bash
supabase link --project-ref
```
3. Run database migrations:
```bash
supabase db push
```
4. Set your kwtSMS credentials:
```bash
supabase secrets set KWTSMS_USERNAME=your_api_username
supabase secrets set KWTSMS_PASSWORD=your_api_password
supabase secrets set SEND_SMS_HOOK_SECRET=v1,whsec_your_secret_here
```
5. Deploy Edge Functions:
```bash
supabase functions deploy
```
6. Enable the Send SMS Hook in the Supabase Dashboard:
- Go to **Authentication > Hooks > Send SMS**
- Select HTTP and enter the `sms-auth-hook` function URL
### Send an SMS
Queue an SMS with a template:
```sql
INSERT INTO sms_queue (phone, template_slug, variables, language)
VALUES ('96598765432', 'order_confirmed', '{"order_id": "1234"}', 'en');
```
Or call the RPC function from your app:
```typescript
const { data } = await supabase.rpc('send_sms', {
p_phone: '96598765432',
p_template_slug: 'order_confirmed',
p_variables: { order_id: '1234' },
p_language: 'en'
})
```
The queue processor picks up pending rows every 30 seconds, normalizes the phone number, cleans the message, and sends it through the kwtSMS API.
## Default templates
| Slug | English | Arabic |
|------|---------|--------|
| `auth_otp` | Your verification code is: `{{otp}}` | رمز التحقق الخاص بك هو: `{{otp}}` |
| `order_confirmed` | Your order #`{{order_id}}` has been confirmed. | تم تأكيد طلبك رقم #`{{order_id}}`. |
| `order_shipped` | Your order #`{{order_id}}` has been shipped. | تم شحن طلبك رقم #`{{order_id}}`. |
| `order_delivered` | Your order #`{{order_id}}` has been delivered. | تم توصيل طلبك رقم #`{{order_id}}`. |
| `order_cancelled` | Your order #`{{order_id}}` has been cancelled. | تم إلغاء طلبك رقم #`{{order_id}}`. |
| `payment_received` | Payment of `{{amount}}` received. Thank you. | تم استلام دفعة بقيمة `{{amount}}`. شكرا لك. |
| `welcome` | Welcome to `{{app_name}}`! | مرحبا بك في `{{app_name}}`! |
Templates are editable through the `sms-admin` Edge Function and can be reset to defaults at any time.
## Admin API
The `sms-admin` Edge Function exposes these endpoints (requires `service_role` JWT):
| Method | Path | Description |
|--------|------|-------------|
| POST | `/login` | Test credentials, save to settings |
| GET | `/settings` | Get settings (credentials masked) |
| PUT | `/settings` | Update gateway settings |
| GET | `/templates` | List all templates |
| PUT | `/templates/:slug` | Update a template |
| POST | `/templates/:slug/reset` | Reset a template to default |
| POST | `/templates/reset` | Reset all templates |
| GET | `/logs` | Paginated SMS log |
| DELETE | `/logs` | Clear logs |
| GET | `/balance` | Get cached balance |
| POST | `/balance/sync` | Sync balance from kwtSMS |
| POST | `/test-gateway` | Send a test SMS |
## License
MIT