服务端

消息回调用于自建服务器和微信公众号进行双向通信.

例如:

  • 接收和自动回复用户消息
  • 接口地理位置
  • 关注/取消关注事件
  • 扫描带参数二维码事件
  • 自定义菜单事件
  • 点击菜单拉取消息时的事件推送
  • 点击菜单跳转链接时的事件推送

设置接收消息的参数

使用之前请先配置好URL、Token、EncodingAESKey。

  1. OfficialAccountApp, err := officialAccount.NewOfficialAccount(&officialAccount.UserConfig{
  2. AppID: conf.OffiAccount.AppID, // 小程序、公众号或者企业微信的appid
  3. Secret: conf.OffiAccount.AppSecret, // 商户号 appID
  4. Token: conf.OffiAccount.MessageToken,
  5. AESKey: conf.OffiAccount.MessageAesKey,
  6. ResponseType: os.Getenv("response_type"),
  7. Log: officialAccount.Log{
  8. Level: "debug",
  9. File: "./wechat.log",
  10. },
  11. Cache: cache,
  12. HttpDebug: true,
  13. Debug: false,
  14. })

验证URL有效性

这里接收一个标准的http.Request,PowerWeChat会自动帮你解析里面的参数,你只要将解析出来的string通过web框架返回给微信即可。

TIP

验证URL这一块已经和企业微信 Server.Serve 部分不太一样了,增加了新的接口 Server.VerifyURL

  1. rs, err := services.OfficialAccountApp.Server.VerifyURL(c.Request)
  2. if err != nil {
  3. panic(err)
  4. }
  5. text, _ := ioutil.ReadAll(rs.Body)
  6. // 这里是gin的使用方法,c *gin.Context
  7. // c.String(http.StatusOK, string(text))

开始接收消息

终于,我们到了消息接收这一步,微信在一些事件变更的时候会推送消息过来。

  1. import (
  2. models2 "github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/models"
  3. "github.com/ArtisanCloud/PowerWeChat/v3/src/officialAccount/server/handlers/models"
  4. )
  5. rs, err := services.OfficialAccountApp.Server.Notify(c.Request, func(event contract.EventInterface) interface{} {
  6. fmt.Println("event", event)
  7. // event output:
  8. // {
  9. // "EventInterface": null,
  10. // "XMLName": {
  11. // "Space": "",
  12. // "Local": "xml"
  13. // },
  14. // "Text": "\n \n \n \n \n \n \n \n",
  15. // "ToUserName": "gh_1d1ccd059b2d",
  16. // "FromUserName": "oKmMk6AcUTTQAcHbERb85kLm9fdg",
  17. // "CreateTime": "1657125069",
  18. // "MsgType": "text",
  19. // "Event": "",
  20. // "ChangeType": "",
  21. // "Content": "PHhtbD4KICAgIDxUb1VzZXJOYW1lPjwhW0NEQVRBW2doXzFkMWNjZDA1OWIyZF1dPjwvVG9Vc2VyTmFtZT4KICAgIDxGcm9tVXNlck5hbWU+PCFbQ0RBVEFbb0ttTWs2QWN// VVFRRQWNIYkVSYjg1a0xtOWZkZ11dPjwvRnJvbVVzZXJOYW1lPgogICAgPENyZWF0ZVRpbWU+MTY1NzEyNTA2OTwvQ3JlYXRlVGltZT4KICAgIDxNc2dUeXBlPjwhW0NEQVRBW3RleHRdXT// 48L01zZ1R5cGU+CiAgICA8Q29udGVudD48IVtDREFUQVsxMTExXV0+PC9Db250ZW50PgogICAgPE1zZ0lkPjIzNzI0MzI2OTAxOTgxMzg4PC9Nc2dJZD4KICAgIDxFbmNyeXB0PjwhW0NEQ// VRBW0pHbVFJUkNmMmN5UDM2UGs0U2F1bzMya2pjSjVQNG9hQldVRGJMSXhoRGpvZFpPbkliMDRCOFVweVVDb09kRGwvQnd0MW9XNVdPdDlFTFd1c3VpWlpacVloblVhYTFJU1h0aTJxcHlQ// QXlvK3pHNkE2YmR4akh0MG15R0JNVElrOGw2ZHJJM2RITEpBYWpEMW5BRFNxa0FwbW5rZXMwZzdDSXlrMk1KRzR3VUZnay9vMlN4TGcwbi9weE5tUUFYcUZuUndSSzlkZWJkZXZTSHdLZGM// veDhyNnQ4ZmJsMHZFWHY1RzlYT1FhclJUM0tzamlydkFVUS90eTIrYnlYMU51bEJmSHoxMFFrbnkyVnp5QmNRSW9ycXc1VjF0bFREQnZRQkYrc3pHcXVxeTJibDV2MFlBT09TZk9ZRDFJd1// FxWjlzYmdIQkc3bDNKaEJLbE1HY0dzS2VGTjVhdk9BRU1CQ0tiejc2MkFqWXN6VUdnMGl1RHVrQmtGdGRhVUdrQVpSeU12d2hMRzZsdFhNTHljSmxPSGgvTzFQUFVJVFdQcnNueTZxellRN// kk9XV0+PC9FbmNyeXB0Pgo8L3htbD4K"
  22. // }
  23. //
  24. // 这里需要获取到事件类型,然后把对应的结构体传递进去进一步解析
  25. // 所有包含的结构体请参考: https://github.com/ArtisanCloud/PowerWeChat/v3/src/officialAccount/server/handlers/models
  26. switch event.GetMsgType() {
  27. case models2.CALLBACK_MSG_TYPE_TEXT:
  28. msg := models.MessageText{}
  29. err := event.ReadMessage(&msg)
  30. if err != nil {
  31. println(err.Error())
  32. return "error"
  33. }
  34. fmt.Dump(msg)
  35. }
  36. // 假设用户给应用发送消息,这里可以直接回复消息文本,
  37. // return "I'm recv..."
  38. // 这里回复success告诉微信我收到了,后续需要回复用户信息可以主动调发消息接口
  39. return kernel.SUCCESS_EMPTY_RESPONSE
  40. // 如果要返回xml,也可以返回message对象
  41. return messages.NewText("返回消息内容")
  42. })
  43. if err != nil {
  44. panic(err)
  45. }
  46. // 选择1: 直接把gin context writer传入,会自动回复。
  47. err = rs.Send(c.Writer)
  48. if err != nil {
  49. panic(err)
  50. }
  51. // 选择2: 或者是把内容读取出来
  52. //text, _ := ioutil.ReadAll(rs.Body)
  53. //c.String(http.StatusOK, string(text))

事件和消息结构体

由于微信事件太多难以通过文档形式全部展现出来,所以请自行看源码文件里面的定义。

如果有什么使用相关问题,欢迎联系我们或者提交PR。

参考示例

参考:PowerWechatTutorial

微信官方文档: https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html