Commit a1860434 authored by lifei's avatar lifei

训练营短信群发助手功能finish

parent aa98c6e0
......@@ -71,4 +71,8 @@ public interface GroupMemberDao extends CustomizedMapper<GroupMember> {
@Select("select passport from group_member where group_id = #{group_id} and status = 1 and role in (1,2)")
List<String> listGroupManager(@Param("group_id")Long groupId);
@Select("select u.mobile from group_member g LEFT JOIN user u ON g.passport = u.id where g.group_id in (${groupIdLst}) "
+ "group by g.passport limit #{offset}, #{size}")
List<String> queryGroupMemberMobiles(@Param("groupIdLst") String groupIdLst, @Param("offset") int offset, @Param("size") int size);
}
......@@ -546,4 +546,7 @@ public class GroupMemberDs {
return groupMemberDao.listGroupManager(groupId);
}
public List<String> queryGroupMemberMobiles(String groupIdLst, int offset, int size) {
return groupMemberDao.queryGroupMemberMobiles(groupIdLst, offset, size);
}
}
package mobi.mixiong.camp.jobs;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import mobi.mixiong.camp.AliyunSdkAcsClientUtils;
import mobi.mixiong.camp.ds.group.GroupDs;
import mobi.mixiong.camp.ds.group.GroupMemberDs;
import mobi.mixiong.camp.ds.group.GroupMsgDs;
import mobi.mixiong.camp.ds.msg.param.im.IMMsgBody;
import mobi.mixiong.camp.ds.msg.param.im.ImMsgParam;
......@@ -17,6 +26,7 @@ import mobi.mixiong.camp.entity.group.GroupMsgDetail;
import mobi.mixiong.camp.enums.*;
import mobi.mixiong.camp.im.ImUserAction;
import org.apache.commons.lang3.RandomUtils;
import org.apache.logging.log4j.util.Strings;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
......@@ -31,12 +41,15 @@ import java.util.stream.Collectors;
@Slf4j
public class GroupMsgJob implements Job {
@Autowired
private GroupMsgDs groupMsgDs;
@Autowired
private GroupDs groupDs;
@Autowired
private GroupMemberDs groupMemberDs;
@Autowired
private MsgSendASyncService msgSendASyncService ;
......@@ -47,7 +60,7 @@ public class GroupMsgJob implements Job {
log.info("start exec group ms job ,id : {}", id);
GroupMsg msg = groupMsgDs.getMsg(id);
//如果删除或被暂停,不执行
// 如果删除或被暂停,不执行
if (!msg.isCommon()) {
return;
}
......@@ -59,7 +72,7 @@ public class GroupMsgJob implements Job {
{
}
// 找需要发送得到group ID list
List<Long> groups = JSONArray.parseArray(msg.getGroups(), Long.class);
List<String> imGroups = groups.stream().map(groupId -> groupDs.get(groupId).getImGroupId()).collect(Collectors.toList());
List<GroupMsgDetail> details = groupMsgDs.listDetails(msg.getId());
......@@ -71,11 +84,14 @@ public class GroupMsgJob implements Job {
try {
for (int i = 0; i < total; i++) {
GroupMsgDetail detail = details.get(i);
sendGroupMsg(msg.getCreator(), detail, imGroups);
// 发送IM信息
sendGroupMsg(msg.getCreator(), detail, imGroups, groups);
// 发送SMS阿里云短信
sendGroupSMS(msg.getCreator(), detail, groups);
successAmount++;
groupMsgDs.incrSuccessCount(historyId);
// 睡眠,来保证顺序性
TimeUnit.MILLISECONDS.sleep( RandomUtils.nextInt(5000,10000));
TimeUnit.MILLISECONDS.sleep(RandomUtils.nextInt(5000,10000));
}
} catch (Exception e) {
log.error("群发消息失败", e);
......@@ -90,10 +106,18 @@ public class GroupMsgJob implements Job {
}
}
private void sendGroupMsg(String passport, GroupMsgDetail detail, List<String> imGroups) {
/**
*
* @param passport 发送人id
* @param detail 短信明细内容
* @param imGroups imGroups
* @param groups groups
*/
private void sendGroupMsg(String passport, GroupMsgDetail detail, List<String> imGroups, List<Long> groups) {
GroupMsgDetailType detailType = GroupMsgDetailType.getByValue(detail.getType());
ImMsgParam param = null;
switch (detailType) {
// 图片消息
case IMAGE: {
PicInfo picInfo = JSONObject.parseObject(detail.getContent(), PicInfo.class);
param= ImMsgParam.builder().target(imGroups).source(passport)
......@@ -101,6 +125,7 @@ public class GroupMsgJob implements Job {
.otherParam(ImOtherParam.builder().role(GroupMemberRole.MANAGER.role()).build()).build();
break;
}
// 文字消息
case TEXT: {
TextInfo info = JSONObject.parseObject(detail.getContent(),TextInfo.class);
param = ImMsgParam.builder().target(imGroups).source(passport)
......@@ -108,14 +133,70 @@ public class GroupMsgJob implements Job {
.otherParam(ImOtherParam.builder().role(GroupMemberRole.MANAGER.role()).build()).build();
break;
}
case SMS: {
}
default:
break;
}
if (param != null) {
msgSendASyncService.sendIMGroupMsg(param);
}
}
/**
* 发送阿里云短信服务
* @param creator String
* @param detail GroupMsgDetail
* @param groups List<Long>
*/
private void sendGroupSMS(String creator, GroupMsgDetail detail, List<Long> groups) {
if (groups == null || groups.isEmpty())
return;
GroupMsgDetailType detailType = GroupMsgDetailType.getByValue(detail.getType());
if (detailType != GroupMsgDetailType.SMS)
return;
IAcsClient defaultAcsClient = AliyunSdkAcsClientUtils.getDefaultAcsClient();
// 阿里云批量短信一次最多发100个,故pageSize 设置为100
int page = 1, pageSize = 100;
String groupIdLst = Strings.join(groups, ',');
while (true) {
int offset = (page - 1) * pageSize;
List<String> toMobiles = groupMemberDs.queryGroupMemberMobiles(groupIdLst, offset, pageSize);
sendSMS(toMobiles, detail, defaultAcsClient);
if (toMobiles.size() < pageSize)
break;
page++;
}
}
private void sendSMS(List<String> toMobiles, GroupMsgDetail detail, IAcsClient defaultAcsClient) {
JSONObject jsonObject = JSON.parseObject(detail.getContent());
String templateCode = jsonObject.getString("TemplateCode");
String templateParam = jsonObject.getString("TemplateParamJson");
// Start! SignNameJson, PhoneNumberJson, TemplateParamJson三者数量要一致,并且一一对应: 阿里云文档这么写的
List<String> SignNameJson = Lists.newArrayList();
toMobiles.forEach(c -> SignNameJson.add("米焙"));
List<String> templateParamArray = Lists.newArrayList();
toMobiles.forEach(c -> templateParamArray.add(templateParam));
// End!
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain("dysmsapi.aliyuncs.com");
request.setSysVersion("2017-05-25");
request.setSysAction("SendBatchSms");
request.putQueryParameter("RegionId", "cn-hangzhou");
request.putQueryParameter("TemplateCode", templateCode);
request.putQueryParameter("SignNameJson", JSON.toJSONString(SignNameJson));
request.putQueryParameter("PhoneNumberJson", JSON.toJSONString(toMobiles));
request.putQueryParameter("TemplateParamJson", JSON.toJSONString(templateParamArray));
log.info("putQueryParameter SignNameJson :" + JSON.toJSONString(SignNameJson));
log.info("putQueryParameter PhoneNumberJson :" + JSON.toJSONString(toMobiles));
log.info("putQueryParameter TemplateParamJson :" + JSON.toJSONString(templateParamArray));
try {
CommonResponse commonResponse = defaultAcsClient.getCommonResponse(request);
log.info("AliyunSMS-Result:" + commonResponse.getData());
} catch (ClientException e) {
log.error("sendsms error: ", e);
}
}
}
......@@ -17,6 +17,7 @@ import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import mobi.mixiong.camp.AliyunSdkAcsClientUtils;
import mobi.mixiong.camp.PageBean;
import mobi.mixiong.camp.cache.sms.SmsTemplateCache;
import mobi.mixiong.camp.constant.OnsEventType;
......@@ -51,10 +52,7 @@ import java.util.stream.Collectors;
@Slf4j
public class GroupMsgServiceImpl implements GroupMsgService {
// 当前类使用的阿里云Sdk短信调用参数,目前只有"cn-hangzhou"这个region可用, 不要使用填写其他region的值
public static final String REGION_CN_HANGZHOU = "cn-hangzhou";
private String accessKeyId = "LTAI4Fzc8WyCFUMomrDYC6zo";
private String accessKeySecret = "ORgAqrZ64EtOfYUuFigFqAVZfFl1uv";
@Autowired
private GroupMsgDs groupMsgDs;
......@@ -297,8 +295,7 @@ public class GroupMsgServiceImpl implements GroupMsgService {
String templateCodes = smsTemplateCache.getTemplateCodes();
String[] split = templateCodes.split(",");
// 参照阿里云sdk demo例子
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
IAcsClient client = new DefaultAcsClient(profile);
IAcsClient client = AliyunSdkAcsClientUtils.getDefaultAcsClient();
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain("dysmsapi.aliyuncs.com");
......
......@@ -235,7 +235,6 @@ public class GroupServiceImpl implements GroupService {
List<Group> groups = groupDs.listMyManageGroups(passport, offset, size, type);
return groups.stream().map(GroupSimpleVo::from).collect(Collectors.toList());
}
@Override
......
package mobi.mixiong.camp.service.group.vo;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class AliYunSMSTemplateVo {
private String templateCode;
private String templateContent;
private String templateName;
private String templateStatus;
private Integer templateType;
}
......@@ -47,7 +47,13 @@
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- <dependency>-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.3.2</version>
<scope>compile</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.bouncycastle</groupId>-->
<!-- <artifactId>bcpkix-jdk15on</artifactId>-->
<!-- <version>1.54</version>-->
......
package mobi.mixiong.camp;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.profile.DefaultProfile;
public class AliyunSdkAcsClientUtils {
public static final String accessKeyId = "LTAI4Fzc8WyCFUMomrDYC6zo";
private static final String accessKeySecret = "ORgAqrZ64EtOfYUuFigFqAVZfFl1uv";
// 当前类使用的阿里云Sdk短信调用参数,目前只有"cn-hangzhou"这个region可用, 不要使用填写其他region的值
public static final String REGION_CN_HANGZHOU = "cn-hangzhou";
public static IAcsClient getDefaultAcsClient() {
DefaultProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
IAcsClient client = new DefaultAcsClient(profile);
return client;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment