当前位置:网站首页>Public and private account sending prompt information (user microservice -- message microservice)
Public and private account sending prompt information (user microservice -- message microservice)
2022-07-03 12:33:00 【Gentle just because of you】
Public and private signs send prompt messages ( User microservices – Message microservices )
Integration of wechat messages ( WeChat official account )
scene : Mainly used for shopping tips , Amount reminder , Campaign ads, etc
Apply for wechat test number ( It is different from wechat applet )
https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
Get the information
View specific documents
obtain access_token( Here is the difference between others token)
The essence is to send a request
Send message template document
The message template
Get the template ID
Summarize what you need
appID,appsecret, Templates ID
technological process :
1. according to appid and appsecret Get access_token 2. Send a request ( The request contains template content ,access_token)
User microservices
pom.xml( Message microservices are needed api---- because AliSmsModel Class in message api in )
<dependency> <groupId>com.xiaoge</groupId> <artifactId>message-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
Start class
@SpringBootApplication @EnableEurekaClient public class MemberServiceApplication { public static void main(String[] args) { SpringApplication.run(MemberServiceApplication.class, args); } }
UserController
package com.xiaoge.controller; import com.alibaba.fastjson.JSON; import com.xiaoge.constant.QueueConstant; import com.xiaoge.domain.User; import com.xiaoge.domain.UserCollection; import com.xiaoge.model.WxMsgModel; import com.xiaoge.service.UserCollectionService; import com.xiaoge.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; /** * @Classname UserController * @Date 2022/6/6 Afternoon 8:23 * @Created by xiaoge * @Description TODO */ @Api(tags = " Foreground user management interface ") @RestController @RequestMapping public class UserController { @Autowired private UserService userService; @Autowired private RabbitTemplate rabbitTemplate; @PostMapping("p/sms/wxSend") @ApiOperation(" Test sending wechat official account messages ") public ResponseEntity<String> wxSend(String openId, String name) { // Building an object WxMsgModel wxMsgModel = new WxMsgModel(); wxMsgModel.setToUser(openId); // When users click on the information, they go to the address wxMsgModel.setUrl("https://www.baidu.com"); // Template id wxMsgModel.setTemplateId("XIL5vtqbdBZbejJ2xfXv-cqXxLni9RzjG32Qjpg_OoY"); // Head color wxMsgModel.setTopColor("#FF0000"); HashMap<String, Map<String, String>> data = new HashMap<>(); data.put("userName", WxMsgModel.buildMap(name, "#FF0000")); data.put("time", WxMsgModel.buildMap(LocalDateTime.now().toString(), "#FF0000")); data.put("product", WxMsgModel.buildMap(" Girl friend ", "#FF0000")); data.put("money", WxMsgModel.buildMap("0.1", "#FF0000")); wxMsgModel.setData(data); // use mq Send a message rabbitTemplate.convertAndSend(QueueConstant.WX_CHANGE_EX, QueueConstant.WX_CHANGE_KEY, JSON.toJSONString(wxMsgModel)); return ResponseEntity.ok(" Send successfully "); } }
Message microservices
message-api Model class in User microservices use this model class
package com.xiaoge.model; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.HashMap; import java.util.Map; @Data @AllArgsConstructor @NoArgsConstructor public class WxMsgModel { @JsonProperty(value = "touser") private String toUser; @JsonProperty(value = "template_id") private String templateId; @JsonProperty(value = "url") private String url; @JsonProperty(value = "topcolor") private String topColor; @JsonProperty(value = "data") private Map<String, Map<String, String>> data; /** * Specially built parameters * * @param value * @param color * @return */ public static Map<String, String> buildMap(String value, String color) { HashMap<String, String> map = new HashMap<>(); map.put("value", value); map.put("color", color); return map; } }
RabbitMQConfig( Send a text message mq To configure PHONE_CHANGE_QUEUE They are all constant values defined casually by themselves )
package com.xiaoge.config; import com.xiaoge.constant.QueueConstant; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.DirectExchange; import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @Classname RabbitMQConfig * @Date 2022/6/25 Afternoon 2:56 * @Created by xiaoge * @Description TODO */ @Configuration public class RabbitMQConfig { /* WeChat mq To configure */ @Bean public Queue wxChangeQueue() { return new Queue(QueueConstant.WX_CHANGE_QUEUE); } @Bean public DirectExchange wxChangeExchange() { return new DirectExchange(QueueConstant.WX_CHANGE_EX); } @Bean public Binding wxBind() { return BindingBuilder .bind(wxChangeQueue()) .to(wxChangeExchange()) .with(QueueConstant.WX_CHANGE_KEY); } }
application.yml
# Wechat official account information wechat: app-id: wx010a59592d9c7234 app-secret: dd6508eb89c7509db542c4b8a0cb062e token-url: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s message-url: https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s
WechatProperties
package com.xiaoge.config; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; /** * @Classname WechatProperties * @Date 2022/6/25 Afternoon 5:31 * @Created by xiaoge * @Description TODO */ @Data @ConfigurationProperties(prefix = "wechat") public class WechatProperties { @ApiModelProperty(" The application of wechat id") private String appId; @ApiModelProperty(" Wechat key ") private String appSecret; @ApiModelProperty(" obtain Tokenurl The address of ") private String tokenUrl; @ApiModelProperty(" Address to send wechat template message ") private String messageUrl; }
WechatAutoConfiguration
package com.xiaoge.config; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; import javax.annotation.PostConstruct; /** * @Classname WechatAutoConfiguration * @Date 2022/6/25 Afternoon 5:32 * @Created by xiaoge * @Description TODO */ @Slf4j @Configuration @EnableConfigurationProperties(value = WechatProperties.class) public class WechatAutoConfiguration { @Autowired private RestTemplate restTemplate; @Autowired private WechatProperties wechatProperties; /** * volatile(jvm Lightweight synchronization mechanism provided ) The three major characteristics : * 1. Guaranteed visibility * 2. There is no guarantee of atomicity * 3. Prohibit command rearrangement * * 1. verification volatile The visibility of * 1.1 If int number = 0; number Variables were not added before volatile Keyword modification , No visibility * 1.2 Added volatile, Can solve visibility issues . * * 2. verification volatile There is no guarantee of atomicity * 2.1 What does atomicity mean ? * An integral , integrity , That is, when a thread is doing a specific business , The middle cannot be plugged or divided , It needs to be complete * Or at the same time , Or fail at the same time . * * 2.2 volatile There is no guarantee of atomicity Case presentation * * number ++ It is non thread safe under multithreading , How not to add synchronized solve ? * * 2.3 why? * Because when the thread writes its own working memory back to the main memory , It's too fast , Notify other threads that they haven't arrived yet , Other threads also write directly back to main memory , So less than 20000 Time , So there is a loss of writing . * * 2.4 How to solve atomicity ? * * Add synchronized * * Use our juc Next AtomicInteger * */ // Because we need to refresh regularly token, In order for other threads to see , We use volatile To modify private volatile String accessToken; /** * This spring Implements the specification of this annotation * be-all bean Execute after the object is created , Execute before the project starts completely * Limit Cannot have return value , Nor can there be parameters * * Because consumers directly monitor producers , * When consumers hang up , * At the start-up, he will directly consume , * But at this time token We didn't get it , * This needs to be sharp token, So we need to add this annotation here */ @PostConstruct public void tokenInit() { refushToken(); } /** * Refresh token Methods Get it within two hours * initialDelay Execute after the project is started , That's why token invalid , Because the consumer and he execute at the same time */ @Scheduled(initialDelay = 7100 * 1000, fixedRate = 7100 * 1000) public void refushToken() { String tokenUrl = String.format(wechatProperties.getTokenUrl(), wechatProperties.getAppId(), wechatProperties.getAppSecret()); String jsonStr = restTemplate.getForObject(tokenUrl, String.class); JSONObject jsonObject = JSON.parseObject(jsonStr); String accessToken = jsonObject.getString("access_token"); if (!StringUtils.isEmpty(accessToken)) { log.info("token To be successful "); this.accessToken = accessToken; return; } log.error("token Acquisition failure "); } public String getAccessToken() { return this.accessToken; } }
WechatListener( Monitor , And send a prompt message )
package com.xiaoge.listener; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.rabbitmq.client.Channel; import com.xiaoge.config.WechatAutoConfiguration; import com.xiaoge.config.WechatProperties; import com.xiaoge.constant.QueueConstant; import com.xiaoge.model.WxMsgModel; import com.xiaoge.service.SmsLogService; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.support.AmqpHeaders; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.io.IOException; /** * @Classname WechatListener * @Date 2022/6/25 Afternoon 5:46 * @Created by xiaoge * @Description TODO */ @Slf4j @Component public class WechatListener { @Autowired private WechatProperties wechatProperties; @Autowired private WechatAutoConfiguration wechatAutoConfiguration; @Autowired private SmsLogService smsLogService; @Autowired private RestTemplate restTemplate; @RabbitListener(queues = QueueConstant.WX_CHANGE_QUEUE, concurrency = "3-5") public void handlerWechatMessage(Channel channel, Message message) { String wxStr = new String(message.getBody()); // Get the news WxMsgModel wxMsgModel = JSON.parseObject(wxStr, WxMsgModel.class); // Hairstyle wechat public profile message realSendWxMsg(wxMsgModel); smsLogService.saveWxMsg(wxMsgModel); try { // Sign for the message channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); } catch (IOException e) { log.error(" Sign in failed !"); } } /** * The real way to send wechat messages * Send wechat official account information * @param wxMsgModel */ private void realSendWxMsg(WxMsgModel wxMsgModel) { // Sending public and private number information url String messageUrl = String.format(wechatProperties.getMessageUrl(), wechatAutoConfiguration.getAccessToken()); // Send a message String result = restTemplate.postForObject(messageUrl, wxMsgModel, String.class); System.out.println(result); } }
SmsLogService
package com.xiaoge.service; import com.aliyuncs.CommonResponse; import com.baomidou.mybatisplus.extension.service.IService; import com.xiaoge.domain.SmsLog; import com.xiaoge.model.AliSmsModel; import com.xiaoge.model.WxMsgModel; /** * @Classname SmsLogService * @Date 2022/6/25 Afternoon 3:19 * @Created by xiaoge * @Description TODO */ public interface SmsLogService extends IService<SmsLog>{ /** * hold wx The information is saved in the database * @param wxMsgModel */ void saveWxMsg(WxMsgModel wxMsgModel); }
SmsLogServiceImpl( Save the sent SMS to the database )
package com.xiaoge.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.aliyuncs.CommonResponse; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xiaoge.domain.SmsLog; import com.xiaoge.mapper.SmsLogMapper; import com.xiaoge.model.AliSmsModel; import com.xiaoge.model.WxMsgModel; import com.xiaoge.service.SmsLogService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; /** * @Classname SmsLogServiceImpl * @Date 2022/6/25 Afternoon 3:19 * @Created by xiaoge * @Description TODO */ @Service public class SmsLogServiceImpl extends ServiceImpl<SmsLogMapper, SmsLog> implements SmsLogService{ @Autowired private SmsLogMapper smsLogMapper; /** * hold wx The information is saved in the database * * @param wxMsgModel */ @Override public void saveWxMsg(WxMsgModel wxMsgModel) { SmsLog smsLog = new SmsLog(); smsLog.setContent(" Wechat message sent successfully "); smsLog.setUserId(wxMsgModel.getToUser()); smsLog.setResponseCode("200"); smsLog.setRecDate(new Date()); smsLog.setStatus(0); smsLog.setType(2); // Insert database smsLogMapper.insert(smsLog); } }
Postman test
Open wechat applet , Take any request token, Just bring it here
边栏推荐
猜你喜欢
If you can't learn, you have to learn. Jetpack compose writes an im app (II)
【附下载】密码获取工具LaZagne安装及使用
4000字超详解指针
[official MySQL document] deadlock
雲計算未來 — 雲原生
TOGAF认证自学宝典V2.0
Summary of development issues
Flutter 退出登录二次确认怎么做才更优雅?
2.8 overview of ViewModel knowledge
Symlink(): solution to protocol error in PHP artisan storage:link on win10
随机推荐
Atomic atomic operation
Implement verification code verification
Use bloc to build a page instance of shutter
在网上炒股开户可以吗?资金安全吗?
(构造笔记)MIT reading部分学习心得
【嵌入式】---- 内存四区介绍
2.9 overview of databinding knowledge points
225. Implement stack with queue
Redis notes 01: Introduction
Cloud Computing future - native Cloud
Is it OK to open an account for online stock speculation? Is the fund safe?
SLF4J 日志门面
雲計算未來 — 雲原生
Unicode查询的官方网站
Prompt unread messages and quantity before opening chat group
Integer int compare size
公纵号发送提示信息(用户微服务--消息微服务)
(构造笔记)ADT与OOP
Laravel time zone timezone
The future of cloud computing cloud native