80 lines
2.6 KiB
JavaScript
80 lines
2.6 KiB
JavaScript
// backend/utils/smsService.js
|
||
// Centralised Twilio helper + DB helpers for the Reminders feature.
|
||
// Now *also* writes back status → reminders.status and sent_at so the
|
||
// cron‑job doesn’t need its own UPDATE logic.
|
||
|
||
import twilio from 'twilio';
|
||
import { v4 as uuid } from 'uuid';
|
||
import db from '../config/mysqlPool.js';
|
||
|
||
const {
|
||
TWILIO_ACCOUNT_SID,
|
||
TWILIO_AUTH_TOKEN,
|
||
TWILIO_MESSAGING_SERVICE_SID
|
||
} = process.env;
|
||
|
||
if (!TWILIO_ACCOUNT_SID || !TWILIO_AUTH_TOKEN || !TWILIO_MESSAGING_SERVICE_SID) {
|
||
throw new Error('Twilio env vars missing; check env or PM2 config');
|
||
}
|
||
|
||
const client = twilio(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN);
|
||
|
||
/* ────────────────────────────────────────────────────────────── *
|
||
Immediate send + status update
|
||
------------------------------------------------------------------ */
|
||
export async function sendSMS ({ reminderId = null, to, body }) {
|
||
try {
|
||
const msg = await client.messages.create({
|
||
to,
|
||
body,
|
||
messagingServiceSid: TWILIO_MESSAGING_SERVICE_SID
|
||
});
|
||
|
||
// Mark success if we were called from reminderCron
|
||
if (reminderId) {
|
||
await db.execute(
|
||
`UPDATE reminders
|
||
SET status = 'sent',
|
||
sent_at = UTC_TIMESTAMP(),
|
||
twilio_sid = ?
|
||
WHERE id = ?`,
|
||
[msg.sid, reminderId]
|
||
);
|
||
}
|
||
|
||
return msg;
|
||
} catch (err) {
|
||
// Persist failure so we don’t keep retrying blindly
|
||
if (reminderId) {
|
||
await db.execute(
|
||
`UPDATE reminders
|
||
SET status = 'failed',
|
||
sent_at = UTC_TIMESTAMP(),
|
||
error_code = ?
|
||
WHERE id = ?`,
|
||
[err.code || null, reminderId]
|
||
);
|
||
}
|
||
throw err; // propagate so cron can log
|
||
}
|
||
}
|
||
|
||
/* ────────────────────────────────────────────────────────────── *
|
||
Persist a *future* reminder row
|
||
------------------------------------------------------------------ */
|
||
export async function createReminder ({ userId, phone, body, sendAtUtc }) {
|
||
const id = uuid();
|
||
const mysqlDateTime = new Date(sendAtUtc)
|
||
.toISOString()
|
||
.slice(0, 19) // 2025-06-17T22:00:00
|
||
.replace('T', ' '); // 2025-06-17 22:00:00
|
||
|
||
await db.execute(
|
||
`INSERT INTO reminders (id, user_id, phone_e164, message_body, send_at_utc)
|
||
VALUES (?,?,?,?,?)`,
|
||
[id, userId, phone, body.slice(0, 320), mysqlDateTime]
|
||
);
|
||
|
||
return id;
|
||
}
|