diff --git a/README.md b/README.md index 1dba2be..f106c7a 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ We've developed TextWise and have been using it internally for a while, and have Care has been taken to ensure that TextWise works with on-prem or cloud, and has been styled to fit in with the rest of the ConnectWise Manage (PSA) user interface to provide a seamless experience. # Features -- Supports SMSBroadcast and Twilio +- Supports SMSBroadcast, Twilio and ClickSend - Send SMS messages or authentication codes directly to a contact - Authenticate ticket contacts with randomly generated 4 digit codes - Optional configuration for: @@ -33,13 +33,16 @@ The application uses the following environment variables: ## SMS Provider Variables | Variable | Required | Description | Expected Shape | Default | |--|--|--|--|--| -|SMS_PROVIDER|**false**|The SMS provider to use. Currently only supports Twilio or SmsBroadcast|**twilio** or **smsbroadcast**|**smsbroadcast** +|SMS_PROVIDER|**false**|The SMS provider to use. Currently supports Twilio or SmsBroadcast or ClickSend|**twilio** or **smsbroadcast** or **clicksend**|**smsbroadcast** |SMSBROADCAST_USERNAME|**true** if **SMS_PROVIDER** is set to **smsbroadcast**|Your SmsBroadcast username|string |SMSBROADCAST_PASSWORD|**true** if **SMS_PROVIDER** is set to **smsbroadcast**|Your SmsBroadcast password|string |SMSBROADCAST_FROM|**true** if **SMS_PROVIDER** is set to **smsbroadcast**|The from label for your messages|string |TWILIO_AUTH_TOKEN|**true** if **SMS_PROVIDER** is set to **twilio**|Your Twilio auth token|string |TWILIO_ACCOUNT_SID|**true** if **SMS_PROVIDER** is set to **twilio**|Your Twilio account SID|string |TWILIO_PHONE_NUMBER|**true** if **SMS_PROVIDER** is set to **twilio**|The phone number to use for sending|string +|CLICKSEND_USERNAME|**true** if **SMS_PROVIDER** is set to **clicksend**|Your ClickSend API Username|string +|CLICKSEND_PASSWORD|**true** if **SMS_PROVIDER** is set to **clicksend**|Your ClickSend API Key|string +|CLICKSEND_FROM|**false** if **SMS_PROVIDER** is set to **clicksend**|The number/alpha tag you wish to send to. Number must be in internation format. Leave blank to use a shared number|string ## Optional Config Variables | Variable | Required | Description | Expected Shape | Default | diff --git a/src/env.js b/src/env.js index c720305..4afeef6 100644 --- a/src/env.js +++ b/src/env.js @@ -11,13 +11,17 @@ export const env = createEnv({ CW_COMPANY_URL: z.string(), CW_CODE_BASE: z.string().default("v4_6_release"), SMS_AUTH_MSG: z.string().default("Hi! Your auth code is {code}."), - SMS_PROVIDER: z.enum(["twilio", "smsbroadcast"]).default("smsbroadcast"), + SMS_PROVIDER: z.enum(["twilio", "smsbroadcast", "clicksend"]).default("smsbroadcast"), TWILIO_ACCOUNT_SID: z.string().optional().nullish(), TWILIO_AUTH_TOKEN: z.string().optional().nullish(), TWILIO_PHONE_NUMBER: z.string().optional().nullish(), SMSBROADCAST_USERNAME: z.string().optional().nullish(), SMSBROADCAST_PASSWORD: z.string().optional().nullish(), SMSBROADCAST_FROM: z.string().optional().nullish(), + CLICKSEND_USERNAME: z.string().optional().nullish(), + CLICKSEND_PASSWORD: z.string().optional().nullish(), + CLICKSEND_FROM: z.string().optional().nullish(), + }, client: { NEXT_PUBLIC_DEBUG_LOGGING: z diff --git a/src/lib/sms/providers/clicksend.ts b/src/lib/sms/providers/clicksend.ts new file mode 100644 index 0000000..eabe964 --- /dev/null +++ b/src/lib/sms/providers/clicksend.ts @@ -0,0 +1,37 @@ +import { env } from "~/env"; +import type { SMSProvider } from "./../types"; + +export class ClicksendProvider implements SMSProvider { + async sendSms(contactNumber: string, message: string): Promise { + const apiUsername = env.CLICKSEND_USERNAME; + const apiPassword = env.CLICKSEND_PASSWORD; + const fromNumber = env.CLICKSEND_FROM|| ""; + + const messagePayload: any = { + body: message, + to: contactNumber, + source: "TextWise" + }; + + if (fromNumber) { + messagePayload.from = fromNumber; + } + + const body = JSON.stringify({ + messages: [messagePayload] + }); + + const response = await fetch('https://rest.clicksend.com/v3/sms/send', { + method: 'POST', + headers: { + 'Authorization': `Basic ${btoa(`${apiUsername}:${apiPassword}`)}`, + 'Content-Type': 'application/json' + }, + body: body + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + } +} \ No newline at end of file diff --git a/src/lib/sms/providers/index.ts b/src/lib/sms/providers/index.ts index 0c76830..0468057 100644 --- a/src/lib/sms/providers/index.ts +++ b/src/lib/sms/providers/index.ts @@ -1,2 +1,3 @@ export * from './sms-broadcast' -export * from './twilio' \ No newline at end of file +export * from './twilio' +export * from './clicksend' \ No newline at end of file diff --git a/src/lib/sms/utils.ts b/src/lib/sms/utils.ts index 242c7da..fbc7b27 100644 --- a/src/lib/sms/utils.ts +++ b/src/lib/sms/utils.ts @@ -1,4 +1,4 @@ -import { SMSBroadcastProvider, TwilioProvider } from "~/lib/sms/providers"; +import { SMSBroadcastProvider, TwilioProvider, ClicksendProvider } from "~/lib/sms/providers"; import { env } from "~/env"; import type { SMSProvider } from "~/lib/sms/types"; @@ -9,6 +9,8 @@ export const getSMSProvider = (): SMSProvider => { return new TwilioProvider(); case "smsbroadcast": return new SMSBroadcastProvider(); + case "clicksend": + return new ClicksendProvider(); default: throw new Error("Invalid SMS provider in environment variables"); }