微信公众号开启了服务器配置,那么自定义菜单和手动设置的自动回复就失效了
相当于自定义菜单和自动回复只能通过接口来实现了
自定义菜单实现比较简单:
先获取到token
然后调用接口
这里有一个问题,就是用户点击了菜单,我们怎么给用户相应的链接或者是图文消息呢?
思路如下:
用户点击菜单之后微信会推送事件到我们的服务器地址上
这里有两点需要注意:
1.事件通知是以post请求推送到这个服务器地址上的。
2.用户点击哪一个菜单通过EventKey(创建菜单时填写的Key)来判断
那我们这里怎么接收到了事件反馈给用户呢?
需要使用被动回复用户消息功能
简单来说就是接收到了微信的事件然后返回对应xml字符串给微信。
比如我收到的事件的类型是text,那么我返回给微信的就是对应的xml字符串
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
<MsgDataId>xxxx</MsgDataId>
<Idx>xxxx</Idx>
</xml>
把真实数据填充到xml中,返回给微信,微信接收到了就会给用户发送对应的消息
这里我以go语言为例子(语言不重要,主要是思路)
一个简单的服务器地址的处理逻辑如下:
func (l *PostPublicCallbackLogic) PostPublicCallback(w http.ResponseWriter, r *http.Request) error {
body, err := ioutil.ReadAll(r.Body)
var xmlMsg XMLMessage
err = xml.Unmarshal(body, &xmlMsg)
if err != nil {
logx.Errorf("消息推送失败 error: %v\n", xmlMsg)
return err
}
//1.用户发送消息
if xmlMsg.MsgType == "text" && strings.Contains(xmlMsg.Content, "停车") {
text := sendImage(xmlMsg, "dZ7hibV5wsIdYdwWOhRIi7T7V0CRXSi7cB0tVgO1YFg_w_yV-NROef2xS_YyrUxn")
w.Write([]byte(text))
return nil
}
//2.用户点击自定义菜单事件
if xmlMsg.Event == "CLICK" {
switch xmlMsg.EventKey {
case "2": //创建菜单的KEY
xmlMsg.Content = "关注“汇邻商管”公众号,可至汇邻广场5号楼1F客服中心领取中影“9.9”元观影券一张(仅限中影汇邻店使用),每号限领一次,观影券数量有限,送完即止!"
text := sendText(xmlMsg)
w.Write([]byte(text))
return nil
case "4":
text := sendImage(xmlMsg, "dZ7hibV5wsIdYdwWOhRIi1u0Z4ZmJJ_fX1BLO8ewDHhOJs2FBj37YYTb0cti81GK")
w.Write([]byte(text))
return nil
case "8":
xmlMsg.Content = "暂时没有抽奖~"
text := sendText(xmlMsg)
w.Write([]byte(text))
return nil
}
}
w.Write([]byte(""))
if xmlMsg.Event != constants.Follow && xmlMsg.Event != constants.CancelFollow {
return nil
}
return nil
}
//发送文本消息
func sendText(xmlMsg XMLMessage) string {
textTpl := `"<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";`
finalText := fmt.Sprintf(textTpl, xmlMsg.FromUserName, xmlMsg.ToUserName, xmlMsg.CreateTime, xmlMsg.Content)
return finalText
}
//发送图片消息
func sendImage(xmlMsg XMLMessage, mediaId string) string {
imageInfo := `"<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[%s]]></MediaId>
</Image>
</xml>";`
finalText := fmt.Sprintf(imageInfo, xmlMsg.FromUserName, xmlMsg.ToUserName, xmlMsg.CreateTime, mediaId)
return finalText
}
测试一下自定义回复
我们看到自定义回复和自定义菜单已经ok了。