短信功能使用说明
<h3>一、sms模块介绍</h3>
<p>  Sms模块是为平台提供一个短信发送服务的工具类,该工具类外平台提供发送短信的接口,包含两个方法<code>发送短信</code>和<code>分批发送短信</code>。该接口提供sms模块的统一入口,可以针对不同短信供应商平台来实现该接口。目前,九牧使用的是华为短信平台,该工具类实现华为云短信平台的对接方式,后续如果需要更换短信平台对接,可以重新实现对应平台对接的实现方式,而作为平台整体的引用发送短信的地方,使用方法和代码不需要变动太大,只需要根据新的平台方式更换传来参数的规则就可以了。</p>
<h3>二、sms模块设计</h3>
<p>  sms整个代码模块采用接口设计模式,外部引用接口保持不变,根据实际需要提供不同短信平台的实现,来满足可能带的变化。
  下图是该模块整体的设计结构图
<img src="https://www.showdoc.cc/server/api/common/visitfile/sign/b879b570a06946a05f7af909a62317a6?showdoc=.jpg" alt="sms设计结构" title="sms设计结构" />
  可以看出,每个短信平台的实现类,会对应一个该平台所需的配置和参数内容。</p>
<h3>三、sms使用流程</h3>
<p>  sms使用时序图如下
<img src="https://www.showdoc.cc/server/api/common/visitfile/sign/86b1b79b634d62fe5c58efab2ce113c1?showdoc=.jpg" alt="短信流程" title="短信流程" />
  这里以华为短信平台为例说明,对于各大短信平台的功能基本流程都是这样的,首先要申请发短信的模板,模板可以设计一些可变参数,并申请相应的通道号和签名(用于发短信的通讯号,相当于发短信方的手机号)。因为短信内容有可能会涉及违法的内容,一般模板内容都是受平台管控的,所以各个平台都会审核,只有审核过的模板,才可使用。
一般流程:申请签名->申请模板->调用短信API,并配置相应回调->短信平台返回结果->短信发送完成异步回调</p>
<h3>四、sms代码说明</h3>
<p>  接口代码</p>
<pre><code>public interface SmsSendService<T> {
/**
* 发送单个短信
* @param params 发送短信的参数
* 根据各平台参数内容,继承BaseSmsParams
* @return T
* @throws SmsException 短信异常
*/
T sendSms(BaseSmsParams params) throws SmsException;
/**
* 分批发送
* @param params 参数
* @return T
* @throws SmsException 短信异常
*/
T sendDifSms(BaseSmsParams params) throws SmsException;
}
</code></pre>
<p>  参数代码说明</p>
<pre><code>public class SmsParamsHuaWei extends BaseSmsParams {
/**
* 短信模板id(华为云申请的短信模板尖)
*
* ex:"8ff55eac1d0b478ab3c06c3c6a492300"
*/
private String templateId;
/**
* 通讯号 (与模板类型和签名有关,请到华为云短信控制台查询)
*/
private String sender;
/**
* 短信信的签名(短信的抬头如:【九牧集团】 xxx...)
* ex: "九牧集团"
*/
private String signature;
/**
* 接收人电话(可以接收多个电话号码)
* 单条短信最多允许携带1000个号码
* ex:"180xxx...","180xxx...,181xxx..."
*/
private String receiver;
/**
* 回调地址,该消息的状态报告将通过“接收状态报告”接口直接通知客户。
* 可选
*/
private String statusCallBack;
/**
* 扩展参数,在状态报告中会原样返回
* 可选
*/
private String extend;
/**
* 模板中的参数值
* 模板中没{txt_20}之类的参数,可以为空
*/
private List<String> templateParas;
/**
* 分批发送短信的参数
*/
private List<SmsParamHwDiff> diffs;
}</code></pre>
<p><code>注:</code>:短信一般都是异常推送,推送的时间根据短信类型或者平台规则来决定的,几乎所有的平台都会有可选参数,回调地址,用户如果在用户发送api时设置的回调地址,平台将短信发送到目标手机后,会回调这个地址,用户可以根据这个回调地址做出相应的业务处理,回调地址会有一个附带的回调参数。</p>
<h3>五、短信类型、签名说明</h3>
<p>  一般短信平台,都将短信类型分成三类(应该是通信运营商规定的):</p>
<ul>
<li>验证码类
手机验证码,用户安全验证,手机用户收到短信的比较及时。</li>
<li>通知类
通知某类消息,主要用于服务通知,订单通知,交易等,手机用户收到短信的比较及时。</li>
<li>推广类
推广产品,活动等,类似于广告,这类短信会卡的比较严格,手机用户收到短信的时间根据实际情况决定,延迟会比较久。</li>
</ul>
<p>  每个签名对应一个短信类型对应一个通道号。
华为云短信平台参考链接:<a href="https://support.huaweicloud.com/api-msgsms/sms_05_0001.html" title="华为云短信平台api">华为云短信平台api</a></p>
<h3>六、使用说明</h3>
<h3>1、短信发送工具包(nisbos-sms)使用</h3>
<h4>1.1、功能点</h4>
<p>封装短信调用接口,功能如下:
云平台短信单条(批量)发送;
通过配置参数(isInBatch)可进行自动分批发送短信(超过1000条);
非正常号码格式的手机号筛选出来返回数据;</p>
<h4>1.2、如何使用</h4>
<h5>1.2.1、依赖包引用</h5>
<pre><code class="language-java"><!-- nisbos平台组提供的 短信发送接口封装工具类 -->
<dependency>
<groupId>com.nisbos</groupId>
<artifactId>nisbos-sms</artifactId>
<version>2.0-RELEASE</version>
</dependency></code></pre>
<p>目前依赖包放在华为云远程仓库上,过之前没有使用过需要引入相应的远程仓库配置:
在pom中增加以下配置:</p>
<pre><code class="language-java"><repositories>
<repository>
<id>releases</id>
<url>https://devrepo-cn-south-1.devcloud.huaweicloud.com/01/nexus/content/repositories/f7cbdf16691e4fae9e7f309a8ab2963a_1_0/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>releases</id>
<url>https://devrepo-cn-south-1.devcloud.huaweicloud.com/01/nexus/content/repositories/f7cbdf16691e4fae9e7f309a8ab2963a_1_0/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories></code></pre>
<p>maven的setting配置相应的账号信息:</p>
<pre><code class="language-java"><server>
<id>releases</id>
<username>f7cbdf16691e4fae9e7f309a8ab2963a_0a010e88ca00f3831fbdc00fed63c5a4</username>
<password>U-y4[4hUR^</password>
</server></code></pre>
<ul>
<li>注:如果想配置全局的可在maven的setting文件中配置,参考配置:<a href="https://jm-retail.obs.cn-south-1.myhuaweicloud.com/settings.xml">https://jm-retail.obs.cn-south-1.myhuaweicloud.com/settings.xml</a></li>
</ul>
<h5>1.2.2、代码处理</h5>
<h6>1.2.2.1、非spring项目</h6>
<p>a、创建工具类</p>
<pre><code class="language-java">public class SmsHuaweiSendUtil {
static String apiUrl = "https://rtcsms.cn-north-1.myhuaweicloud.com:10743";
static String appKey = "wK6j05GMPWRS6mEva3d7cjnD3Z1t";
static String appSecret = "***********";// 该密钥涉及到私密信息,请跟项目相关负责人获取平台人员确认配置信息
// 使用提供的工厂类
private static SmsSendService<SmsResultHw> smsSendService = FactoryProducer.getSmsHuaweiSendService(apiUrl, appKey, appSecret, null, null);
public static SmsSendService service() {
return smsSendService;
}
private SmsHuaweiSendUtil() {
}
}</code></pre>
<p>b、调用使用(单个模板)</p>
<pre><code class="language-java"> SmsSendService smsSendService = SmsHuaweiSendUtil.service();
String str = "14759206561";
SmsParamsHuaWei paramsHuaWei = new SmsParamsHuaWei();
paramsHuaWei.setTemplateId("18c9d50993f84773b35a776cf5fddf93");// 模板id
paramsHuaWei.setReceiver(str);// 发送的目标手机号,多个“,”隔开
paramsHuaWei.setSender("8819101720165");
// paramsHuaWei.setIsInBatch("1");//默认0不分批次,若超过1000个调用华为短信则全部号码都会发送失败,1为超过1000分批次
List<String> tempParams = new ArrayList<>();
tempParams.add("普通会员");//对应模板中定义的变量参数,个数需要匹配上
paramsHuaWei.setTemplateParas(tempParams);
// paramsHuaWei.setExtend("8801139352182");// 扩展字段
SmsResultHw result = (SmsResultHw) smsSendService.sendSms(paramsHuaWei);</code></pre>
<h6>1.2.2.1、spring项目</h6>
<p>注:spring项目如果之前没有用过nisbos平台的依赖包需要定义对应的包扫描范围才能让Spring找到对应的bean,详细信息见2.1</p>
<p>a、yml配置</p>
<pre><code class="language-java">sms:
config:
apiUrl: https://rtcsms.cn-north-1.myhuaweicloud.com:10743
appKey: wK6j05GMPWRS6mEva3d7cjnD3Z1t
# 该密钥涉及到私密信息,请跟项目相关负责人获取平台人员确认配置信息
appSecret: ***********
# 全局的模板id,可在调用处自定义(可选)-需在华为云上申请短信模板
templateId: 3bbd0815982a4767a9f1db4ac43ca33d
# 发送方(可选),可在调用处自定义-对应华为云上的签名管理中对应签名的通道号
sender: 8819101720221
# 短信平台类型
type: huawei</code></pre>
<p>b、调用</p>
<pre><code class="language-java">@Autowired
SmsSendService smsSendService;
@GetMapping(value = "test11")
public AjaxResult test() {
String str = "14759206561";
SmsParamsHuaWei paramsHuaWei = new SmsParamsHuaWei();
paramsHuaWei.setTemplateId("18c9d50993f84773b35a776cf5fddf93");// 模板id
paramsHuaWei.setReceiver(str); // 发送的目标手机号,多个“,”隔开
paramsHuaWei.setSender("8819101720165");
// paramsHuaWei.setIsInBatch("1");//默认0不分批次,若超过1000个调用华为短信则全部号码都会发送失败,1为超过1000分批次
List<String> tempParams = new ArrayList<>();
tempParams.add("普通会员");//对应模板中定义的变量参数,个数需要匹配上
paramsHuaWei.setTemplateParas(tempParams);
paramsHuaWei.setExtend("8801139352182");
SmsResultHw result = (SmsResultHw) smsSendService.sendSms(paramsHuaWei);
return AjaxResult.success(result);
}</code></pre>
<p>多个短信模板批量发送:</p>
<pre><code class="language-java"> List<SmsParamHwDiff> list = new ArrayList<>();
SmsParamHwDiff paramsHuaWei = new SmsParamHwDiff();
paramsHuaWei.setTemplateId("97637ad9a2de443f8dc63d7d890d802b");
paramsHuaWei.setTo(new String[]{"123", "124"});
// paramsHuaWei.setTo(new String[]{"123"});
paramsHuaWei.setSignature("九牧厨卫");
String[] tempParams = {"hybirs-", "job", "用户中心-", "用户中心-"};
paramsHuaWei.setTemplateParas(tempParams);
list.add(paramsHuaWei);
////////////
SmsParamHwDiff paramsHuaWei2 = new SmsParamHwDiff();
paramsHuaWei2.setTemplateId("97637ad9a2de443f8dc63d7d890d802b");
paramsHuaWei2.setTo(new String[]{"12354465"});
paramsHuaWei2.setSignature("九牧厨卫");
String[] tempParams2 = {"hybirs-", "job", "用户中心-", "用户中心-"};
paramsHuaWei2.setTemplateParas(tempParams2);
list.add(paramsHuaWei2);
SmsParamsHuaWei hw = new SmsParamsHuaWei();
hw.setSender("8819101720198");
hw.setDiffs(list);
SmsResultHw result = (SmsResultHw) smsSendService.sendDifSms(hw);</code></pre>
<h3>2、Q&A</h3>
<h4>2.1、spring相关项目启动时报错加载不了SmsSendService</h4>
<p><img src="http://10.1.4.71:4999/server/index.php?s=/api/attachment/visitFile/sign/4855612ef8c6d8e7fc51d697e0720c00&showdoc=.jpg" alt="" /></p>
<blockquote>
<p>项目增加对应的扫描包范围</p>
</blockquote>
<p>1、spring项目:
在xlm中配置spring的扫描器:<context:component-scan base-package="com.nisbos" />
2、springboot项目:
启动类上增加注解:a、@SpringBootApplication(scanBasePackages = {"com.nisbos"})
b、@ComponentScan(basePackages = "com.nisbos")</p>
<h4>2.2、调用发送短信接口之后报错status为E200028</h4>
<p><img src="http://10.1.4.71:4999/server/index.php?s=/api/attachment/visitFile/sign/852531d05a42e143350aa9a71f46c92c&showdoc=.jpg" alt="" /></p>
<blockquote>
<p>status为E200028的报错信息表示你塞入的参数与你的模板匹配不上,请检查paramsHuaWei.setTemplateParas(tempParams);中的tempParams个数是否与模板的参数变量个数匹配。
其他类型的报错可参考文档:<a href="https://support.huaweicloud.com/devg-msgsms/sms_04_0009.html">https://support.huaweicloud.com/devg-msgsms/sms_04_0009.html</a></p>
</blockquote>