服务端

消息回调用于自建应用和企业微信进行双向通信。例如:用户发送消息到应用、自定义菜单操作、上报地理位置、上报进入应用事件、审批状态通知事件、外部联系人变更回调等等。

设置接收消息的参数

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

  1. WeComContactApp, err := work.NewWork(&work.UserConfig{
  2. CorpID: "[corp_id]", // 企业微信的app id,所有企业微信共用一个。
  3. AgentID: "[agent_id]", // 内部应用的app id
  4. Secret: "[secret]", // 内部应用的app secret
  5. Token: "[token]", // 内部应用的app token
  6. AESKey: "[aes_key]", // 内部应用的app aeskey
  7. CallbackURL: "[callback_url]", // 内部应用的场景回调设置
  8. OAuth: work.OAuth{
  9. Callback: "[app_oauth_callback_url]", // 内部应用的app oauth url
  10. Scopes: nil,
  11. },
  12. HttpDebug: true,
  13. })

验证URL有效性

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

  1. rs, err := services.WeComContactApp.Server.Serve(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. rs, err := services.WeComContactApp.Server.Notify(c.Request, func(event contract.EventInterface) interface{} {
  2. fmt.Println("event", event)
  3. //return "handle callback"
  4. // event output:
  5. //{
  6. // "EventInterface": null,
  7. // "XMLName": {
  8. // "Space": "",
  9. // "Local": "xml"
  10. // },
  11. // "Text": "",
  12. // "ToUserName": "ww454dfb9d6f6d432a",
  13. // "FromUserName": "sys",
  14. // "CreateTime": "1654861516",
  15. // "MsgType": "event",
  16. // "Event": "change_contact",
  17. // "ChangeType": "update_user",
  18. // "Content": "PHhtbD48VG9Vc2VyTmFtZT48IVtDREFUQVt3dzQ1NGRmYjlkNmY2ZDQzMmFdXT48L1RvVXNlck5hbWU+PEZyb21Vc2VyTmFtZT48IVtDREFUQVtzeXNdXT48L0Zyb21Vc2VyTmFtZT48Q3JlYXRlVGltZT4xNjU0ODYxNTE2PC9DcmVhdGVUaW1lPjxNc2dUeXBlPjwhW0NEQVRBW2V2ZW50XV0+PC9Nc2dUeXBlPjxFdmVudD48IVtDREFUQVtjaGFuZ2VfY29udGFjdF1dPjwvRXZlbnQ+PENoYW5nZVR5cGU+PCFbQ0RBVEFbdXBkYXRlX3VzZXJdXT48L0NoYW5nZVR5cGU+PFVzZXJJRD48IVtDREFUQVtXYW5nQ2hhb1lpXV0+PC9Vc2VySUQ+PEFkZHJlc3M+PCFbQ0RBVEFbYWRkci4uLl1dPjwvQWRkcmVzcz48L3htbD4="
  19. //}
  20. // 这里需要获取到事件类型,然后把对应的结构体传递进去进一步解析
  21. // 所有包含的结构体请参考: https://github.com/ArtisanCloud/PowerWeChat/tree/master/src/work/server/handlers/models
  22. if event.GetEvent() == models.CALLBACK_EVENT_CHANGE_CONTACT && event.GetChangeType() == models.CALLBACK_EVENT_CHANGE_TYPE_CREATE_PARTY {
  23. msg := models.EventPartyCreate{}
  24. err := event.ReadMessage(&msg)
  25. if err != nil {
  26. println(err.Error())
  27. return "error"
  28. }
  29. fmt.Dump(msg)
  30. }
  31. // 假设员工给应用发送消息,这里可以直接回复消息文本,
  32. // return "I'm recv..."
  33. // 这里回复success告诉微信我收到了,后续需要回复用户信息可以主动调发消息接口
  34. return kernel.SUCCESS_EMPTY_RESPONSE
  35. })
  36. if err != nil {
  37. panic(err)
  38. }
  39. // 选择1: 直接把gin context writer传入,会自动回复。
  40. err = rs.Send(c.Writer)
  41. if err != nil {
  42. panic(err)
  43. }
  44. // 选择2: 或者是把内容读取出来
  45. //text, _ := ioutil.ReadAll(rs.Body)
  46. //c.String(http.StatusOK, string(text))

事件和消息结构体

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

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

参考示例

参考:PowerWechatTutorial