Browse Source

Merge pull request #4181 from vvlladd28/improvement/twilio-sms-provider

Twilio SMS provider added support Phone Number's SID or Messaging Service SID
pull/4190/head
Igor Kulikov 6 years ago
committed by GitHub
parent
commit
d77ec66203
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      application/src/main/java/org/thingsboard/server/service/sms/AbstractSmsSender.java
  2. 15
      application/src/main/java/org/thingsboard/server/service/sms/twilio/TwilioSmsSender.java
  3. 8
      ui-ngx/src/app/modules/home/components/sms/twilio-sms-provider-configuration.component.html
  4. 13
      ui-ngx/src/app/modules/home/components/sms/twilio-sms-provider-configuration.component.ts
  5. 1
      ui-ngx/src/app/shared/models/settings.models.ts
  6. 2
      ui-ngx/src/assets/locale/locale.constant-en_US.json

2
application/src/main/java/org/thingsboard/server/service/sms/AbstractSmsSender.java

@ -24,7 +24,7 @@ import java.util.regex.Pattern;
@Slf4j
public abstract class AbstractSmsSender implements SmsSender {
private static final Pattern E_164_PHONE_NUMBER_PATTERN = Pattern.compile("^\\+[1-9]\\d{1,14}$");
protected static final Pattern E_164_PHONE_NUMBER_PATTERN = Pattern.compile("^\\+[1-9]\\d{1,14}$");
private static final int MAX_SMS_MESSAGE_LENGTH = 1600;
private static final int MAX_SMS_SEGMENT_LENGTH = 70;

15
application/src/main/java/org/thingsboard/server/service/sms/twilio/TwilioSmsSender.java

@ -19,21 +19,34 @@ import com.twilio.http.TwilioRestClient;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;
import org.apache.commons.lang3.StringUtils;
import org.thingsboard.rule.engine.api.sms.exception.SmsParseException;
import org.thingsboard.server.common.data.sms.config.TwilioSmsProviderConfiguration;
import org.thingsboard.rule.engine.api.sms.exception.SmsException;
import org.thingsboard.rule.engine.api.sms.exception.SmsSendException;
import org.thingsboard.server.service.sms.AbstractSmsSender;
import java.util.regex.Pattern;
public class TwilioSmsSender extends AbstractSmsSender {
private static final Pattern PHONE_NUMBERS_SID_MESSAGE_SERVICE_SID = Pattern.compile("^(PN|MG).*$");
private TwilioRestClient twilioRestClient;
private String numberFrom;
private String validatePhoneTwilioNumber(String phoneNumber) throws SmsParseException {
phoneNumber = phoneNumber.trim();
if (!E_164_PHONE_NUMBER_PATTERN.matcher(phoneNumber).matches() && !PHONE_NUMBERS_SID_MESSAGE_SERVICE_SID.matcher(phoneNumber).matches()) {
throw new SmsParseException("Invalid phone number format. Phone number must be in E.164 format/Phone Number's SID/Messaging Service SID.");
}
return phoneNumber;
}
public TwilioSmsSender(TwilioSmsProviderConfiguration config) {
if (StringUtils.isEmpty(config.getAccountSid()) || StringUtils.isEmpty(config.getAccountToken()) || StringUtils.isEmpty(config.getNumberFrom())) {
throw new IllegalArgumentException("Invalid twilio sms provider configuration: accountSid, accountToken and numberFrom should be specified!");
}
this.numberFrom = this.validatePhoneNumber(config.getNumberFrom());
this.numberFrom = this.validatePhoneTwilioNumber(config.getNumberFrom());
this.twilioRestClient = new TwilioRestClient.Builder(config.getAccountSid(), config.getAccountToken()).build();
}

8
ui-ngx/src/app/modules/home/components/sms/twilio-sms-provider-configuration.component.html

@ -18,14 +18,14 @@
<form [formGroup]="twilioSmsProviderConfigurationFormGroup" style="padding-bottom: 16px;">
<mat-form-field class="mat-block">
<mat-label translate>admin.number-from</mat-label>
<input type="tel" required [pattern]="phoneNumberPattern" matInput formControlName="numberFrom">
<input type="tel" required [pattern]="phoneNumberPatternTwilio" matInput formControlName="numberFrom">
<mat-error *ngIf="twilioSmsProviderConfigurationFormGroup.get('numberFrom').hasError('required')">
{{ 'admin.number-from-required' | translate }}
</mat-error>
<mat-error *ngIf="twilioSmsProviderConfigurationFormGroup.get('numberFrom').hasError('pattern')">
{{ 'admin.phone-number-pattern' | translate }}
{{ 'admin.phone-number-pattern-twilio' | translate }}
</mat-error>
<mat-hint innerHTML="{{ 'admin.phone-number-hint' | translate }}"></mat-hint>
<mat-hint innerHTML="{{ 'admin.phone-number-hint-twilio' | translate }}"></mat-hint>
</mat-form-field>
<mat-form-field class="mat-block">
<mat-label translate>admin.twilio-account-sid</mat-label>
@ -36,7 +36,7 @@
</mat-form-field>
<mat-form-field class="mat-block">
<mat-label translate>admin.twilio-account-token</mat-label>
<input required type="password" matInput formControlName="accountToken">
<input required type="password" autocomplete="new-password" matInput formControlName="accountToken">
<mat-error *ngIf="twilioSmsProviderConfigurationFormGroup.get('accountToken').hasError('required')">
{{ 'admin.twilio-account-token-required' | translate }}
</mat-error>

13
ui-ngx/src/app/modules/home/components/sms/twilio-sms-provider-configuration.component.ts

@ -21,8 +21,9 @@ import { AppState } from '@app/core/core.state';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { isDefinedAndNotNull } from '@core/utils';
import {
phoneNumberPattern,
SmsProviderConfiguration, SmsProviderType,
phoneNumberPatternTwilio,
SmsProviderConfiguration,
SmsProviderType,
TwilioSmsProviderConfiguration
} from '@shared/models/settings.models';
@ -40,7 +41,7 @@ export class TwilioSmsProviderConfigurationComponent implements ControlValueAcce
twilioSmsProviderConfigurationFormGroup: FormGroup;
phoneNumberPattern = phoneNumberPattern;
phoneNumberPatternTwilio = phoneNumberPatternTwilio;
private requiredValue: boolean;
@ -71,9 +72,9 @@ export class TwilioSmsProviderConfigurationComponent implements ControlValueAcce
ngOnInit() {
this.twilioSmsProviderConfigurationFormGroup = this.fb.group({
numberFrom: [null, [Validators.required, Validators.pattern(phoneNumberPattern)]],
accountSid: [null, [Validators.required]],
accountToken: [null, [Validators.required]]
numberFrom: [null, [Validators.required, Validators.pattern(phoneNumberPatternTwilio)]],
accountSid: [null, Validators.required],
accountToken: [null, Validators.required]
});
this.twilioSmsProviderConfigurationFormGroup.valueChanges.subscribe(() => {
this.updateModel();

1
ui-ngx/src/app/shared/models/settings.models.ts

@ -65,6 +65,7 @@ export interface UpdateMessage {
}
export const phoneNumberPattern = /^\+[1-9]\d{1,14}$/;
export const phoneNumberPatternTwilio = /^\+[1-9]\d{1,14}$|^(MG|PN).*$/;
export enum SmsProviderType {
AWS_SNS = 'AWS_SNS',

2
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -122,7 +122,9 @@
"number-to": "Phone Number To",
"number-to-required": "Phone Number To is required.",
"phone-number-hint": "Phone Number in E.164 format, ex. +19995550123",
"phone-number-hint-twilio": "Phone Number in E.164 format/Phone Number's SID/Messaging Service SID, ex. +19995550123/PNXXX/MGXXX",
"phone-number-pattern": "Invalid phone number. Should be in E.164 format, ex. +19995550123.",
"phone-number-pattern-twilio": "Invalid phone number. Should be in E.164 format/Phone Number's SID/Messaging Service SID, ex. +19995550123/PNXXX/MGXXX.",
"sms-message": "SMS message",
"sms-message-required": "SMS message is required.",
"sms-message-max-length": "SMS message can't be longer 1600 characters",

Loading…
Cancel
Save