公众号开发:获取用户消息和回复消息

本文首发于个人公众号【Java技术大杂烩】,欢迎关注。

最近在看微信公众号的开发文档,觉得很有意思,可以自定义开发一些功能,比如有人关注了公众号之后,你可以做出稍微复杂点的回复(简单的回复在公众号后台配置就好啦);比如关注者发送了「学习」消息,你可以给他推送一些文章,发送「天气」的消息,你可以回复当前的天气状况;还可以进行素材的管理,用户的管理等等。

今天先来实现下最简单的获取关注者发送的消息,并给他回复同样的消息,支持文本消息,图片和语音。后续再解锁其他的姿势。

先来看看最终效果:

接下来开始操作,主要分为以下几个步骤:

  1. 申请测试公众号
  2. 配置服务器地址
  3. 验证服务器地址的有效性
  4. 接收消息,回复消息

申请测试公众号

第一步首先要申请一个测试的微信公众号,地址:

https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

配置服务器地址

在测试号页面上有接口配置信息选项,在这个选项下面进行配置:

有两个配置项:服务器地址(URL)Token,在正式的公众号上还有一个选项EncodingAESKey

  1. URL:是开发者用来接收微信消息和事件的接口URL。
  2. Token可可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。
  3. EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。

当输入这个 URL 和 Token 点击保存的时候,需要后台启动并且验证 Token 通过之后才能保存,不然会保存失败,所以先把后台代码启动起来。

验证 Token

当填写 URL, Token,点击保存时,微信会通过 GET 的方式把微信加密签名(signature)时间戳(timestamp)随机数(nonce)随机字符串(echostr)传到后台,我们根据这四个参数来验证 Token。

验证步骤如下:

  1. 将token、timestamp、nonce三个参数进行字典序排序。
  2. 将三个参数字符串拼接成一个字符串进行sha1加密.
  3. 获得加密后的字符串与signature对比,如果相等,返回echostr,表示配置成功,否则返回null,配置失败。

代码如下

首先在application.properties配置文件中配置项目启动端口,Token,appId和appsecret,其中,Token随便写,只要和页面配置一致即可,appId和appsecret 在测试公众号页面可以看到,如下所示:

server.port=80
wechat.interface.config.token=wechattoken
wechat.appid=wxfe39186d102xxxxx
wechat.appsecret=cac2d5d68f0270ea37bd6110b26xxxx

然后把这些配置信息映射到类属性上去:

@Component
public class WechatUtils {
    @Value("${wechat.interface.config.token}")
    private String token;
    @Value("${wechat.appid}")
    private String appid;
    @Value("${wechat.appsecret}")
    private String appsecret;

    public String getToken() { return token; }
    public String getAppid() {return appid;}
    public String getAppsecret() {return appsecret;}
}

然后,需要有个方法,用来接收微信传过来的四个参数,请求的 URL 和页面配置的需要一样,如下:

@RestController
public class WechatController {
    /** 日志 */
    private Logger logger = LoggerFactory.getLogger(getClass());
    /** 工具类 */
    @Autowired
    private WechatUtils wechatUtils;

    /**
     * 微信公众号接口配置验证
     * @return
     */
    @RequestMapping(value = "/wechat", method = RequestMethod.GET)
    public String checkSignature(String signature, String timestamp, 
                                     String nonce, String echostr) {
        logger.info("signature = {}", signature);
        logger.info("timestamp = {}", timestamp);
        logger.info("nonce = {}", nonce);
        logger.info("echostr = {}", echostr);
        // 第一步:自然排序
        String[] tmp = {wechatUtils.getToken(), timestamp, nonce};
        Arrays.sort(tmp);
        // 第二步:sha1 加密
        String sourceStr = StringUtils.join(tmp);
        String localSignature = DigestUtils.sha1Hex(sourceStr);
        // 第三步:验证签名
        if (signature.equals(localSignature)) {
            return echostr;
        }
        return null;
    }
}

这里需要注意的是请求方式一定是GET的方式,POST方式是用户每次向公众号发送消息、或者产生自定义菜单、或产生微信支付订单等情况时,微信还是会根据这个URL来发送消息或事件。

启动项目,这时在测试公众号配置 URL 和 Token:

你会发现保存失败,后台也没有接收到消息,日志都没有打印;这是因为是在本地启动的项目,访问地址为127.0.0.1,而在点击保存的时候,是由腾讯服务器发送过来的,人家的服务器自然是访问不到你本地啦,所以还需要一款内网穿透工具,把我们本机地址映射到互联网上去,这样腾讯服务器就可以把消息发送过来啦。

我使用的是natapp这款工具,运行之后,如下:

http://pquigs.natappfree.cc这个互联网地址会映射到我们的本机127.0.0.1的地址,页面上就配置这个地址:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值