Port Twilio SMS integration from CFML to PHP
Add sendSMS() to helpers.php using Twilio REST API with cURL, credentials loaded from config/twilio.json. Wire into sendOTP, loginOTP, and sendLoginOTP endpoints, replacing TODO stubs. SMS is auto-skipped on dev environments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4d806d4e1e
commit
08ef54976f
5 changed files with 66 additions and 14 deletions
|
|
@ -37,13 +37,9 @@ $otp = random_int(100000, 999999);
|
||||||
queryTimed("UPDATE Users SET MobileVerifyCode = ? WHERE ID = ?", [$otp, $user['ID']]);
|
queryTimed("UPDATE Users SET MobileVerifyCode = ? WHERE ID = ?", [$otp, $user['ID']]);
|
||||||
|
|
||||||
// Send OTP via Twilio (skip on dev)
|
// Send OTP via Twilio (skip on dev)
|
||||||
$smsMessage = 'Code saved (SMS skipped in dev)';
|
|
||||||
$dev = isDev();
|
$dev = isDev();
|
||||||
|
$smsResult = sendSMS("+1{$phone}", "Your Payfrit code is: {$otp}");
|
||||||
if (!$dev) {
|
$smsMessage = $smsResult['success'] ? 'Login code sent' : ('SMS failed - ' . $smsResult['message']);
|
||||||
// TODO: Twilio integration
|
|
||||||
$smsMessage = 'Login code sent';
|
|
||||||
}
|
|
||||||
|
|
||||||
$resp = [
|
$resp = [
|
||||||
'OK' => true,
|
'OK' => true,
|
||||||
|
|
|
||||||
|
|
@ -66,10 +66,10 @@ try {
|
||||||
[$uid, $code]
|
[$uid, $code]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send OTP via email or SMS (skip on dev)
|
// Send OTP via SMS or email (skip on dev)
|
||||||
if (!$dev) {
|
if (!$dev) {
|
||||||
if (!empty($phone) && !empty($user['ContactNumber'])) {
|
if (!empty($phone) && !empty($user['ContactNumber'])) {
|
||||||
// TODO: Twilio SMS
|
sendSMS("+1" . $user['ContactNumber'], "Your Payfrit login code is: {$code}. It expires in 10 minutes.");
|
||||||
} else {
|
} else {
|
||||||
// TODO: Email sending
|
// TODO: Email sending
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,9 @@ if ($existing) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send OTP via Twilio (skip on dev)
|
// Send OTP via Twilio (skip on dev)
|
||||||
$smsMessage = 'Code saved (SMS skipped in dev)';
|
|
||||||
$dev = isDev();
|
$dev = isDev();
|
||||||
|
$smsResult = sendSMS("+1{$phone}", "Your Payfrit code is: {$otp}");
|
||||||
if (!$dev) {
|
$smsMessage = $smsResult['success'] ? 'Code sent' : ('SMS failed - ' . $smsResult['message']);
|
||||||
// TODO: Twilio integration
|
|
||||||
$smsMessage = 'Code sent';
|
|
||||||
}
|
|
||||||
|
|
||||||
$resp = [
|
$resp = [
|
||||||
'OK' => true,
|
'OK' => true,
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,61 @@ function generateUUID(): string {
|
||||||
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($bytes), 4));
|
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($bytes), 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// TWILIO SMS
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an SMS via Twilio REST API.
|
||||||
|
* Returns ['success' => bool, 'message' => string].
|
||||||
|
* Skips sending on dev (returns success with note).
|
||||||
|
*/
|
||||||
|
function sendSMS(string $to, string $body): array {
|
||||||
|
if (isDev()) {
|
||||||
|
return ['success' => true, 'message' => 'SMS skipped in dev'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$configPath = realpath(__DIR__ . '/../config/twilio.json');
|
||||||
|
if (!$configPath || !file_exists($configPath)) {
|
||||||
|
return ['success' => false, 'message' => 'Twilio config not found'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = json_decode(file_get_contents($configPath), true);
|
||||||
|
$sid = $config['accountSid'] ?? '';
|
||||||
|
$token = $config['authToken'] ?? '';
|
||||||
|
$from = $config['fromNumber'] ?? '';
|
||||||
|
|
||||||
|
if (empty($sid) || empty($token) || empty($from)) {
|
||||||
|
return ['success' => false, 'message' => 'Twilio config incomplete'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = "https://api.twilio.com/2010-04-01/Accounts/{$sid}/Messages.json";
|
||||||
|
|
||||||
|
$ch = curl_init($url);
|
||||||
|
curl_setopt_array($ch, [
|
||||||
|
CURLOPT_POST => true,
|
||||||
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
|
CURLOPT_USERPWD => "{$sid}:{$token}",
|
||||||
|
CURLOPT_POSTFIELDS => http_build_query([
|
||||||
|
'From' => $from,
|
||||||
|
'To' => $to,
|
||||||
|
'Body' => $body,
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
if ($httpCode === 201) {
|
||||||
|
return ['success' => true, 'message' => 'Message sent'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$parsed = json_decode($response, true);
|
||||||
|
$errMsg = $parsed['message'] ?? "HTTP $httpCode";
|
||||||
|
return ['success' => false, 'message' => $errMsg];
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// AUTH MIDDLEWARE
|
// AUTH MIDDLEWARE
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
|
||||||
5
config/twilio.json
Normal file
5
config/twilio.json
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"accountSid": "AC3e218c8f3496f2e3f95d3f9bb943f65a",
|
||||||
|
"authToken": "493df16db970ca6cc141768de2db7db3",
|
||||||
|
"fromNumber": "+16506678425"
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue