mirror of
https://github.com/myronblair/tomsjavajive-app
synced 2026-06-30 17:50:56 -05:00
196 lines
6.2 KiB
PHP
196 lines
6.2 KiB
PHP
<?php
|
|
/**
|
|
* Tom's Java Jive - Twilio SMS Service
|
|
*
|
|
* Handles all SMS notifications using Twilio API
|
|
*/
|
|
|
|
class TwilioSMS {
|
|
private string $accountSid;
|
|
private string $authToken;
|
|
private string $fromNumber;
|
|
|
|
public function __construct() {
|
|
// Load from settings or config
|
|
$this->accountSid = getSetting('twilio_account_sid', 'YOUR_TWILIO_ACCOUNT_SID');
|
|
$this->authToken = getSetting('twilio_auth_token', 'YOUR_TWILIO_AUTH_TOKEN');
|
|
$this->fromNumber = getSetting('twilio_phone_number', '+1234567890');
|
|
}
|
|
|
|
/**
|
|
* Send SMS via Twilio API
|
|
*/
|
|
public function send(string $to, string $message): array {
|
|
// Ensure phone number is in E.164 format
|
|
$to = $this->formatPhoneNumber($to);
|
|
|
|
if (!$to) {
|
|
return ['success' => false, 'error' => 'Invalid phone number'];
|
|
}
|
|
|
|
$url = "https://api.twilio.com/2010-04-01/Accounts/{$this->accountSid}/Messages.json";
|
|
|
|
$data = [
|
|
'To' => $to,
|
|
'From' => $this->fromNumber,
|
|
'Body' => $message
|
|
];
|
|
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => http_build_query($data),
|
|
CURLOPT_USERPWD => "{$this->accountSid}:{$this->authToken}",
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 30
|
|
]);
|
|
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$error = curl_error($ch);
|
|
curl_close($ch);
|
|
|
|
if ($error) {
|
|
return ['success' => false, 'error' => $error];
|
|
}
|
|
|
|
$result = json_decode($response, true);
|
|
|
|
if ($httpCode >= 200 && $httpCode < 300) {
|
|
return [
|
|
'success' => true,
|
|
'sid' => $result['sid'] ?? null,
|
|
'status' => $result['status'] ?? 'queued'
|
|
];
|
|
}
|
|
|
|
return [
|
|
'success' => false,
|
|
'error' => $result['message'] ?? 'Failed to send SMS',
|
|
'code' => $result['code'] ?? $httpCode
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Format phone number to E.164 format
|
|
*/
|
|
private function formatPhoneNumber(string $phone): ?string {
|
|
// Remove all non-numeric characters except +
|
|
$phone = preg_replace('/[^0-9+]/', '', $phone);
|
|
|
|
// If already in E.164 format
|
|
if (preg_match('/^\+[1-9]\d{1,14}$/', $phone)) {
|
|
return $phone;
|
|
}
|
|
|
|
// US number without country code
|
|
if (preg_match('/^1?\d{10}$/', $phone)) {
|
|
$phone = preg_replace('/^1?/', '', $phone);
|
|
return '+1' . $phone;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Send order confirmation SMS
|
|
*/
|
|
public function sendOrderConfirmation(array $order, string $phone): array {
|
|
$message = "Tom's Java Jive: Your order #{$order['order_number']} has been confirmed! " .
|
|
"Total: " . formatCurrency($order['total']) . ". " .
|
|
"Thank you for your purchase!";
|
|
|
|
return $this->send($phone, $message);
|
|
}
|
|
|
|
/**
|
|
* Send shipping notification SMS
|
|
*/
|
|
public function sendShippingNotification(array $order, string $phone): array {
|
|
$message = "Tom's Java Jive: Your order #{$order['order_number']} has shipped! " .
|
|
"Tracking: {$order['tracking_number']}. " .
|
|
"Track at: " . ($order['tracking_url'] ?? SITE_URL);
|
|
|
|
return $this->send($phone, $message);
|
|
}
|
|
|
|
/**
|
|
* Send delivery notification SMS
|
|
*/
|
|
public function sendDeliveryNotification(array $order, string $phone): array {
|
|
$message = "Tom's Java Jive: Great news! Your order #{$order['order_number']} " .
|
|
"has been delivered. Enjoy your coffee!";
|
|
|
|
return $this->send($phone, $message);
|
|
}
|
|
|
|
/**
|
|
* Send password reset SMS
|
|
*/
|
|
public function sendPasswordResetCode(string $phone, string $code): array {
|
|
$message = "Tom's Java Jive: Your password reset code is {$code}. " .
|
|
"This code expires in 15 minutes. Don't share it with anyone.";
|
|
|
|
return $this->send($phone, $message);
|
|
}
|
|
|
|
/**
|
|
* Send OTP verification SMS
|
|
*/
|
|
public function sendVerificationCode(string $phone, string $code): array {
|
|
$message = "Tom's Java Jive: Your verification code is {$code}. " .
|
|
"Valid for 10 minutes.";
|
|
|
|
return $this->send($phone, $message);
|
|
}
|
|
|
|
/**
|
|
* Send promotional SMS (with opt-out info)
|
|
*/
|
|
public function sendPromotion(string $phone, string $promoMessage): array {
|
|
$message = "Tom's Java Jive: {$promoMessage} " .
|
|
"Reply STOP to unsubscribe.";
|
|
|
|
return $this->send($phone, $message);
|
|
}
|
|
|
|
/**
|
|
* Send order ready for pickup SMS
|
|
*/
|
|
public function sendReadyForPickup(array $order, string $phone): array {
|
|
$message = "Tom's Java Jive: Your order #{$order['order_number']} is ready for pickup! " .
|
|
"Show this message at the counter.";
|
|
|
|
return $this->send($phone, $message);
|
|
}
|
|
|
|
/**
|
|
* Send low wallet balance alert
|
|
*/
|
|
public function sendLowBalanceAlert(string $phone, float $balance): array {
|
|
$message = "Tom's Java Jive: Your wallet balance is " . formatCurrency($balance) . ". " .
|
|
"Top up now to continue enjoying fast checkout!";
|
|
|
|
return $this->send($phone, $message);
|
|
}
|
|
|
|
/**
|
|
* Send loyalty tier upgrade notification
|
|
*/
|
|
public function sendTierUpgrade(string $phone, string $tierName): array {
|
|
$message = "Tom's Java Jive: Congratulations! You've reached {$tierName} status! " .
|
|
"Enjoy your new benefits and rewards. Thank you for being a loyal customer!";
|
|
|
|
return $this->send($phone, $message);
|
|
}
|
|
}
|
|
|
|
// Helper function for easy access
|
|
function sendSMS(): TwilioSMS {
|
|
static $instance = null;
|
|
if ($instance === null) {
|
|
$instance = new TwilioSMS();
|
|
}
|
|
return $instance;
|
|
}
|