Files
calendar/packages/features/ee/workflows/lib/reminders/smsProviders/twilioProvider.ts
T
Carina WollendorferGitHubCarinaWollizomarskodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
c2f150dbab Feat/verify phone number (#6035)
* first implementation of verifying phone number

* add UI + logic for verifying phone number flow

* check if all phone numbers are verified before submit

* add numberVerification pending

* only send SMS to verified numbers

* fix design for mobile view

* check if phone number is verified before testing action

* add back message service id check

* add TWILIO_VERIFY_SID to .env.example

* code clean up

* add TWILIO_VERIFY_SID to README.md instructions

* save new verified numbers

* fix wrongly thrown error for new verified numbers

* use false as default value for isVerificationPending paramater

* add translations

* add migration file

* code clean up

* don't throw error if phone number is not needed

* Feedback

* Shows error when Twillio isn't properly setup

* Type fixes

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: zomars <zomars@me.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2022-12-15 21:54:40 +00:00

75 lines
2.2 KiB
TypeScript

import TwilioClient from "twilio";
declare global {
// eslint-disable-next-line no-var
var twilio: TwilioClient.Twilio | undefined;
}
export const twilio =
globalThis.twilio ||
(process.env.TWILIO_SID && process.env.TWILIO_TOKEN && process.env.TWILIO_MESSAGING_SID)
? TwilioClient(process.env.TWILIO_SID, process.env.TWILIO_TOKEN)
: undefined;
if (process.env.NODE_ENV !== "production") {
globalThis.twilio = twilio;
}
function assertTwilio(twilio: TwilioClient.Twilio | undefined): asserts twilio is TwilioClient.Twilio {
if (!twilio) throw new Error("Twilio credentials are missing from the .env file");
}
export const sendSMS = async (phoneNumber: string, body: string, sender: string) => {
assertTwilio(twilio);
const response = await twilio.messages.create({
body: body,
messagingServiceSid: process.env.TWILIO_MESSAGING_SID,
to: phoneNumber,
from: sender ? sender : process.env.TWILIO_PHONE_NUMBER,
});
return response;
};
export const scheduleSMS = async (phoneNumber: string, body: string, scheduledDate: Date, sender: string) => {
assertTwilio(twilio);
const response = await twilio.messages.create({
body: body,
messagingServiceSid: process.env.TWILIO_MESSAGING_SID,
to: phoneNumber,
scheduleType: "fixed",
sendAt: scheduledDate,
from: sender ? sender : process.env.TWILIO_PHONE_NUMBER,
});
return response;
};
export const cancelSMS = async (referenceId: string) => {
assertTwilio(twilio);
await twilio.messages(referenceId).update({ status: "canceled" });
};
export const sendVerificationCode = async (phoneNumber: string) => {
assertTwilio(twilio);
if (process.env.TWILIO_VERIFY_SID) {
await twilio.verify
.services(process.env.TWILIO_VERIFY_SID)
.verifications.create({ to: phoneNumber, channel: "sms" });
}
};
export const verifyNumber = async (phoneNumber: string, code: string) => {
assertTwilio(twilio);
if (process.env.TWILIO_VERIFY_SID) {
try {
const verification_check = await twilio.verify.v2
.services(process.env.TWILIO_VERIFY_SID)
.verificationChecks.create({ to: phoneNumber, code: code });
return verification_check.status;
} catch (e) {
return "failed";
}
}
};