Przeglądaj źródła

添加发送消息的接口

tuonina 5 lat temu
rodzic
commit
04715fdb50

+ 17 - 0
tuon-core/src/main/java/cn/tonyandmoney/tuon/core/utils/RestUtils.java

@@ -1,5 +1,6 @@
 package cn.tonyandmoney.tuon.core.utils;
 
+import org.springframework.http.HttpEntity;
 import org.springframework.http.client.SimpleClientHttpRequestFactory;
 import org.springframework.web.client.RestTemplate;
 
@@ -8,6 +9,22 @@ import java.util.Map;
 public class RestUtils {
 
 
+    /**
+     * post请求
+     *
+     * @param host 主机地址
+     * @param url  路径
+     * @param body 消息内容
+     * @param clz  返回数据类型
+     * @param <T>  返回数据类型
+     * @return 响应
+     */
+    public static <T> T post(String host, String url, HttpEntity body, Map<String, String> params, Class<T> clz) {
+        RestTemplate restTemplate = new RestTemplate(createFactory());
+        return restTemplate.postForObject(String.format("%s%s", host, url), body, clz, params);
+    }
+
+
     public static <T> T get(String url, Map<String, String> params, Class<T> clz) {
         RestTemplate restTemplate = new RestTemplate(createFactory());
         return restTemplate.getForObject(url, clz, params);

+ 32 - 0
tuon-qywx/src/main/java/cn/tonyandmoney/tuon/qywx/QywxProperties.java

@@ -17,10 +17,42 @@ public class QywxProperties {
     private String accessTokenPath="/cgi-bin/gettoken?corpid={corpid}&corpsecret={corpsecret}";
     private String userInfoPath="/cgi-bin/user/getuserinfo?access_token={access_token}&code={code}";
     private String userGetPath="/cgi-bin/user/get?access_token={access_token}&userid={userid}";
+    private String sendMsgPath="/cgi-bin/message/send?access_token={access_token}";
     //消息接收的Token-EncodingAESKey
     private String token="xwKMrU6J";
     private String encodingAESKey="uiSDpQAl9yJHtv5iOS9Nr25oKyrIeRcD30DQHECR3zV";
 
+    private String agentId="1000002";
+
+    /**
+     * 每当用户登录的时候,给用户发送消息
+     */
+    private String welcome="您已登陆应用!";
+
+
+    public void setAgentId(String agentId) {
+        this.agentId = agentId;
+    }
+
+    public String getAgentId() {
+        return agentId;
+    }
+
+    public void setWelcome(String welcome) {
+        this.welcome = welcome;
+    }
+
+    public String getWelcome() {
+        return welcome;
+    }
+
+    public void setSendMsgPath(String sendMsgPath) {
+        this.sendMsgPath = sendMsgPath;
+    }
+
+    public String getSendMsgPath() {
+        return sendMsgPath;
+    }
 
     public void setEncodingAESKey(String encodingAESKey) {
         this.encodingAESKey = encodingAESKey;

+ 106 - 0
tuon-qywx/src/main/java/cn/tonyandmoney/tuon/qywx/bean/WxMsgTo.java

@@ -0,0 +1,106 @@
+package cn.tonyandmoney.tuon.qywx.bean;
+
+/**
+ * 应用通过企业微信接口向用户主动推送的消息实体类
+ */
+public class WxMsgTo {
+    /**
+     * 成员ID列表(消息接收者,多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为@all,则向该企业应用的全部成员发送
+     */
+    private String touser;
+    /**
+     * 部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
+     */
+    private String toparty;
+    private String totag;
+    /**
+     * 消息类型,此时固定为:text
+     */
+    private String msgtype = "text";
+    /**
+     * 企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值
+     */
+    private String agentid;
+    private Text text;
+    private int safe = 0;  //表示是否是保密消息,0表示否,1表示是,默认0
+    private int enable_id_trans;//表示是否开启id转译,0表示否,1表示是,默认0
+
+
+    public String getTouser() {
+        return touser;
+    }
+
+    public void setTouser(String touser) {
+        this.touser = touser;
+    }
+
+    public String getToparty() {
+        return toparty;
+    }
+
+    public void setToparty(String toparty) {
+        this.toparty = toparty;
+    }
+
+    public String getTotag() {
+        return totag;
+    }
+
+    public void setTotag(String totag) {
+        this.totag = totag;
+    }
+
+    public String getMsgtype() {
+        return msgtype;
+    }
+
+    public void setMsgtype(String msgtype) {
+        this.msgtype = msgtype;
+    }
+
+    public String getAgentid() {
+        return agentid;
+    }
+
+    public void setAgentid(String agentid) {
+        this.agentid = agentid;
+    }
+
+    public void setText(Text text) {
+        this.text = text;
+    }
+
+    public Text getText() {
+        return text;
+    }
+
+    public int getSafe() {
+        return safe;
+    }
+
+    public void setSafe(int safe) {
+        this.safe = safe;
+    }
+
+    public int getEnable_id_trans() {
+        return enable_id_trans;
+    }
+
+    public void setEnable_id_trans(int enable_id_trans) {
+        this.enable_id_trans = enable_id_trans;
+    }
+
+
+    public static class Text{
+        private String content;
+
+        public void setContent(String content) {
+            this.content = content;
+        }
+
+        public String getContent() {
+            return content;
+        }
+    }
+
+}

+ 35 - 0
tuon-qywx/src/main/java/cn/tonyandmoney/tuon/qywx/bean/WxMsgToResp.java

@@ -0,0 +1,35 @@
+package cn.tonyandmoney.tuon.qywx.bean;
+
+/**
+ * 发送消息的返回数据类型
+ */
+public class WxMsgToResp extends WxBaseResult {
+
+    private String invaliduser;
+    private String invalidparty;
+    private String invalidtag;
+
+    public String getInvaliduser() {
+        return invaliduser;
+    }
+
+    public void setInvaliduser(String invaliduser) {
+        this.invaliduser = invaliduser;
+    }
+
+    public String getInvalidparty() {
+        return invalidparty;
+    }
+
+    public void setInvalidparty(String invalidparty) {
+        this.invalidparty = invalidparty;
+    }
+
+    public String getInvalidtag() {
+        return invalidtag;
+    }
+
+    public void setInvalidtag(String invalidtag) {
+        this.invalidtag = invalidtag;
+    }
+}

+ 12 - 1
tuon-qywx/src/main/kotlin/cn/tonyandmoney/tuon/qywx/controller/QywxController.kt

@@ -11,8 +11,10 @@ import cn.tonyandmoney.tuon.qywx.QywxProperties
 import cn.tonyandmoney.tuon.qywx.WxErrorCode
 import cn.tonyandmoney.tuon.qywx.aes.WXBizMsgCrypt
 import cn.tonyandmoney.tuon.qywx.bean.WxMsg
+import cn.tonyandmoney.tuon.qywx.bean.WxMsgTo
 import cn.tonyandmoney.tuon.qywx.bean.WxUser
 import cn.tonyandmoney.tuon.qywx.service.IDutyService
+import cn.tonyandmoney.tuon.qywx.service.IQywxMsgService
 import cn.tonyandmoney.tuon.qywx.service.IQywxService
 import com.fasterxml.jackson.databind.ObjectMapper
 import org.slf4j.LoggerFactory
@@ -53,6 +55,8 @@ class QywxController {
     @Autowired
     @Qualifier("xmlObjectMapper")
     private lateinit var objectMapper: ObjectMapper
+    @Autowired
+    private lateinit var msgService: IQywxMsgService
 
     /**
      * @param code 凭据
@@ -74,7 +78,14 @@ class QywxController {
                                 .flatMap { info -> SessionUtils.setUser(exchange, info) }
                     }
                 }
-                .flatMap { info -> Mono.just(BaseResp.ok(info)) }
+                .flatMap { info ->
+                    val msg = WxMsgTo().apply {
+                        touser = info.userId
+                        text = WxMsgTo.Text().apply {  properties.welcome }
+                    }
+                    msgService.sendMsgTo(msg)
+                    Mono.just(BaseResp.ok(info))
+                }
                 .onErrorResume {
                     if (it is OpException) {
                         Mono.just(it.toResp())

+ 24 - 0
tuon-qywx/src/main/kotlin/cn/tonyandmoney/tuon/qywx/controller/WxMsgController.kt

@@ -0,0 +1,24 @@
+package cn.tonyandmoney.tuon.qywx.controller
+
+import cn.tonyandmoney.tuon.qywx.bean.WxMsgTo
+import cn.tonyandmoney.tuon.qywx.bean.WxMsgToResp
+import cn.tonyandmoney.tuon.qywx.service.IQywxMsgService
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+import reactor.core.publisher.Mono
+
+@RestController
+@RequestMapping("/wx/msg")
+class WxMsgController {
+
+    @Autowired
+    private lateinit var msgService: IQywxMsgService
+
+    @PostMapping
+    fun sendMsgTo(@RequestBody msg: WxMsgTo): Mono<WxMsgToResp> {
+        return msgService.sendMsg(msg)
+    }
+}

+ 23 - 0
tuon-qywx/src/main/kotlin/cn/tonyandmoney/tuon/qywx/service/IQywxMsgService.kt

@@ -0,0 +1,23 @@
+package cn.tonyandmoney.tuon.qywx.service
+
+import cn.tonyandmoney.tuon.qywx.bean.WxMsgTo
+import cn.tonyandmoney.tuon.qywx.bean.WxMsgToResp
+import org.springframework.scheduling.annotation.Async
+import reactor.core.publisher.Mono
+
+/**
+ * 企业微信消息相关的接口服务于
+ */
+interface IQywxMsgService {
+
+    /**
+     * 异步发送消息
+     */
+    @Async
+    fun sendMsgTo(msgTo: WxMsgTo)
+
+    /**
+     * 形式不一样,跟上面的一样的
+     */
+    fun sendMsg(msgTo: WxMsgTo):Mono<WxMsgToResp>
+}

+ 57 - 0
tuon-qywx/src/main/kotlin/cn/tonyandmoney/tuon/qywx/service/impl/QywxMsgServiceImpl.kt

@@ -0,0 +1,57 @@
+package cn.tonyandmoney.tuon.qywx.service.impl
+
+import cn.tonyandmoney.tuon.core.utils.RestUtils
+import cn.tonyandmoney.tuon.qywx.QywxProperties
+import cn.tonyandmoney.tuon.qywx.bean.WxMsgTo
+import cn.tonyandmoney.tuon.qywx.bean.WxMsgToResp
+import cn.tonyandmoney.tuon.qywx.service.IQywxMsgService
+import cn.tonyandmoney.tuon.qywx.service.IQywxService
+import com.fasterxml.jackson.databind.ObjectMapper
+import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.http.HttpEntity
+import org.springframework.http.HttpHeaders
+import org.springframework.http.MediaType
+import org.springframework.stereotype.Service
+import reactor.core.publisher.Mono
+
+/**
+ * 企业微信发送消息的接口
+ */
+@Service
+class QywxMsgServiceImpl : IQywxMsgService {
+
+    companion object {
+        val logger = LoggerFactory.getLogger(QywxMsgServiceImpl::class.java.simpleName)
+    }
+
+    @Autowired
+    private lateinit var properties: QywxProperties
+    @Autowired
+    private lateinit var qywxService: IQywxService
+    @Autowired
+    private lateinit var objectMapper: ObjectMapper
+
+    /**
+     * 异步发送消息到用户
+     */
+    override fun sendMsgTo(msgTo: WxMsgTo) {
+        sendMsg(msgTo).subscribe { logger.info("sendMsgTo :{}", it) }
+    }
+
+    override fun sendMsg(msgTo: WxMsgTo): Mono<WxMsgToResp> {
+        return qywxService.getAccessToken(properties.agentId)
+                .flatMap { token ->
+                    Mono.create<WxMsgToResp> {
+                        msgTo.apply {
+                            agentid = properties.agentId
+                        }
+                        val headers = HttpHeaders()
+                        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+                        val body = HttpEntity<String>(objectMapper.writeValueAsString(msgTo), headers)
+                        val resp = RestUtils.post(properties.host, properties.sendMsgPath, body, mapOf("access_token" to token), WxMsgToResp::class.java)
+                        it.success(resp)
+                    }
+                }
+    }
+}

+ 2 - 0
tuon-web/src/main/kotlin/cn/tonyandmoney/tuon/web/MainApplication.kt

@@ -7,11 +7,13 @@ import org.springframework.boot.builder.SpringApplicationBuilder
 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient
 import org.springframework.cloud.netflix.eureka.EnableEurekaClient
+import org.springframework.scheduling.annotation.EnableAsync
 import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession
 
 /**
  * 所以这个
  */
+@EnableAsync
 @EnableEurekaClient
 @EnableDiscoveryClient
 @EnableRedisWebSession