mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 22:59:07 +00:00
add call and sms cost
This commit is contained in:
parent
17509225ee
commit
dca1d2c370
@ -28,3 +28,12 @@ export interface CallRequestMessage {
|
|||||||
export default interface CallRequest extends CallRequestMessage {
|
export default interface CallRequest extends CallRequestMessage {
|
||||||
to: Phone;
|
to: Phone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const isHighRiskPhoneNumber: Function = (phoneNumber: Phone): boolean => {
|
||||||
|
// Pakistan
|
||||||
|
if (phoneNumber.toString().startsWith('+92')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# OneUptime notification Deployment
|
# OneUptime notification Deployment
|
||||||
{{- $notificationEnv := dict "PORT" $.Values.port.notification "SMS_DEFAULT_COST_IN_CENTS" $.Values.billing.smsDefaultValueInCents "CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE" $.Values.billing.callDefaultValueInCentsPerMinute "INTERNAL_SMTP_EMAIL" $.Values.internalSmtp.email "INTERNAL_SMTP_PASSWORD" "internal_smtp_password" -}}
|
{{- $notificationEnv := dict "PORT" $.Values.port.notification "SMS_HIGH_RISK_COST_IN_CENTS" $.Values.billing.smsHighRiskValueInCents "CALL_HIGH_RISK_COST_IN_CENTS_PER_MINUTE" $.Values.billing.callHighRiskValueInCentsPerMinute "SMS_DEFAULT_COST_IN_CENTS" $.Values.billing.smsDefaultValueInCents "CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE" $.Values.billing.callDefaultValueInCentsPerMinute "INTERNAL_SMTP_EMAIL" $.Values.internalSmtp.email "INTERNAL_SMTP_PASSWORD" "internal_smtp_password" -}}
|
||||||
{{- $notificationDeploymentArgs :=dict "IsServer" true "ServiceName" "notification" "Port" $.Values.port.notification "Release" $.Release "Values" $.Values "Env" $notificationEnv -}}
|
{{- $notificationDeploymentArgs :=dict "IsServer" true "ServiceName" "notification" "Port" $.Values.port.notification "Release" $.Release "Values" $.Values "Env" $notificationEnv -}}
|
||||||
{{- include "oneuptime.deployment" $notificationDeploymentArgs }}
|
{{- include "oneuptime.deployment" $notificationDeploymentArgs }}
|
||||||
---
|
---
|
||||||
|
@ -87,7 +87,9 @@ billing:
|
|||||||
publicKey:
|
publicKey:
|
||||||
privateKey:
|
privateKey:
|
||||||
smsDefaultValueInCents:
|
smsDefaultValueInCents:
|
||||||
callDefaultValueInCentsPerMinute:
|
callDefaultValueInCentsPerMinute:
|
||||||
|
smsHighRiskValueInCents:
|
||||||
|
callHighRiskValueInCentsPerMinute:
|
||||||
|
|
||||||
subscriptionPlan:
|
subscriptionPlan:
|
||||||
basic:
|
basic:
|
||||||
|
@ -185,6 +185,18 @@ export const SMSDefaultCostInCents: number = process.env[
|
|||||||
? parseInt(process.env['SMS_DEFAULT_COST_IN_CENTS'])
|
? parseInt(process.env['SMS_DEFAULT_COST_IN_CENTS'])
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
|
export const SMSHighRiskCostInCents: number = process.env[
|
||||||
|
'SMS_HIGH_RISK_COST_IN_CENTS'
|
||||||
|
]
|
||||||
|
? parseInt(process.env['SMS_HIGH_RISK_COST_IN_CENTS'])
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
export const CallHighRiskCostInCentsPerMinute: number = process.env[
|
||||||
|
'CALL_HIGH_RISK_COST_IN_CENTS_PER_MINUTE'
|
||||||
|
]
|
||||||
|
? parseInt(process.env['CALL_HIGH_RISK_COST_IN_CENTS_PER_MINUTE'])
|
||||||
|
: 0;
|
||||||
|
|
||||||
export const CallDefaultCostInCentsPerMinute: number = process.env[
|
export const CallDefaultCostInCentsPerMinute: number = process.env[
|
||||||
'CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE'
|
'CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE'
|
||||||
]
|
]
|
||||||
|
@ -2,13 +2,18 @@ import ObjectID from 'Common/Types/ObjectID';
|
|||||||
import Phone from 'Common/Types/Phone';
|
import Phone from 'Common/Types/Phone';
|
||||||
import {
|
import {
|
||||||
CallDefaultCostInCentsPerMinute,
|
CallDefaultCostInCentsPerMinute,
|
||||||
|
CallHighRiskCostInCentsPerMinute,
|
||||||
TwilioConfig,
|
TwilioConfig,
|
||||||
getTwilioConfig,
|
getTwilioConfig,
|
||||||
} from '../Config';
|
} from '../Config';
|
||||||
import Twilio from 'twilio';
|
import Twilio from 'twilio';
|
||||||
import CallLog from 'Model/Models/CallLog';
|
import CallLog from 'Model/Models/CallLog';
|
||||||
import CallStatus from 'Common/Types/Call/CallStatus';
|
import CallStatus from 'Common/Types/Call/CallStatus';
|
||||||
import CallRequest, { GatherInput, Say } from 'Common/Types/Call/CallRequest';
|
import CallRequest, {
|
||||||
|
GatherInput,
|
||||||
|
Say,
|
||||||
|
isHighRiskPhoneNumber,
|
||||||
|
} from 'Common/Types/Call/CallRequest';
|
||||||
import { IsBillingEnabled } from 'CommonServer/EnvironmentConfig';
|
import { IsBillingEnabled } from 'CommonServer/EnvironmentConfig';
|
||||||
import CallLogService from 'CommonServer/Services/CallLogService';
|
import CallLogService from 'CommonServer/Services/CallLogService';
|
||||||
import ProjectService from 'CommonServer/Services/ProjectService';
|
import ProjectService from 'CommonServer/Services/ProjectService';
|
||||||
@ -33,6 +38,15 @@ export default class CallService {
|
|||||||
userOnCallLogTimelineId?: ObjectID | undefined; // user notification log timeline id
|
userOnCallLogTimelineId?: ObjectID | undefined; // user notification log timeline id
|
||||||
}
|
}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
let callCost: number = 0;
|
||||||
|
|
||||||
|
if (IsBillingEnabled) {
|
||||||
|
callCost = CallDefaultCostInCentsPerMinute / 100;
|
||||||
|
if (isHighRiskPhoneNumber(callRequest.to)) {
|
||||||
|
callCost = CallHighRiskCostInCentsPerMinute / 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const twilioConfig: TwilioConfig | null = await getTwilioConfig();
|
const twilioConfig: TwilioConfig | null = await getTwilioConfig();
|
||||||
|
|
||||||
if (!twilioConfig) {
|
if (!twilioConfig) {
|
||||||
@ -165,9 +179,7 @@ export default class CallService {
|
|||||||
`We tried to make a call to ${callRequest.to.toString()}. This call was not made because project does not have enough balance to make calls. Current balance is ${
|
`We tried to make a call to ${callRequest.to.toString()}. This call was not made because project does not have enough balance to make calls. Current balance is ${
|
||||||
(project.smsOrCallCurrentBalanceInUSDCents ||
|
(project.smsOrCallCurrentBalanceInUSDCents ||
|
||||||
0) / 100
|
0) / 100
|
||||||
} USD. Required balance to send this SMS should is ${
|
} USD. Required balance to send this SMS should is ${callCost} USD. Please enable auto recharge or recharge manually.`
|
||||||
CallDefaultCostInCentsPerMinute / 100
|
|
||||||
} USD. Please enable auto recharge or recharge manually.`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -175,14 +187,12 @@ export default class CallService {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
project.smsOrCallCurrentBalanceInUSDCents <
|
project.smsOrCallCurrentBalanceInUSDCents <
|
||||||
CallDefaultCostInCentsPerMinute
|
callCost * 100
|
||||||
) {
|
) {
|
||||||
callLog.status = CallStatus.LowBalance;
|
callLog.status = CallStatus.LowBalance;
|
||||||
callLog.statusMessage = `Project does not have enough balance to make this call. Current balance is ${
|
callLog.statusMessage = `Project does not have enough balance to make this call. Current balance is ${
|
||||||
project.smsOrCallCurrentBalanceInUSDCents / 100
|
project.smsOrCallCurrentBalanceInUSDCents / 100
|
||||||
} USD. Required balance is ${
|
} USD. Required balance is ${callCost} USD to make this call.`;
|
||||||
CallDefaultCostInCentsPerMinute / 100
|
|
||||||
} USD to make this call.`;
|
|
||||||
logger.error(callLog.statusMessage);
|
logger.error(callLog.statusMessage);
|
||||||
await CallLogService.create({
|
await CallLogService.create({
|
||||||
data: callLog,
|
data: callLog,
|
||||||
@ -207,9 +217,7 @@ export default class CallService {
|
|||||||
(project.name || ''),
|
(project.name || ''),
|
||||||
`We tried to make a call to ${callRequest.to.toString()}. This call was not made because project does not have enough balance to make a call. Current balance is ${
|
`We tried to make a call to ${callRequest.to.toString()}. This call was not made because project does not have enough balance to make a call. Current balance is ${
|
||||||
project.smsOrCallCurrentBalanceInUSDCents / 100
|
project.smsOrCallCurrentBalanceInUSDCents / 100
|
||||||
} USD. Required balance is ${
|
} USD. Required balance is ${callCost} USD to make this call. Please enable auto recharge or recharge manually.`
|
||||||
CallDefaultCostInCentsPerMinute / 100
|
|
||||||
} USD to make this call. Please enable auto recharge or recharge manually.`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -230,18 +238,17 @@ export default class CallService {
|
|||||||
logger.info('Call Request sent successfully.');
|
logger.info('Call Request sent successfully.');
|
||||||
logger.info(callLog.statusMessage);
|
logger.info(callLog.statusMessage);
|
||||||
if (IsBillingEnabled && project) {
|
if (IsBillingEnabled && project) {
|
||||||
callLog.callCostInUSDCents = CallDefaultCostInCentsPerMinute;
|
callLog.callCostInUSDCents = callCost * 100;
|
||||||
|
|
||||||
if (twillioCall && parseInt(twillioCall.duration) > 60) {
|
if (twillioCall && parseInt(twillioCall.duration) > 60) {
|
||||||
callLog.callCostInUSDCents = Math.ceil(
|
callLog.callCostInUSDCents = Math.ceil(
|
||||||
Math.ceil(parseInt(twillioCall.duration) / 60) *
|
Math.ceil(parseInt(twillioCall.duration) / 60) *
|
||||||
CallDefaultCostInCentsPerMinute
|
(callCost * 100)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
project.smsOrCallCurrentBalanceInUSDCents = Math.floor(
|
project.smsOrCallCurrentBalanceInUSDCents = Math.floor(
|
||||||
project.smsOrCallCurrentBalanceInUSDCents! -
|
project.smsOrCallCurrentBalanceInUSDCents! - callCost * 100
|
||||||
CallDefaultCostInCentsPerMinute
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await ProjectService.updateOneById({
|
await ProjectService.updateOneById({
|
||||||
|
@ -2,6 +2,7 @@ import ObjectID from 'Common/Types/ObjectID';
|
|||||||
import Phone from 'Common/Types/Phone';
|
import Phone from 'Common/Types/Phone';
|
||||||
import {
|
import {
|
||||||
SMSDefaultCostInCents,
|
SMSDefaultCostInCents,
|
||||||
|
SMSHighRiskCostInCents,
|
||||||
TwilioConfig,
|
TwilioConfig,
|
||||||
getTwilioConfig,
|
getTwilioConfig,
|
||||||
} from '../Config';
|
} from '../Config';
|
||||||
@ -18,6 +19,7 @@ import logger from 'CommonServer/Utils/Logger';
|
|||||||
import UserOnCallLogTimelineService from 'CommonServer/Services/UserOnCallLogTimelineService';
|
import UserOnCallLogTimelineService from 'CommonServer/Services/UserOnCallLogTimelineService';
|
||||||
import UserNotificationStatus from 'Common/Types/UserNotification/UserNotificationStatus';
|
import UserNotificationStatus from 'Common/Types/UserNotification/UserNotificationStatus';
|
||||||
import BadDataException from 'Common/Types/Exception/BadDataException';
|
import BadDataException from 'Common/Types/Exception/BadDataException';
|
||||||
|
import { isHighRiskPhoneNumber } from 'Common/Types/Call/CallRequest';
|
||||||
|
|
||||||
export default class SmsService {
|
export default class SmsService {
|
||||||
public static async sendSms(
|
public static async sendSms(
|
||||||
@ -30,6 +32,16 @@ export default class SmsService {
|
|||||||
userOnCallLogTimelineId?: ObjectID | undefined;
|
userOnCallLogTimelineId?: ObjectID | undefined;
|
||||||
}
|
}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
let smsCost: number = 0;
|
||||||
|
|
||||||
|
if (IsBillingEnabled) {
|
||||||
|
smsCost = SMSDefaultCostInCents / 100;
|
||||||
|
|
||||||
|
if (isHighRiskPhoneNumber(to)) {
|
||||||
|
smsCost = SMSHighRiskCostInCents / 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const twilioConfig: TwilioConfig | null = await getTwilioConfig();
|
const twilioConfig: TwilioConfig | null = await getTwilioConfig();
|
||||||
|
|
||||||
if (!twilioConfig) {
|
if (!twilioConfig) {
|
||||||
@ -161,24 +173,17 @@ export default class SmsService {
|
|||||||
`We tried to send an SMS to ${to.toString()} with message: <br/> <br/> ${message} <br/>This SMS was not sent because project does not have enough balance to send SMS. Current balance is ${
|
`We tried to send an SMS to ${to.toString()} with message: <br/> <br/> ${message} <br/>This SMS was not sent because project does not have enough balance to send SMS. Current balance is ${
|
||||||
(project.smsOrCallCurrentBalanceInUSDCents ||
|
(project.smsOrCallCurrentBalanceInUSDCents ||
|
||||||
0) / 100
|
0) / 100
|
||||||
} USD cents. Required balance to send this SMS should is ${
|
} USD cents. Required balance to send this SMS should is ${smsCost} USD. Please enable auto recharge or recharge manually.`
|
||||||
SMSDefaultCostInCents / 100
|
|
||||||
} USD. Please enable auto recharge or recharge manually.`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (project.smsOrCallCurrentBalanceInUSDCents < smsCost * 100) {
|
||||||
project.smsOrCallCurrentBalanceInUSDCents <
|
|
||||||
SMSDefaultCostInCents
|
|
||||||
) {
|
|
||||||
smsLog.status = SmsStatus.LowBalance;
|
smsLog.status = SmsStatus.LowBalance;
|
||||||
smsLog.statusMessage = `Project does not have enough balance to send SMS. Current balance is ${
|
smsLog.statusMessage = `Project does not have enough balance to send SMS. Current balance is ${
|
||||||
project.smsOrCallCurrentBalanceInUSDCents / 100
|
project.smsOrCallCurrentBalanceInUSDCents / 100
|
||||||
} USD. Required balance is ${
|
} USD. Required balance is ${smsCost} USD to send this SMS.`;
|
||||||
SMSDefaultCostInCents / 100
|
|
||||||
} USD to send this SMS.`;
|
|
||||||
logger.error(smsLog.statusMessage);
|
logger.error(smsLog.statusMessage);
|
||||||
await SmsLogService.create({
|
await SmsLogService.create({
|
||||||
data: smsLog,
|
data: smsLog,
|
||||||
@ -203,9 +208,7 @@ export default class SmsService {
|
|||||||
(project.name || ''),
|
(project.name || ''),
|
||||||
`We tried to send an SMS to ${to.toString()} with message: <br/> <br/> ${message} <br/> <br/> This SMS was not sent because project does not have enough balance to send SMS. Current balance is ${
|
`We tried to send an SMS to ${to.toString()} with message: <br/> <br/> ${message} <br/> <br/> This SMS was not sent because project does not have enough balance to send SMS. Current balance is ${
|
||||||
project.smsOrCallCurrentBalanceInUSDCents / 100
|
project.smsOrCallCurrentBalanceInUSDCents / 100
|
||||||
} USD. Required balance is ${
|
} USD. Required balance is ${smsCost} USD to send this SMS. Please enable auto recharge or recharge manually.`
|
||||||
SMSDefaultCostInCents / 100
|
|
||||||
} USD to send this SMS. Please enable auto recharge or recharge manually.`
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -229,11 +232,10 @@ export default class SmsService {
|
|||||||
logger.info(smsLog.statusMessage);
|
logger.info(smsLog.statusMessage);
|
||||||
|
|
||||||
if (IsBillingEnabled && project) {
|
if (IsBillingEnabled && project) {
|
||||||
smsLog.smsCostInUSDCents = SMSDefaultCostInCents;
|
smsLog.smsCostInUSDCents = smsCost * 100;
|
||||||
|
|
||||||
project.smsOrCallCurrentBalanceInUSDCents = Math.floor(
|
project.smsOrCallCurrentBalanceInUSDCents = Math.floor(
|
||||||
project.smsOrCallCurrentBalanceInUSDCents! -
|
project.smsOrCallCurrentBalanceInUSDCents! - smsCost * 100
|
||||||
SMSDefaultCostInCents
|
|
||||||
);
|
);
|
||||||
|
|
||||||
await ProjectService.updateOneById({
|
await ProjectService.updateOneById({
|
||||||
|
@ -177,6 +177,9 @@ METERED_PLAN_ACTIVE_MONITORING=priceMonthlyId,1,active-monitor,month
|
|||||||
SMS_DEFAULT_COST_IN_CENTS=
|
SMS_DEFAULT_COST_IN_CENTS=
|
||||||
CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE=
|
CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE=
|
||||||
|
|
||||||
|
SMS_HIGH_RISK_COST_IN_CENTS=
|
||||||
|
CALL_HIGH_RISK_COST_IN_CENTS_PER_MINUTE=
|
||||||
|
|
||||||
# IS BILLING ENABLED for this installer.
|
# IS BILLING ENABLED for this installer.
|
||||||
BILLING_ENABLED=false
|
BILLING_ENABLED=false
|
||||||
# Public and private key for billing provider, usually stripe.
|
# Public and private key for billing provider, usually stripe.
|
||||||
|
@ -172,6 +172,8 @@ services:
|
|||||||
PORT: ${NOTIFICATION_PORT}
|
PORT: ${NOTIFICATION_PORT}
|
||||||
SMS_DEFAULT_COST_IN_CENTS: ${SMS_DEFAULT_COST_IN_CENTS}
|
SMS_DEFAULT_COST_IN_CENTS: ${SMS_DEFAULT_COST_IN_CENTS}
|
||||||
CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE: ${CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE}
|
CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE: ${CALL_DEFAULT_COST_IN_CENTS_PER_MINUTE}
|
||||||
|
SMS_HIGH_RISK_COST_IN_CENTS: ${SMS_HIGH_RISK_COST_IN_CENTS}
|
||||||
|
CALL_HIGH_RISK_COST_IN_CENTS_PER_MINUTE: ${CALL_HIGH_RISK_COST_IN_CENTS_PER_MINUTE}
|
||||||
INTERNAL_SMTP_EMAIL: ${INTERNAL_SMTP_EMAIL}
|
INTERNAL_SMTP_EMAIL: ${INTERNAL_SMTP_EMAIL}
|
||||||
INTERNAL_SMTP_PASSWORD: ${INTERNAL_SMTP_PASSWORD}
|
INTERNAL_SMTP_PASSWORD: ${INTERNAL_SMTP_PASSWORD}
|
||||||
depends_on:
|
depends_on:
|
||||||
|
Loading…
Reference in New Issue
Block a user