2025-12-03 19:56:35 -03:00
# SEND SMS
2025-12-10 18:22:37 -03:00
Send SMS text messages to phone numbers using various providers with optional priority levels.
2025-12-03 19:56:35 -03:00
## Syntax
```basic
2025-12-10 18:22:37 -03:00
' Basic SMS sending (default priority: normal)
2025-12-03 19:56:35 -03:00
SEND SMS phone, message
2025-12-10 18:22:37 -03:00
' With priority level
SEND SMS phone, message, priority
2025-12-03 19:56:35 -03:00
' With specific provider
SEND SMS phone, message, provider
2025-12-10 18:22:37 -03:00
' With provider AND priority (full syntax)
SEND SMS phone, message, provider, priority
2025-12-03 19:56:35 -03:00
```
## Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `phone` | String | Yes | Recipient phone number (E.164 format recommended) |
| `message` | String | Yes | The text message to send (max 160 chars for single SMS) |
2025-12-10 18:22:37 -03:00
| `priority` | String | No | Priority level: `low` , `normal` , `high` , `urgent` |
| `provider` | String | No | SMS provider: `twilio` , `aws_sns` , `vonage` , `messagebird` , or custom |
### Priority Levels
| Priority | Description | Provider Behavior |
|----------|-------------|-------------------|
| `low` | Non-urgent, promotional messages | Standard delivery |
| `normal` | Default priority | Standard delivery |
| `high` | Important messages | Transactional routing (AWS SNS), priority prefix |
| `urgent` | Critical/time-sensitive | Flash message (Vonage), [URGENT] prefix (Twilio) |
2025-12-03 19:56:35 -03:00
## Return Value
2025-12-10 18:22:37 -03:00
Returns a map object with the following properties:
| Property | Type | Description |
|----------|------|-------------|
| `success` | Boolean | `true` if SMS was sent successfully |
| `message_id` | String | Provider's message ID for tracking |
| `provider` | String | The provider used to send the message |
| `to` | String | Normalized recipient phone number |
| `priority` | String | The priority level used |
| `error` | String | Error message (only present if `success` is `false` ) |
2025-12-03 19:56:35 -03:00
## Configuration
Configure SMS provider credentials in `config.csv` :
```csv
key,value
sms-provider,twilio
2025-12-10 18:22:37 -03:00
sms-default-priority,normal
2025-12-03 19:56:35 -03:00
twilio-account-sid,YOUR_ACCOUNT_SID
twilio-auth-token,YOUR_AUTH_TOKEN
2025-12-10 18:22:37 -03:00
twilio-from-number,+15551234567
2025-12-03 19:56:35 -03:00
```
### Provider-Specific Configuration
**Twilio:**
```csv
sms-provider,twilio
twilio-account-sid,ACxxxxx
twilio-auth-token,your_token
2025-12-10 18:22:37 -03:00
twilio-from-number,+15551234567
2025-12-03 19:56:35 -03:00
```
**AWS SNS:**
```csv
sms-provider,aws_sns
2025-12-10 18:22:37 -03:00
aws-access-key,AKIAXXXXXXXX
aws-secret-key,your_secret
2025-12-03 19:56:35 -03:00
aws-region,us-east-1
```
**Vonage (Nexmo):**
```csv
sms-provider,vonage
vonage-api-key,your_api_key
vonage-api-secret,your_secret
vonage-from-number,+15551234567
```
**MessageBird:**
```csv
sms-provider,messagebird
messagebird-access-key,your_access_key
messagebird-originator,YourBrand
```
## Examples
### Basic SMS
```basic
HEAR phone AS TEXT "Enter phone number:"
SEND SMS phone, "Hello from General Bots!"
TALK "SMS sent successfully!"
```
2025-12-10 18:22:37 -03:00
### SMS with Priority
```basic
' Send urgent notification
result = SEND SMS "+15551234567", "Server is DOWN! Immediate action required.", "urgent"
IF result.success THEN
TALK "Urgent alert sent with ID: " + result.message_id
ELSE
TALK "Failed to send alert: " + result.error
END IF
```
### Order Confirmation (Normal Priority)
2025-12-03 19:56:35 -03:00
```basic
' Send order confirmation via SMS
order_id = "ORD-2025-001"
phone = customer.phone
message = "Your order " + order_id + " has been confirmed. "
message = message + "Estimated delivery: 2-3 business days."
2025-12-10 18:22:37 -03:00
result = SEND SMS phone, message, "normal"
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
IF result.success THEN
2025-12-03 19:56:35 -03:00
TALK "Confirmation SMS sent to " + phone
ELSE
TALK "Failed to send SMS. We'll email you instead."
2025-12-10 18:22:37 -03:00
SEND MAIL customer.email, "Order Confirmation", message, []
2025-12-03 19:56:35 -03:00
END IF
```
2025-12-10 18:22:37 -03:00
### Two-Factor Authentication (High Priority)
2025-12-03 19:56:35 -03:00
```basic
2025-12-10 18:22:37 -03:00
' Generate and send OTP with high priority for faster delivery
2025-12-03 19:56:35 -03:00
otp = RANDOM(100000, 999999)
REMEMBER "otp_" + user.id, otp, "5 minutes"
message = "Your verification code is: " + otp + ". Valid for 5 minutes."
2025-12-10 18:22:37 -03:00
result = SEND SMS user.phone, message, "high"
IF NOT result.success THEN
TALK "Failed to send verification code. Please try again."
RETURN
END IF
2025-12-03 19:56:35 -03:00
HEAR entered_code AS TEXT "Enter the code sent to your phone:"
stored_otp = RECALL "otp_" + user.id
IF entered_code = stored_otp THEN
TALK "✅ Phone verified successfully!"
SET USER MEMORY "phone_verified", true
ELSE
TALK "❌ Invalid code. Please try again."
END IF
```
2025-12-10 18:22:37 -03:00
### Emergency Alert (Urgent Priority)
2025-12-03 19:56:35 -03:00
```basic
2025-12-10 18:22:37 -03:00
' Send emergency notification to multiple recipients
alert_message = "⚠️ ALERT: System maintenance in 30 minutes. Save your work."
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
contacts = FIND "emergency_contacts", "notify=true"
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
sent_count = 0
failed_count = 0
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
FOR EACH contact IN contacts
result = SEND SMS contact.phone, alert_message, "urgent"
IF result.success THEN
sent_count = sent_count + 1
ELSE
failed_count = failed_count + 1
PRINT "Failed to send to " + contact.phone + ": " + result.error
2025-12-03 19:56:35 -03:00
END IF
2025-12-10 18:22:37 -03:00
WAIT 100 ' Small delay between messages
NEXT
TALK "Emergency alert sent to " + sent_count + " contacts (" + failed_count + " failed)"
2025-12-03 19:56:35 -03:00
```
2025-12-10 18:22:37 -03:00
### Using Specific Provider with Priority
2025-12-03 19:56:35 -03:00
```basic
2025-12-10 18:22:37 -03:00
' Use AWS SNS for high-priority transactional messages
result = SEND SMS "+15551234567", "Your appointment is in 1 hour!", "aws", "high"
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
IF result.success THEN
TALK "Reminder sent via " + result.provider + " with " + result.priority + " priority"
2025-12-03 19:56:35 -03:00
END IF
2025-12-10 18:22:37 -03:00
```
### Priority-Based Routing
```basic
' Route messages based on urgency
SUB send_notification(phone, message, urgency)
SELECT CASE urgency
CASE "critical"
' Use multiple channels for critical messages
result = SEND SMS phone, message, "urgent"
SEND MAIL user.email, "CRITICAL: " + message, message, []
CASE "important"
result = SEND SMS phone, message, "high"
CASE "info"
result = SEND SMS phone, message, "low"
CASE ELSE
result = SEND SMS phone, message, "normal"
END SELECT
RETURN result
END SUB
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
' Usage
send_notification(customer.phone, "Your package has been delivered!", "important")
2025-12-03 19:56:35 -03:00
```
2025-12-10 18:22:37 -03:00
### Appointment Reminder with Priority
2025-12-03 19:56:35 -03:00
```basic
2025-12-10 18:22:37 -03:00
' Send appointment reminder based on time until appointment
hours_until = DATEDIFF(appointment.datetime, NOW(), "hour")
IF hours_until < = 1 THEN
' Urgent - appointment is very soon
priority = "urgent"
message = "⏰ REMINDER: Your appointment is in " + hours_until + " hour(s)!"
ELSE IF hours_until < = 4 THEN
' High priority - same day
priority = "high"
message = "Reminder: Your appointment is today at " + FORMAT(appointment.datetime, "h:mm A")
2025-12-03 19:56:35 -03:00
ELSE
2025-12-10 18:22:37 -03:00
' Normal priority - advance reminder
priority = "normal"
message = "Reminder: You have an appointment on " + FORMAT(appointment.datetime, "MMMM D")
END IF
result = SEND SMS patient.phone, message, priority
IF result.success THEN
UPDATE "appointments", appointment.id, "reminder_sent", true
2025-12-03 19:56:35 -03:00
END IF
```
2025-12-10 18:22:37 -03:00
### Bulk SMS with Priority Levels
2025-12-03 19:56:35 -03:00
```basic
2025-12-10 18:22:37 -03:00
' Send promotional messages with low priority (cost-effective)
customers = FIND "customers.csv", "marketing_opt_in = true"
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
FOR EACH customer IN customers
message = "Hi " + customer.first_name + "! Check out our weekend sale - 20% off!"
' Use low priority for promotional bulk messages
result = SEND SMS customer.phone, message, "low"
IF result.success THEN
INSERT "sms_log", customer.phone, message, result.message_id, NOW()
END IF
WAIT 500 ' Rate limiting for bulk sends
2025-12-03 19:56:35 -03:00
NEXT
2025-12-10 18:22:37 -03:00
TALK "Campaign completed!"
2025-12-03 19:56:35 -03:00
```
2025-12-10 18:22:37 -03:00
### Multi-Channel Fallback with Priority
2025-12-03 19:56:35 -03:00
```basic
2025-12-10 18:22:37 -03:00
' Try SMS first, fall back to other channels
SUB notify_user(user, message, priority)
' Try SMS first
result = SEND SMS user.phone, message, priority
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
IF result.success THEN
RETURN "sms"
END IF
' SMS failed, try WhatsApp
wa_result = SEND WHATSAPP user.phone, message
IF wa_result.success THEN
RETURN "whatsapp"
END IF
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
' Fall back to email
SEND MAIL user.email, "Notification", message, []
RETURN "email"
END SUB
' Usage
channel_used = notify_user(customer, "Your order has shipped!", "high")
TALK "Notification sent via " + channel_used
2025-12-03 19:56:35 -03:00
```
## Phone Number Formats
2025-12-10 18:22:37 -03:00
The keyword accepts various phone number formats and normalizes them:
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
| Format | Example | Result |
|--------|---------|--------|
| E.164 | `+14155551234` | `+14155551234` |
| National (US) | `(415) 555-1234` | `+14155551234` |
| Digits only (10) | `4155551234` | `+14155551234` |
| Digits only (11) | `14155551234` | `+14155551234` |
2025-12-03 19:56:35 -03:00
**Best Practice:** Always use E.164 format (`+` followed by country code and number).
## Message Length
| Type | Characters | Notes |
|------|------------|-------|
| Single SMS | 160 | Standard ASCII |
| Unicode SMS | 70 | Emojis, non-Latin scripts |
| Concatenated | 153 × segments | Long messages split |
2025-12-10 18:22:37 -03:00
> **Note:** High and urgent priority messages may have prefixes added (e.g., `[URGENT]`), which reduces available characters.
2025-12-03 19:56:35 -03:00
```basic
' Check message length before sending
2025-12-10 18:22:37 -03:00
IF LEN(message) > 140 AND priority = "urgent" THEN
TALK "Warning: Urgent prefix may cause message to split"
2025-12-03 19:56:35 -03:00
END IF
2025-12-10 18:22:37 -03:00
SEND SMS phone, message, priority
2025-12-03 19:56:35 -03:00
```
2025-12-10 18:22:37 -03:00
## Priority Behavior by Provider
| Provider | Low | Normal | High | Urgent |
|----------|-----|--------|------|--------|
| **Twilio** | Standard | Standard | `[HIGH]` prefix | `[URGENT]` prefix |
| **AWS SNS** | Promotional | Promotional | Transactional | Transactional |
| **Vonage** | Standard | Standard | Standard | Flash message (class 0) |
| **MessageBird** | Standard | Standard | Class 1 | Flash message (class 0) |
2025-12-03 19:56:35 -03:00
## Error Handling
```basic
' Handle SMS errors gracefully
2025-12-10 18:22:37 -03:00
result = SEND SMS phone, message, "high"
IF NOT result.success THEN
' Log the failure
INSERT "sms_failures", phone, message, result.error, NOW()
2025-12-03 19:56:35 -03:00
2025-12-10 18:22:37 -03:00
' Check error type and respond
IF result.error LIKE "*INVALID_PHONE*" THEN
TALK "The phone number appears to be invalid."
ELSE IF result.error LIKE "*INSUFFICIENT_FUNDS*" THEN
TALK "SMS service temporarily unavailable."
' Alert admin
SEND MAIL admin.email, "SMS Balance Low", "Please top up SMS credits", []
ELSE
TALK "Could not send SMS: " + result.error
2025-12-03 19:56:35 -03:00
END IF
2025-12-10 18:22:37 -03:00
' Fallback to email if available
IF user.email < > "" THEN
SEND MAIL user.email, "Notification", message, []
END IF
END IF
2025-12-03 19:56:35 -03:00
```
## Cost Considerations
SMS messages incur costs per message sent. Consider:
2025-12-10 18:22:37 -03:00
- Use `low` priority for promotional/non-urgent messages (may use cheaper routes)
- Use `high` /`urgent` only when delivery speed is critical
- Use [SEND WHATSAPP ](./universal-messaging.md ) for free messaging when possible
- Batch non-urgent messages to optimize costs
2025-12-03 19:56:35 -03:00
## Compliance
When sending SMS messages, ensure compliance with:
- **TCPA** (US) - Require consent before sending
- **GDPR** (EU) - Document consent and provide opt-out
- **LGPD** (Brazil) - Similar consent requirements
```basic
' Check opt-in before sending
IF GET USER MEMORY "sms_opt_in" = true THEN
2025-12-10 18:22:37 -03:00
SEND SMS phone, message, priority
2025-12-03 19:56:35 -03:00
ELSE
TALK "User has not opted in to SMS notifications"
END IF
```
## See Also
- [SEND WHATSAPP ](./universal-messaging.md ) - WhatsApp messaging
- [SEND MAIL ](./keyword-send-mail.md ) - Email messaging
2025-12-10 18:22:37 -03:00
- [SEND TEMPLATE ](./keyword-send-template.md ) - Template messages
2025-12-03 19:56:35 -03:00
- [Universal Messaging ](./universal-messaging.md ) - Multi-channel messaging
2025-12-10 18:22:37 -03:00
- [SMS Provider Configuration ](../08-config/sms-providers.md ) - Provider setup guide
2025-12-03 19:56:35 -03:00
## Implementation
2025-12-10 18:22:37 -03:00
The SEND SMS keyword is implemented in `src/basic/keywords/sms.rs` with support for multiple providers through a unified interface. Priority levels are mapped to provider-specific features for optimal delivery.