Skip to content

Commit

Permalink
Added the function of sending SMS messages through Alibaba Cloud. (#1768
Browse files Browse the repository at this point in the history
)

Co-authored-by: Logic <[email protected]>
  • Loading branch information
lwqzz and zqr10159 authored Apr 18, 2024
1 parent 7d5082f commit d209bd3
Show file tree
Hide file tree
Showing 6 changed files with 332 additions and 0 deletions.
4 changes: 4 additions & 0 deletions common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java-sms</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
</dependency>
<!-- caffeine-->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ public void setAlertsDataTopic(String alertsDataTopic) {
* sms properties
*/
public static class SmsProperties {
//Tencent cloud SMS configuration
private TencentSmsProperties tencent;
//Ali cloud SMS configuration
private AliYunSmsProperties aliYun;

public TencentSmsProperties getTencent() {
return tencent;
Expand All @@ -159,6 +162,14 @@ public TencentSmsProperties getTencent() {
public void setTencent(TencentSmsProperties tencent) {
this.tencent = tencent;
}

public AliYunSmsProperties getAliYun() {
return aliYun;
}

public void setAliYun(AliYunSmsProperties aliYun) {
this.aliYun = aliYun;
}
}

/**
Expand Down Expand Up @@ -231,4 +242,75 @@ public void setTemplateId(String templateId) {
this.templateId = templateId;
}
}

/**
* aliYun sms properties
*/
public static class AliYunSmsProperties {

/**
* Aliyun account access key id
*/
private String secretId;

/**
* Ali Cloud account access key
*/
private String secretKey;

/**
* SMS app id
*/
private String appId;

/**
* SMS signature
*/
private String signName;

/**
* ID of the SMS template
*/
private String templateId;

public String getAppId() {
return appId;
}

public void setAppId(String appId) {
this.appId = appId;
}

public String getSecretId() {
return secretId;
}

public void setSecretId(String secretId) {
this.secretId = secretId;
}

public String getSecretKey() {
return secretKey;
}

public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}

public String getSignName() {
return signName;
}

public void setSignName(String signName) {
this.signName = signName;
}

public String getTemplateId() {
return templateId;
}

public void setTemplateId(String templateId) {
this.templateId = templateId;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hertzbeat.common.service;

import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.common.config.CommonProperties;
import org.apache.hertzbeat.common.support.exception.SendMessageException;
import org.apache.hertzbeat.common.util.AliYunSendSmsUtil;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
* sms service client for aliyun cloud
*/
@Component
@ConditionalOnProperty("common.sms.aliyun.app-id")
@Slf4j
public class AliYunSmsClient {

private static final String RESPONSE_OK = "OK";
private static final String REGION = "ap-guangzhou";

private SmsClient smsClient;
private String appId;
private String signName;
private String templateId;
private String secretId;
private String secretKey;

public AliYunSmsClient(CommonProperties properties) {
if (properties == null || properties.getSms() == null || properties.getSms().getTencent() == null) {
log.error("init error, please config TencentSmsClient props in application.yml");
throw new IllegalArgumentException("please config TencentSmsClient props");
}
initSmsClient(properties.getSms().getAliYun());
}

private void initSmsClient(CommonProperties.AliYunSmsProperties tencent) {
this.appId = tencent.getAppId();
this.signName = tencent.getSignName();
this.templateId = tencent.getTemplateId();
this.secretId = tencent.getSecretId();
this.secretKey = tencent.getSecretKey();
Credential cred = new Credential(tencent.getSecretId(), tencent.getSecretKey());
smsClient = new SmsClient(cred, REGION);
}

/**
* Alibaba cloud sends SMS messages
* @param appId appId
* @param signName sign name
* @param templateId template id
* @param templateValues template values
* @param phones phones num
*/
public void sendMessage(String appId, String signName, String templateId, String secretId, String secretKey,
String[] templateValues, String[] phones){

LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
SendSmsRequest req = new SendSmsRequest();
req.setSmsSdkAppId(appId);
req.setSignName(signName);
req.setTemplateId(templateId);
req.setTemplateParamSet(templateValues);
req.setPhoneNumberSet(phones);
try {
Map<String, Object> param = new HashMap<>();
// taskName: monitoring name, alert: alarm level, message: alarm content, sysTime:system time
param.put("taskName", templateValues[0]);
param.put("alert", templateValues[1]);
param.put("message", templateValues[2]);
param.put("sysTime", dateTime.format(formatter));
SendSmsResponse smsResponse = AliYunSendSmsUtil.send(param, signName, templateId, phones[0], secretId, secretKey);
String code = smsResponse.body.code;
if (!RESPONSE_OK.equals(code)) {
throw new SendMessageException(code + ":" + smsResponse.body.message);
}
} catch (Exception e) {
log.warn(e.getMessage());
throw new SendMessageException(e.getMessage());
}
}

/**
* Send a text message
* @param templateValues template values
* @param phones phones num
*/
public void sendMessage(String[] templateValues, String[] phones) {
sendMessage(this.appId, this.signName, this.templateId, this.secretId, this.secretKey, templateValues, phones);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hertzbeat.common.util;

import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

/**
* Alibaba cloud send SMS util
*/
public class AliYunSendSmsUtil {

public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
Config config = new Config();
config.accessKeyId = accessKeyId;
config.accessKeySecret = accessKeySecret;
return new com.aliyun.dysmsapi20170525.Client(config);
}

/**
* Method for sending SMS messages: Enter the map format
*/
public static SendSmsResponse send(Map<String, Object> map, String singName, String templateCode, String phone, String accessKeyId, String accessKeySecret) throws Exception {
com.aliyun.dysmsapi20170525.Client client = AliYunSendSmsUtil.createClient(accessKeyId, accessKeySecret);
SendSmsRequest sendReq = new SendSmsRequest()
.setPhoneNumbers(phone)//The phone number that received the text message
.setSignName(singName)//SMS signature
.setTemplateCode(templateCode)//SMS Template Code
.setTemplateParam(new ObjectMapper().writeValueAsString(map)); //The actual value of the SMS template variable
SendSmsResponse sendResp = client.sendSms(sendReq);
return sendResp;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hertzbeat.manager.component.alerter.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.common.constants.CommonConstants;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.apache.hertzbeat.common.entity.manager.NoticeReceiver;
import org.apache.hertzbeat.common.entity.manager.NoticeTemplate;
import org.apache.hertzbeat.common.service.AliYunSmsClient;
import org.apache.hertzbeat.common.util.ResourceBundleUtil;
import org.apache.hertzbeat.manager.support.exception.AlertNoticeException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.util.ResourceBundle;

/**
* Send alarm information through Alibaba Cloud SMS
*/
@Component
@RequiredArgsConstructor
@Slf4j
@ConditionalOnProperty("common.sms.aliyun.app-id")
final class AliYunAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl {

private final AliYunSmsClient aliYunSmsClient;

private final ResourceBundle bundle = ResourceBundleUtil.getBundle("alerter");

@Override
public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) {
// SMS notification
try {
String monitorName = null;
if (alert.getTags() != null) {
monitorName = alert.getTags().get(CommonConstants.TAG_MONITOR_NAME);
}
String[] params = new String[3];
params[0] = monitorName == null ? alert.getTarget() : monitorName;
params[1] = bundle.getString("alerter.priority." + alert.getPriority());
params[2] = alert.getContent();
aliYunSmsClient.sendMessage(params, new String[]{receiver.getPhone()});
} catch (Exception e) {
throw new AlertNoticeException("[Sms Notify Error] " + e.getMessage());
}
}

@Override
public byte type() {
return 0;
}
}
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
<guava.version>32.1.2-jre</guava.version>
<protobuf.version>3.19.6</protobuf.version>
<tencentcloud-sdk-java-sms.version>3.1.648</tencentcloud-sdk-java-sms.version>
<aliYun-sdk-java-sms.version>2.0.24</aliYun-sdk-java-sms.version>
<caffeine.version>2.9.3</caffeine.version>
<httpclient.version>4.5.14</httpclient.version>

Expand Down Expand Up @@ -340,6 +341,11 @@
<artifactId>tencentcloud-sdk-java-sms</artifactId>
<version>${tencentcloud-sdk-java-sms.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>${aliYun-sdk-java-sms.version}</version>
</dependency>
<!-- okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
Expand Down

0 comments on commit d209bd3

Please sign in to comment.