wechat_send_msg.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. package services
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "hongze/hongze_clpt/models"
  8. "hongze/hongze_clpt/utils"
  9. "io/ioutil"
  10. "net/http"
  11. "strconv"
  12. "strings"
  13. "time"
  14. )
  15. // 访谈申请
  16. func SendInterviewApplyTemplateMsg(realName, companyName, mobile, articleTitle string, itemOpenid *models.OpenIdList) (err error) {
  17. var msg string
  18. defer func() {
  19. if err != nil {
  20. go utils.SendEmail("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  21. go utils.SendAlarmMsg(fmt.Sprint("访谈申请模板消息推送消息失败,手机号", mobile, "公司:", companyName, "手机号:", mobile), 2)
  22. }
  23. if msg != "" {
  24. utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
  25. }
  26. }()
  27. accessToken, err := models.GetWxAccessTokenByXzs()
  28. if err != nil {
  29. msg = "GetWxAccessToken Err:" + err.Error()
  30. return
  31. }
  32. if accessToken == "" {
  33. msg = "accessToken is empty"
  34. return
  35. }
  36. sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  37. sendMap := make(map[string]interface{})
  38. sendData := make(map[string]interface{})
  39. keyword1 := realName + "【" + companyName + "】"
  40. first := "您有一条新的访谈申请,请及时处理。"
  41. keyword2 := mobile
  42. keyword3 := time.Now().Format(utils.FormatDateTime)
  43. keyword4 := articleTitle
  44. fontColor := "#D9001B"
  45. sendData["first"] = map[string]interface{}{"value": first, "color": fontColor}
  46. sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": fontColor}
  47. sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": fontColor}
  48. sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": fontColor}
  49. sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": fontColor}
  50. sendMap["template_id"] = utils.WxMsgTemplateIdApplyXzs
  51. sendMap["data"] = sendData
  52. sendTemplateMsg(sendUrl, sendMap, itemOpenid, mobile, utils.TEMPLATE_MSG_CYGX_APPLY)
  53. fmt.Println("send end")
  54. return
  55. }
  56. // 访谈申请取消
  57. func SendInterviewApplyCancelTemplateMsg(realName, companyName, mobile, articleTitle string, itemOpenid *models.OpenIdList) (err error) {
  58. var msg string
  59. defer func() {
  60. if err != nil {
  61. go utils.SendEmail("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  62. go utils.SendAlarmMsg(fmt.Sprint("访谈申请取消模板消息推送消息失败,手机号", mobile, "公司:", companyName, "手机号:", mobile), 2)
  63. }
  64. if msg != "" {
  65. utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
  66. }
  67. }()
  68. accessToken, err := models.GetWxAccessTokenByXzs()
  69. if err != nil {
  70. msg = "GetWxAccessToken Err:" + err.Error()
  71. return
  72. }
  73. if accessToken == "" {
  74. msg = "accessToken is empty"
  75. return
  76. }
  77. sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  78. sendMap := make(map[string]interface{})
  79. sendData := make(map[string]interface{})
  80. first := realName + "-" + mobile + "【" + companyName + "】的访谈申请已取消,请留意。"
  81. keyword1 := articleTitle
  82. keyword2 := time.Now().Format(utils.FormatDateTime)
  83. fontColor := "#D9001B"
  84. sendData["first"] = map[string]interface{}{"value": first, "color": fontColor}
  85. sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": fontColor}
  86. sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": fontColor}
  87. sendMap["template_id"] = utils.WxMsgTemplateIdApplyCancelXzs
  88. sendMap["data"] = sendData
  89. sendTemplateMsg(sendUrl, sendMap, itemOpenid, mobile, utils.TEMPLATE_MSG_CYGX_APPLY)
  90. fmt.Println("send end")
  91. return
  92. }
  93. // 权限申请
  94. func SendPermissionApplyTemplateMsg(realName, companyName, mobile, applyMethod string, itemOpenid *models.OpenIdList) (err error) {
  95. var msg string
  96. defer func() {
  97. if err != nil {
  98. go utils.SendEmail("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  99. go utils.SendAlarmMsg(fmt.Sprint("权限申请模板消息推送消息失败,手机号", mobile, "公司:", companyName, "手机号:", mobile), 2)
  100. }
  101. if msg != "" {
  102. utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
  103. }
  104. }()
  105. //var accessToken string
  106. //if utils.RunMode == "release" {
  107. // accessToken, err = models.GetWxAccessTokenByXzs()
  108. // if err != nil {
  109. // msg = "GetWxAccessToken Err:" + err.Error()
  110. // return
  111. // }
  112. // if accessToken == "" {
  113. // msg = "accessToken is empty"
  114. // return
  115. // }
  116. //} else {
  117. // accessToken, err = models.GetWxAccessToken()
  118. // if err != nil {
  119. // msg = "GetWxAccessToken Err:" + err.Error()
  120. // return
  121. // }
  122. // if accessToken == "" {
  123. // msg = "accessToken is empty"
  124. // return
  125. // }
  126. //}
  127. //
  128. //sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  129. //
  130. //sendMap := make(map[string]interface{})
  131. //sendData := make(map[string]interface{})
  132. //
  133. //keyword1 := realName + "【" + companyName + "】"
  134. //first := "查研观向有一条新的权限申请,请及时处理。"
  135. //keyword2 := mobile
  136. //keyword3 := time.Now().Format(utils.FormatDateTime)
  137. //keyword4 := applyMethod
  138. //fontColor := "#D9001B"
  139. //sendData["first"] = map[string]interface{}{"value": first, "color": fontColor}
  140. //sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": fontColor}
  141. //sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": fontColor}
  142. //sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": fontColor}
  143. //sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": fontColor}
  144. //if utils.RunMode == "release" {
  145. // sendMap["template_id"] = utils.WxMsgTemplateIdApplyXzs
  146. //} else {
  147. // sendMap["template_id"] = utils.WxMsgTemplateIdApply
  148. //}
  149. //sendMap["data"] = sendData
  150. //sendTemplateMsg(sendUrl, sendMap, itemOpenid, mobile, utils.TEMPLATE_MSG_CYGX_APPLY)
  151. //fmt.Println("send end")
  152. var first string
  153. var keyword1 string
  154. var keyword2 string
  155. var keyword3 string
  156. var keyword4 string
  157. var remark string
  158. var redirectUrl string
  159. detail, e := models.GetCygxApplyRecordByMobile(mobile)
  160. if e != nil {
  161. err = errors.New("GetActivitySignupNomeetingCountList" + e.Error())
  162. return
  163. }
  164. //如果是潜在客户就推送可查看详情的模版消息
  165. if detail.ApplyMethod == 2 {
  166. redirectUrl = utils.WX_MSG_PATH_APPLY_DETAIL + strconv.Itoa(detail.ApplyRecordId)
  167. }
  168. keyword1 = "权限申请:" + realName + "【" + companyName + "】"
  169. keyword2 = mobile
  170. keyword3 = time.Now().Format(utils.FormatDateTime)
  171. keyword4 = applyMethod
  172. openIdArr := make([]string, 0)
  173. openIdArr = append(openIdArr, itemOpenid.OpenId)
  174. sendInfo := new(SendWxTemplate)
  175. sendInfo.First = first
  176. sendInfo.Keyword1 = keyword1
  177. sendInfo.Keyword2 = keyword2
  178. sendInfo.Keyword3 = keyword3
  179. sendInfo.Keyword4 = keyword4
  180. sendInfo.Remark = remark
  181. sendInfo.TemplateId = utils.WxMsgTemplateIdApplyXzs
  182. sendInfo.RedirectUrl = redirectUrl
  183. sendInfo.RedirectTarget = 3
  184. sendInfo.Resource = mobile
  185. sendInfo.SendType = utils.TEMPLATE_MSG_CYGX_APPLY
  186. sendInfo.OpenIdArr = openIdArr
  187. err = PublicSendTemplateMsg(sendInfo)
  188. return
  189. }
  190. func sendTemplateMsg(sendUrl string, sendMap map[string]interface{}, itemOpenid *models.OpenIdList, resource string, sendType int) (err error) {
  191. sendMap["touser"] = itemOpenid.OpenId
  192. data, err := json.Marshal(sendMap)
  193. if err != nil {
  194. fmt.Println("SendTemplateMsgOne Marshal Err:", err.Error())
  195. return err
  196. }
  197. err = toSendTemplateMsg(sendUrl, data, resource, sendType, itemOpenid)
  198. if err != nil {
  199. fmt.Println("send err:", err.Error())
  200. }
  201. return
  202. }
  203. func toSendTemplateMsg(sendUrl string, data []byte, resource string, sendType int, dataItem *models.OpenIdList) (err error) {
  204. client := http.Client{}
  205. resp, err := client.Post(sendUrl, "application/json", bytes.NewBuffer(data))
  206. if err != nil {
  207. return
  208. }
  209. defer resp.Body.Close()
  210. body, _ := ioutil.ReadAll(resp.Body)
  211. var templateResponse SendTemplateResponse
  212. err = json.Unmarshal(body, &templateResponse)
  213. fmt.Println(templateResponse)
  214. utils.FileLog.Info("SendResult %s:", string(body))
  215. if err != nil {
  216. utils.FileLog.Info("SendResult Unmarshal Err:%s", err.Error())
  217. return err
  218. }
  219. //新增模板消息推送记录
  220. {
  221. tr := new(models.UserTemplateRecord)
  222. tr.UserId = dataItem.UserId
  223. tr.OpenId = dataItem.OpenId
  224. tr.Resource = resource
  225. tr.SendData = string(data)
  226. tr.Result = string(body)
  227. tr.CreateDate = time.Now().Format(utils.FormatDate)
  228. tr.CreateTime = time.Now().Format(utils.FormatDateTime)
  229. if templateResponse.Errcode == 0 {
  230. tr.SendStatus = 1
  231. } else {
  232. tr.SendStatus = 0
  233. }
  234. tr.SendType = sendType
  235. go func() {
  236. err = models.AddUserTemplateRecord(tr)
  237. if err != nil {
  238. utils.FileLog.Info(fmt.Sprintf("AddUserTemplateRecord Err:%s", err.Error()))
  239. }
  240. }()
  241. }
  242. return
  243. }
  244. type SendTemplateResponse struct {
  245. Errcode int `json:"errcode"`
  246. Errmsg string `json:"errmsg"`
  247. MsgID int `json:"msgid"`
  248. }
  249. type SendWxTemplate struct {
  250. WxAppId string `description:"公众号appId"`
  251. First string `description:"模板消息first字段"`
  252. Keyword1 string `description:"模板消息keyword1字段"`
  253. Keyword2 string `description:"模板消息keyword2字段"`
  254. Keyword3 string `description:"模板消息keyword3字段"`
  255. Keyword4 string `description:"模板消息keyword4字段"`
  256. Remark string `description:"模板消息remark字段"`
  257. TemplateId string `description:"模板id"`
  258. RedirectUrl string `description:"跳转地址"`
  259. RedirectTarget int `description:"小程序跳转目标:1:弘则研报小程序,2:随手办公小程序"`
  260. Resource string `description:"资源唯一标识"`
  261. SendType int `description:"发送的消息类型:1:报告,2:指标更新提醒,3:审批通知,4:销售领取客户通知,5:活动取消通知,6活动更改时间通知,7:关注的作者发布报告通知,8:发送日报(周报、双周报、月报)模板消息,9:活动预约/报名时间通知"`
  262. OpenIdArr []string `description:"消息接收者openid"`
  263. }
  264. // 推送模板消息
  265. func PublicSendTemplateMsg(sendInfo *SendWxTemplate) (err error) {
  266. postData, err := json.Marshal(sendInfo)
  267. if err != nil {
  268. utils.SendAlarmMsg("SendTemplateMsg json.Marshal Err:"+err.Error(), 1)
  269. return err
  270. }
  271. body := ioutil.NopCloser(strings.NewReader(string(postData)))
  272. client := &http.Client{}
  273. req, err := http.NewRequest("POST", utils.SendWxTemplateMsgUrl, body)
  274. if err != nil {
  275. utils.SendAlarmMsg("SendTemplateMsg http.NewRequest Err:"+err.Error(), 1)
  276. return err
  277. }
  278. contentType := "application/json;charset=utf-8"
  279. req.Header.Set("Content-Type", contentType)
  280. req.Header.Set("Authorization", utils.SendTemplateMsgAuthorization)
  281. resp, err := client.Do(req)
  282. if err != nil {
  283. fmt.Println("http client.Do Err:" + err.Error())
  284. return err
  285. }
  286. defer resp.Body.Close()
  287. b, err := ioutil.ReadAll(resp.Body)
  288. if err != nil {
  289. return err
  290. }
  291. result := new(models.BaseResponse)
  292. err = json.Unmarshal(b, &result)
  293. if err != nil {
  294. return err
  295. }
  296. if result.Ret != 200 {
  297. err = errors.New(string(b))
  298. return err
  299. }
  300. return
  301. }