Compare commits

...
Author SHA1 Message Date
a-little-fool 9d1206d1c7 [doc] add smslocal help-doc 2025-03-09 20:50:19 +08:00
淞筱andgithub-actions[bot] 3a00d8a6fa Update hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/pojo/dto/SmslocalConfig.java
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: 淞筱 <105542329+a-little-fool@users.noreply.github.com>
2025-03-09 18:41:57 +08:00
a-little-fool 5168a9abc9 [bugfix] fix 2025-03-09 18:39:51 +08:00
a-little-fool 68ead5687a [bugfix] fix 2025-03-09 17:55:01 +08:00
a-little-fool 7f259f77e7 [feature] add smslocal sms notification 2025-03-09 14:46:29 +08:00
a-little-fool c48a46b24a [feature] add smslocal sms notification 2025-03-09 14:26:25 +08:00
a-little-fool 5e9358b81d fix 2025-03-09 09:34:30 +08:00
a-little-fool c65bd9174e fix 2025-03-09 09:27:15 +08:00
yunfan24 d1693fbf8e Merge branch 'master' into smslocal-notice 2025-03-08 16:49:03 +08:00
淞筱andyunfan24 4746951967 Update hertzbeat-manager/src/main/resources/application.yml
Co-authored-by: yunfan24 <yunfan24@outlook.com>
Signed-off-by: 淞筱 <105542329+a-little-fool@users.noreply.github.com>
2025-03-08 10:43:11 +08:00
a-little-fool 0b8c4e7c36 [improve] format code 2025-03-06 17:08:21 +08:00
a-little-fool fc6406b1c1 [improve] deal apache license 2025-03-06 16:59:46 +08:00
淞筱andgithub-actions[bot] 7e349bfa27 Update hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/config/SmslocalSmsProperties.java
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: 淞筱 <105542329+a-little-fool@users.noreply.github.com>
2025-03-06 16:55:03 +08:00
淞筱andgithub-actions[bot] 5454099532 Update hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/SmsLocalSmsClientImpl.java
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: 淞筱 <105542329+a-little-fool@users.noreply.github.com>
2025-03-06 16:52:08 +08:00
a-little-fool 2fe9c1cb9d [improve] Add apache license 2025-03-06 16:49:35 +08:00
a-little-fool f8706aae92 [feature] Add SMSLocal notification service 2025-03-06 16:36:04 +08:00
24 changed files with 361 additions and 10 deletions
@@ -54,4 +54,8 @@ public class SmsConfig {
*/
private UniSmsProperties unisms;
/**
* Smslocal SMS configuration
*/
private SmslocalSmsProperties smslocal;
}
@@ -0,0 +1,33 @@
/*
* 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.alert.config;
import lombok.Data;
/**
* Smslocal SMS Properties
*/
@Data
public class SmslocalSmsProperties {
/**
* SmsLocal account api key
*/
private String apiKey;
}
@@ -20,6 +20,7 @@ package org.apache.hertzbeat.alert.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.config.SmsConfig;
import org.apache.hertzbeat.alert.service.impl.SmsLocalSmsClientImpl;
import org.apache.hertzbeat.alert.service.impl.TencentSmsClientImpl;
import org.apache.hertzbeat.alert.service.impl.UniSmsClientImpl;
import org.apache.hertzbeat.alert.service.impl.AlibabaSmsClientImpl;
@@ -33,6 +34,7 @@ import org.springframework.stereotype.Component;
import static org.apache.hertzbeat.common.constants.SmsConstants.ALIBABA;
import static org.apache.hertzbeat.common.constants.SmsConstants.TENCENT;
import static org.apache.hertzbeat.common.constants.SmsConstants.UNISMS;
import static org.apache.hertzbeat.common.constants.SmsConstants.SMSLOCAL;
/**
* SMS client factory
@@ -49,9 +51,7 @@ public class SmsClientFactory {
private volatile SmsClient currentSmsClient;
public SmsClientFactory(GeneralConfigDao generalConfigDao,
ObjectMapper objectMapper,
SmsConfig yamlSmsConfig) {
public SmsClientFactory(GeneralConfigDao generalConfigDao, ObjectMapper objectMapper, SmsConfig yamlSmsConfig) {
this.generalConfigDao = generalConfigDao;
this.objectMapper = objectMapper;
this.yamlSmsConfig = yamlSmsConfig;
@@ -133,6 +133,9 @@ public class SmsClientFactory {
case ALIBABA:
currentSmsClient = new AlibabaSmsClientImpl(smsConfig.getAlibaba());
break;
case SMSLOCAL:
currentSmsClient = new SmsLocalSmsClientImpl(smsConfig.getSmslocal());
break;
default:
log.warn("[SmsClientFactory] Unsupported SMS provider type: {}", smsConfig.getType());
break;
@@ -0,0 +1,146 @@
/*
* 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.alert.service.impl;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.config.SmslocalSmsProperties;
import org.apache.hertzbeat.alert.service.SmsClient;
import org.apache.hertzbeat.common.constants.SmsConstants;
import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
import org.apache.hertzbeat.common.entity.alerter.NoticeReceiver;
import org.apache.hertzbeat.common.entity.alerter.NoticeTemplate;
import org.apache.hertzbeat.common.support.exception.SendMessageException;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
/**
* Smslocal SMS Client Implement
*/
@Slf4j
public class SmsLocalSmsClientImpl implements SmsClient {
private static final String HOST = "secure.smslocal.com";
private static final String PATH = "/api/service/enterprise-service/external/sms";
private static final String FROM = "Hertzbeat";
private static final String SUCCESS_CODE = "200";
private final SmslocalSmsProperties config;
public SmsLocalSmsClientImpl(SmslocalSmsProperties smslocalSmsProperties) {
this.config = smslocalSmsProperties;
}
@Override
public void sendMessage(NoticeReceiver receiver, NoticeTemplate noticeTemplate, GroupAlert alert) {
if (Objects.isNull(receiver) || Objects.isNull(alert)) {
log.warn("receiver and alert can not be null! receiver: {}, alert:{}", receiver, alert);
return;
}
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
String content = alert.getCommonAnnotations().get("summary");
if (Objects.isNull(content) || Objects.isNull(alert.getCommonAnnotations().get("description"))) {
content = alert.getAlerts().get(0).getContent();
}
SmsMessage smsMessage = new SmsMessage(FROM, receiver.getPhone(), content);
String payload = JsonUtil.toJson(smsMessage);
HttpPost httpPost = new HttpPost("https://" + HOST + PATH);
httpPost.setHeader("Content-Type", "application/json; charset=utf-8");
httpPost.setHeader("Token", config.getApiKey());
httpPost.setEntity(new StringEntity(payload, StandardCharsets.UTF_8));
log.debug("Sending SMS request to {}, payload: {}", httpPost.getURI(), payload);
// send http request and handle response
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
int statusCode = response.getStatusLine().getStatusCode();
String responseBody = EntityUtils.toString(response.getEntity());
log.debug("SMS response status: {}, body: {}", statusCode, responseBody);
if (statusCode != 200) {
throw new SendMessageException("HTTP request failed with status code: " + statusCode);
}
JsonNode jsonResponse = JsonUtil.fromJson(responseBody);
JsonNode jsonNode = jsonResponse.get(0);
if (Objects.isNull(jsonNode)) {
log.warn("jsonResponse parse errorCode failed: {}", jsonResponse);
return;
}
String errorCode = jsonNode.get("errorCode").asText();
if (!SUCCESS_CODE.equals(errorCode)) {
String msgid = jsonNode.get("id").asText();
throw new SendMessageException(errorCode + ":" + msgid);
}
log.info("Successfully sent SMS to phone: {}", receiver.getPhone());
}
} catch (Exception e) {
log.error("Failed to send SMS: {}", e.getMessage());
throw new SendMessageException(e.getMessage());
}
}
@Override
public String getType() {
return SmsConstants.SMSLOCAL;
}
@Override
public boolean checkConfig() {
if (Objects.isNull(config) || Objects.isNull(config.getApiKey()) || config.getApiKey().isBlank()) {
log.warn("smslocal properties can not be null: {}", config);
return false;
}
return true;
}
@Getter
@Setter
private static class SmsMessage {
String from;
String to;
String content;
final int datacoding = 0;
final String direction = "mt";
public SmsMessage(String from, String to, String content) {
this.from = from;
this.to = to;
this.content = content;
}
}
}
@@ -23,10 +23,13 @@ package org.apache.hertzbeat.common.constants;
public interface SmsConstants {
// Tencent cloud SMS
String TENCENT = "tencent";
// Alibaba Cloud SMS
String ALIBABA = "alibaba";
// UniSMS
String UNISMS = "unisms";
// Smslocal SMS
String SMSLOCAL = "smslocal";
}
@@ -39,5 +39,7 @@ public class SmsNoticeSender {
private SmsUniSmsConfig unisms;
private SmslocalConfig smslocal;
private boolean enable = true;
}
@@ -0,0 +1,38 @@
/*
* 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.pojo.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Smslocal SMS configuration
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SmslocalConfig {
/**
* Smslocal api key
*/
private String apiKey;
}
@@ -225,6 +225,8 @@ alerter:
access-key-secret: YOUR_ACCESS_KEY_SECRET
signature: YOUR_SMS_SIGNATURE
template-id: YOUR_TEMPLATE_ID
smslocal:
api-key: YOUR_API_KEY_HERE
scheduler:
server:
@@ -247,4 +249,4 @@ ai:
# api key
api-key:
#At present, only IFLYTEK large model needs to be filled in
api-secret:
api-secret:
+27
View File
@@ -156,6 +156,33 @@ alerter:
Now you can configure this information in your hertzbeat application.
### Smslocal SMS Configuration
SMSLocal is an all-in-one SMS service for businesses, with features like multi-way sending, strong security, and 24/7 support. You can refer to smslocal's [Developer Documentation](https://www.smslocal.com/developer/) for configuration.
Add/Fill in the following Smslocal configuration to `application.yml` (replace parameters with your own SMS server configuration):
```yaml
alerter:
sms:
enable: true # Whether to enable
type: smslocal # SMS provider type, set to smslocal
smslocal: # Smslocal configuration
api-key: YOUR_API_KEY_HERE
```
1. Register smslocal account
- Visit [Smslocal Website](https://www.smslocal.com/)
2. Obtain `api-key`
- Log in to [Smslocal Api Access](https://secure.smslocal.com/cpaas/pages/profile/settings/api-reference)
- Go to "API Access" page
- Click the eye button
- Copy the displayed access key
- Then you can configure the `application.yml` file
Now you can configure this information in your hertzbeat application.
## Operation steps
1. **【Alarm notification】->【Add new recipient】 ->【Select SMS notification method】**
@@ -155,6 +155,33 @@ alerter:
现在您可以把这些信息配置到您的hertzbeat应用中。
### smslocal短信配置
smslocal是一款面向企业的一体化短信服务平台,具备诸如多种发送方式、强大的安全性以及全天候支持等特性。你可以参考 smslocal 的[开发者文档](https://www.smslocal.com/developer/)来进行配置。
在 `application.yml` 中添加/填写以下 smslocal 配置内容(请用你自己的短信服务器配置参数替换相关参数):
```yaml
alerter:
sms:
enable: true # 是否启用
type: smslocal # 短信服务提供商类型,设置为smslocal
smslocal: # smslocal配置
api-key: 在此处填入你的API密钥
```
1. 注册 smslocal 账号
- 访问 [smslocal官网](https://www.smslocal.com/)
2. 获取 `api-key`
- 登录 [smslocal API accessKey访问页面](https://secure.smslocal.com/cpaas/pages/profile/settings/api-reference)
- 进入 “API 访问” 页面
- 点击眼睛图标按钮
- 复制显示的访问密钥
- 然后你就可以配置 `application.yml` 文件了
现在你可以在你的 Hertzbeat 应用程序中配置这些信息。
## 操作步骤
1. **【告警通知】->【新增接收人】 ->【选择短信通知方式】**
+2
View File
@@ -224,6 +224,8 @@ alerter:
access-key-secret: YOUR_ACCESS_KEY_SECRET
signature: YOUR_SMS_SIGNATURE
template-id: YOUR_TEMPLATE_ID
smslocal:
api-key: YOUR_API_KEY_HERE
scheduler:
server:
@@ -191,6 +191,8 @@ alerter:
access-key-secret: YOUR_ACCESS_KEY_SECRET
signature: YOUR_SMS_SIGNATURE
template-id: YOUR_TEMPLATE_ID
smslocal:
api-key: YOUR_API_KEY_HERE
scheduler:
server:
@@ -187,6 +187,8 @@ alerter:
access-key-secret: YOUR_ACCESS_KEY_SECRET
signature: YOUR_SMS_SIGNATURE
template-id: YOUR_TEMPLATE_ID
smslocal:
api-key: YOUR_API_KEY_HERE
scheduler:
server:
@@ -185,6 +185,8 @@ alerter:
access-key-secret: YOUR_ACCESS_KEY_SECRET
signature: YOUR_SMS_SIGNATURE
template-id: YOUR_TEMPLATE_ID
smslocal:
api-key: YOUR_API_KEY_HERE
scheduler:
server:
@@ -184,6 +184,8 @@ alerter:
access-key-secret: YOUR_ACCESS_KEY_SECRET
signature: YOUR_SMS_SIGNATURE
template-id: YOUR_TEMPLATE_ID
smslocal:
api-key: YOUR_API_KEY_HERE
scheduler:
server:
+2
View File
@@ -18,6 +18,7 @@
*/
import { AlibabaSmsConfig } from './AlibabaSmsConfig';
import { SmslocalSmsConfig } from './SmslocalSmsConfig';
import { TencentSmsConfig } from './TencentSmsConfig';
import { UniSmsConfig } from './UniSmsConfig';
import { SmsType } from './enums/sms-type.enum';
@@ -28,6 +29,7 @@ export class SmsNoticeSender {
tencent: TencentSmsConfig = new TencentSmsConfig();
alibaba: AlibabaSmsConfig = new AlibabaSmsConfig();
unisms: UniSmsConfig = new UniSmsConfig();
smslocal: SmslocalSmsConfig = new SmslocalSmsConfig();
enable: boolean = false;
creator!: string;
modifier!: string;
+22
View File
@@ -0,0 +1,22 @@
/*
* 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.
*/
export class SmslocalSmsConfig {
apiKey!: string;
}
+2 -1
View File
@@ -20,7 +20,8 @@
export enum SmsType {
TENCENT = 'tencent',
ALIBABA = 'alibaba',
UNISMS = 'unisms'
UNISMS = 'unisms',
SMSLOCAL = 'smslocal'
}
export enum UniSmsAuthMode {
@@ -139,7 +139,7 @@
</div>
</nz-modal>
<!-- sms server modal -->
<!-- sms server model -->
<nz-modal
[(nzVisible)]="isSmsServerModalVisible"
[nzTitle]="'settings.server.sms.setting' | i18n"
@@ -158,9 +158,12 @@
<nz-option [nzValue]="SmsType.TENCENT" nzLabel="{{ 'alert.notice.sender.sms.type.tencent' | i18n }}"></nz-option>
<nz-option [nzValue]="SmsType.ALIBABA" nzLabel="{{ 'alert.notice.sender.sms.type.alibaba' | i18n }}"></nz-option>
<nz-option [nzValue]="SmsType.UNISMS" nzLabel="{{ 'alert.notice.sender.sms.type.unisms' | i18n }}"></nz-option>
<nz-option [nzValue]="SmsType.SMSLOCAL" nzLabel="{{ 'alert.notice.sender.sms.type.smslocal' | i18n }}"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<!-- Tencent SMS -->
<ng-container *ngIf="smsType === SmsType.TENCENT">
<nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="secretId" nzRequired="true">
@@ -201,6 +204,8 @@
</nz-form-control>
</nz-form-item>
</ng-container>
<!-- Alibaba SMS -->
<ng-container *ngIf="smsType === SmsType.ALIBABA">
<nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="accessKeyId" nzRequired="true">
@@ -256,6 +261,8 @@
</nz-form-control>
</nz-form-item>
</ng-container>
<!-- UniSMS -->
<ng-container *ngIf="smsType === SmsType.UNISMS">
<nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="accessKeyId" nzRequired="true">
@@ -317,6 +324,18 @@
</nz-form-control>
</nz-form-item>
</ng-container>
<!-- Smslocal SMS -->
<ng-container *ngIf="smsType === SmsType.SMSLOCAL">
<nz-form-item>
<nz-form-label [nzSpan]="7" nzFor="apiKey" nzRequired="true">
{{ 'alert.notice.sender.sms.smslocal.apiKey' | i18n }}
</nz-form-label>
<nz-form-control [nzSpan]="12" [nzErrorTip]="'validation.required' | i18n">
<input [(ngModel)]="smsNoticeSender.smslocal.apiKey" nz-input required name="apiKey" type="password" id="apiKey" />
</nz-form-control>
</nz-form-item>
</ng-container>
<nz-form-item>
<nz-form-label nzSpan="7" nzFor="smsEnable" nzRequired="true">{{ 'common.enable' | i18n }}</nz-form-label>
<nz-form-control nzSpan="12">
@@ -31,6 +31,7 @@ import { UniSmsConfig } from 'src/app/pojo/UniSmsConfig';
import { SmsType, UniSmsAuthMode } from 'src/app/pojo/enums/sms-type.enum';
import { EmailNoticeSender } from '../../../../pojo/EmailNoticeSender';
import { SmslocalSmsConfig } from '../../../../pojo/SmslocalSmsConfig';
import { GeneralConfigService } from '../../../../service/general-config.service';
@Component({
@@ -142,6 +143,7 @@ export class MessageServerComponent implements OnInit {
this.smsNoticeSender.tencent = { ...new TencentSmsConfig(), ...message.data.tencent };
this.smsNoticeSender.alibaba = { ...new AlibabaSmsConfig(), ...message.data.alibaba };
this.smsNoticeSender.unisms = { ...new UniSmsConfig(), ...message.data.unisms };
this.smsNoticeSender.smslocal = { ...new SmslocalSmsConfig(), ...message.data.smslocal };
this.smsType = message.data.type || 'tencent';
} else {
this.smsNoticeSender = new SmsNoticeSender();
@@ -165,7 +167,8 @@ export class MessageServerComponent implements OnInit {
...this.smsNoticeSender,
tencent: { ...this.smsNoticeSender.tencent },
alibaba: { ...this.smsNoticeSender.alibaba },
unisms: { ...this.smsNoticeSender.unisms }
unisms: { ...this.smsNoticeSender.unisms },
smslocal: { ...this.smsNoticeSender.smslocal }
};
this.isSmsServerModalVisible = true;
}
@@ -176,7 +179,8 @@ export class MessageServerComponent implements OnInit {
...this.tempSmsNoticeSender,
tencent: { ...this.tempSmsNoticeSender.tencent },
alibaba: { ...this.tempSmsNoticeSender.alibaba },
unisms: { ...this.tempSmsNoticeSender.unisms }
unisms: { ...this.tempSmsNoticeSender.unisms },
smslocal: { ...this.tempSmsNoticeSender.smslocal }
};
this.isSmsServerModalVisible = false;
}
+2
View File
@@ -153,10 +153,12 @@
"alert.notice.sender.sms.unisms.signature": "UniSMS Signature",
"alert.notice.sender.sms.unisms.templateId": "UniSMS TemplateId",
"alert.notice.sender.sms.unisms.authMode": "UniSMS Authentication Mode",
"alert.notice.sender.sms.smslocal.apiKey": "Smslocal ApiKey",
"alert.notice.sender.sms.type": "Sms Type",
"alert.notice.sender.sms.type.alibaba": "Alibaba Sms",
"alert.notice.sender.sms.type.tencent": "Tencent Sms",
"alert.notice.sender.sms.type.unisms": "UniSMS",
"alert.notice.sender.sms.type.smslocal": "Smslocal Sms",
"alert.notice.template": "Notice Template",
"alert.notice.template.content": "Template Content",
"alert.notice.template.delete": "Delete Template",
+2
View File
@@ -153,10 +153,12 @@
"alert.notice.sender.sms.unisms.signature": "UniSMS Signature",
"alert.notice.sender.sms.unisms.templateId": "UniSMS TemplateId",
"alert.notice.sender.sms.unisms.authMode": "UniSMS認証モード",
"alert.notice.sender.sms.smslocal.apiKey": "Smslocal ApiKey",
"alert.notice.sender.sms.type": "SMSタイプ",
"alert.notice.sender.sms.type.alibaba": "Alibaba Sms",
"alert.notice.sender.sms.type.tencent": "Tencent Sms",
"alert.notice.sender.sms.type.unisms": "UniSMS",
"alert.notice.sender.sms.type.smslocal": "Smslocal Sms",
"alert.notice.template": "通知テンプレート",
"alert.notice.template.content": "テンプレート内容",
"alert.notice.template.delete": "テンプレートを削除",
+2
View File
@@ -153,10 +153,12 @@
"alert.notice.sender.sms.unisms.signature": "合一短信Signature",
"alert.notice.sender.sms.unisms.templateId": "合一短信TemplateId",
"alert.notice.sender.sms.unisms.authMode": "合一短信鉴权方式",
"alert.notice.sender.sms.smslocal.apiKey": "Smslocal短信鉴权方式",
"alert.notice.sender.sms.type": "短信类型",
"alert.notice.sender.sms.type.alibaba": "阿里短信",
"alert.notice.sender.sms.type.tencent": "腾讯短信",
"alert.notice.sender.sms.type.unisms": "合一短信(UniSMS",
"alert.notice.sender.sms.type.smslocal": "当地短信(Smslocal",
"alert.notice.template": "通知模板",
"alert.notice.template.content": "模板内容",
"alert.notice.template.delete": "删除通知模板",
+2
View File
@@ -153,10 +153,12 @@
"alert.notice.sender.sms.unisms.signature": "合一簡訊Signature",
"alert.notice.sender.sms.unisms.templateId": "合一簡訊TemplateId",
"alert.notice.sender.sms.unisms.authMode": "合一簡訊驗證方式",
"alert.notice.sender.sms.smslocal.authMode": "Smslocal短訊ApiKey",
"alert.notice.sender.sms.type": "騰訊類型",
"alert.notice.sender.sms.type.alibaba": "阿裏短訊",
"alert.notice.sender.sms.type.tencent": "騰訊短訊",
"alert.notice.sender.sms.type.unisms": "合一簡訊(UniSMS",
"alert.notice.sender.sms.type.smslocal": "当地短訊(Smslocal",
"alert.notice.template": "通知模板",
"alert.notice.template.content": "模板内容",
"alert.notice.template.delete": "刪除通知模板",