wechat_conn.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. package wechat
  2. import (
  3. "crypto/sha1"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "rtzh_elec_temperature/conf"
  9. "rtzh_elec_temperature/logger"
  10. "rtzh_elec_temperature/tools"
  11. "os"
  12. "strconv"
  13. "sort"
  14. "strings"
  15. "time"
  16. "github.com/astaxie/beego/context"
  17. "github.com/silenceper/wechat/v2"
  18. "github.com/silenceper/wechat/v2/cache"
  19. "github.com/silenceper/wechat/v2/officialaccount"
  20. offConfig "github.com/silenceper/wechat/v2/officialaccount/config"
  21. "github.com/silenceper/wechat/v2/officialaccount/message"
  22. "github.com/silenceper/wechat/v2/officialaccount/oauth"
  23. //wechatuser "github.com/silenceper/wechat/v2/officialaccount/user"
  24. "github.com/astaxie/beego/orm"
  25. //wechatMenu "github.com/silenceper/wechat/v2/officialaccount/menu"
  26. )
  27. type WeThird struct {
  28. Id int `orm:pk,auto`
  29. UserId int
  30. Platform string `orm:default:"wechat"`
  31. Appid string
  32. Apptype string
  33. Unionid string
  34. Openid string
  35. Openname string
  36. Sex string
  37. Headimgurl string
  38. AccessToken string
  39. RefreshToken string
  40. ExpiresIn int
  41. Createtime int
  42. Updatetime int
  43. Logintime int
  44. Expiretime int
  45. }
  46. type Wechat struct {
  47. Token string
  48. officialAccount *officialaccount.OfficialAccount
  49. Cfg *offConfig.Config
  50. }
  51. func init() {
  52. fmt.Println("=======wechat init")
  53. orm.RegisterModel(new(WeThird))
  54. go func() {
  55. time.Sleep(3 * time.Second)
  56. dbo := orm.NewOrm()
  57. var h []orm.Params
  58. sql := "select 1 from we_third"
  59. _, err := dbo.Raw(sql).Values(&h)
  60. if err != nil {
  61. if strings.Index(err.Error(), "doesn't exist") > -1 {
  62. logger.Logger.Error("未初始化Wechat数据表,脚本:db/db_wechat_init.sql")
  63. }
  64. }
  65. }()
  66. }
  67. func (t *Wechat) Init() {
  68. cfgpath := "conf/wechat-" + conf.GlobalConfig["runmode"] + ".cnf"
  69. fileHanlder, err := os.Open(cfgpath)
  70. if err != nil {
  71. fmt.Println(tools.NowTime()+" 配置文件"+cfgpath+":", err)
  72. tools.Log(err)
  73. return
  74. }
  75. txt, readerr := ioutil.ReadAll(fileHanlder)
  76. if readerr != nil {
  77. fmt.Println(tools.NowTime() + " " + readerr.Error())
  78. tools.Log(readerr)
  79. return
  80. }
  81. fileHanlder.Close()
  82. cfgJson := map[string]string{}
  83. err = json.Unmarshal(txt, &cfgJson)
  84. if err != nil {
  85. fmt.Println(tools.NowTime()+" 无效的配置文件"+cfgpath, err)
  86. tools.Log(err)
  87. return
  88. }
  89. wx := wechat.NewWechat()
  90. cfg := &offConfig.Config{
  91. AppID: cfgJson["AppID"],
  92. AppSecret: cfgJson["AppSecret"],
  93. Token: cfgJson["Token"],
  94. EncodingAESKey: cfgJson["EncodingAESKey"],
  95. Cache: cache.NewMemory(),
  96. }
  97. t.Cfg = cfg
  98. t.officialAccount = wx.GetOfficialAccount(cfg)
  99. }
  100. func (t *Wechat) UpdateToken(tokeninfo oauth.ResAccessToken) {
  101. dbc := orm.NewOrm()
  102. sql := "update we_third set access_token=?,expires_in=? where appid=? and openid=?"
  103. _, err := dbc.Raw(sql, tokeninfo.AccessToken, tokeninfo.ExpiresIn, t.Cfg.AppID, tokeninfo.OpenID).Exec()
  104. if err != nil {
  105. tools.Log(err)
  106. }
  107. }
  108. func (t *Wechat) PushMsg(to string, txt string) {
  109. msg := message.NewCustomerTextMessage(to, txt)
  110. mm := t.officialAccount.GetCustomerMessageManager().Send(msg)
  111. if mm != nil {
  112. tools.Log(mm)
  113. }
  114. }
  115. func (t *Wechat) Message(ctx *context.Context) {
  116. // 传入request和responseWriter
  117. server := t.officialAccount.GetServer(ctx.Request, ctx.ResponseWriter)
  118. //设置接收消息的处理方法
  119. server.SetMessageHandler(func(msg *message.MixMessage) *message.Reply {
  120. //fmt.Println(msg.FromUserName)
  121. //fmt.Println(msg.Event)
  122. //回复消息:演示回复用户发送的消息
  123. /*
  124. return nil*/
  125. //text := message.NewText(msg.Content)
  126. //return &message.Reply{MsgType: message.MsgTypeText, MsgData: text}
  127. return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText("感谢您的支持和信任")}
  128. })
  129. //处理消息接收以及回复
  130. err := server.Serve()
  131. if err != nil {
  132. fmt.Println(err)
  133. return
  134. }
  135. reqmessage := server.RequestMsg
  136. if reqmessage.Event == "subscribe" {
  137. t.Subscribe(reqmessage)
  138. } else if reqmessage.Event == "unsubscribe" {
  139. t.UnSubscribe(reqmessage)
  140. }
  141. if reqmessage.Content == "111" {
  142. tpl := message.TemplateMessage{
  143. ToUser: string(reqmessage.FromUserName),
  144. TemplateID: "y-7BIRqRKI6Mg8lTp4U2W5hkdR9N_jNNpShpojIvx2Y",
  145. URL: "",
  146. Data: map[string]*message.TemplateDataItem{
  147. "first": {Value: "有新的客户预约,请及时查看"},
  148. "cardNumber": {Value: "13762", Color: "red"},
  149. "address": {Value: "x路x号"},
  150. "VIPName": {Value: "高级VIP"},
  151. "VIPPhone": {Value: "1868127287"},
  152. "expDate": {Value: "永久"},
  153. "remark": {Value: "点击进入会员中心"},
  154. },
  155. }
  156. t.officialAccount.GetTemplate().Send(&tpl)
  157. }
  158. //发送回复的消息
  159. server.Send()
  160. }
  161. func (t *Wechat) Subscribe(msg *message.MixMessage) {
  162. appid := t.Cfg.AppID
  163. userid := string(msg.FromUserName)
  164. u := t.officialAccount.GetUser()
  165. uinfo, err := u.GetUserInfo(userid)
  166. if err != nil {
  167. tools.Log(err)
  168. return
  169. }
  170. dbobj := orm.NewOrm()
  171. uobj := WeThird{Appid: appid, Openid: userid, Openname: uinfo.Nickname, Logintime: int(time.Now().Unix())}
  172. uobj.Sex = strconv.Itoa(int(uinfo.Sex))
  173. uobj.Headimgurl = uinfo.Headimgurl
  174. uobj.Unionid = uinfo.UnionID
  175. _, err = dbobj.Insert(&uobj)
  176. if err != nil {
  177. tools.Log(err)
  178. return
  179. }
  180. //创建菜单
  181. menuObj := t.officialAccount.GetMenu()
  182. menujson := `{
  183. "button":[
  184. {
  185. "type":"view",
  186. "name":"店铺",
  187. "key":"MENU_JUJUTONG_CASE",
  188. "url":"https://www.jujutong.cloud/mobile/furniture/case/index.html"
  189. },{
  190. "type":"view",
  191. "name":"预约",
  192. "key":"MENU_JUJUTONG_MALL",
  193. "url":"https://www.jujutong.cloud/mobile/furniture/mall/index.html"
  194. },
  195. {
  196. "type":"view",
  197. "name":"我的",
  198. "url":"",
  199. "sub_button":[
  200. {
  201. "type":"view",
  202. "name":"沟通",
  203. "url":"https://www.jujutong.cloud/api/wechat/r/chat"
  204. }
  205. ]
  206. }]
  207. }`
  208. err = menuObj.SetMenuByJSON(menujson)
  209. if err != nil {
  210. tools.Log(err)
  211. return
  212. }
  213. }
  214. func (t *Wechat) UnSubscribe(msg *message.MixMessage) {
  215. menuObj := t.officialAccount.GetMenu()
  216. menuObj.DeleteMenu()
  217. appid := t.Cfg.AppID
  218. userid := string(msg.FromUserName)
  219. dbc := orm.NewOrm()
  220. _, err := dbc.Raw("delete from we_third where appid=? and openid=?", appid, userid).Exec()
  221. if err != nil {
  222. tools.Log(err)
  223. }
  224. }
  225. func (t *Wechat) makeSignature(timestamp, nonce string) string {
  226. //1. 将 plat_token、timestamp、nonce三个参数进行字典序排序
  227. sl := []string{t.Token, timestamp, nonce}
  228. sort.Strings(sl)
  229. //2. 将三个参数字符串拼接成一个字符串进行sha1加密
  230. s := sha1.New()
  231. io.WriteString(s, strings.Join(sl, ""))
  232. return fmt.Sprintf("%x", s.Sum(nil))
  233. }