wechat_send_msg.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. package services
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "hongze/hongze_mobile_admin/models/tables/admin"
  7. "hongze/hongze_mobile_admin/models/tables/user_template_record"
  8. "hongze/hongze_mobile_admin/models/tables/wx_user"
  9. "hongze/hongze_mobile_admin/services/alarm_msg"
  10. "hongze/hongze_mobile_admin/utils"
  11. "io/ioutil"
  12. "net/http"
  13. "time"
  14. )
  15. func sendTemplateMsg(sendUrl string, sendMap map[string]interface{}, items []*wx_user.OpenIdList, resource string, sendType int) (err error) {
  16. for _, v := range items {
  17. sendMap["touser"] = v.OpenId
  18. data, err := json.Marshal(sendMap)
  19. if err != nil {
  20. fmt.Println("SendTemplateMsgOne Marshal Err:", err.Error())
  21. utils.FileLog.Info(fmt.Sprintf("SendTemplateMsgOne Marshal Err:%s", err.Error()))
  22. return err
  23. }
  24. err = toSendTemplateMsg(sendUrl, data, resource, sendType, v)
  25. if err != nil {
  26. fmt.Println("send err:", err.Error())
  27. utils.FileLog.Info(fmt.Sprintf("ToSendTemplateMsg Err:%s", err.Error()))
  28. }
  29. }
  30. return
  31. }
  32. func toSendTemplateMsg(sendUrl string, data []byte, resource string, sendType int, dataItem *wx_user.OpenIdList) (err error) {
  33. utils.FileLog.Info("Send:" + string(data))
  34. client := http.Client{}
  35. resp, err := client.Post(sendUrl, "application/json", bytes.NewBuffer(data))
  36. if err != nil {
  37. return
  38. }
  39. defer resp.Body.Close()
  40. body, _ := ioutil.ReadAll(resp.Body)
  41. utils.FileLog.Info("SendResult:" + string(body))
  42. var templateResponse SendTemplateResponse
  43. err = json.Unmarshal(body, &templateResponse)
  44. if err != nil {
  45. utils.FileLog.Info("SendResult Unmarshal Err:%s", err.Error())
  46. return err
  47. }
  48. //新增模板消息推送记录
  49. {
  50. sendStatus := 0
  51. if templateResponse.Errcode == 0 {
  52. sendStatus = 1
  53. } else {
  54. sendStatus = 0
  55. }
  56. tr := &user_template_record.UserTemplateRecord{
  57. Id: 0,
  58. UserId: dataItem.UserId,
  59. OpenId: dataItem.OpenId,
  60. Resource: resource,
  61. SendData: string(data),
  62. Result: string(body),
  63. CreateDate: time.Now().Format(utils.FormatDate),
  64. CreateTime: time.Now().Format(utils.FormatDateTime),
  65. SendStatus: sendStatus,
  66. SendType: sendType,
  67. }
  68. go func() {
  69. err = user_template_record.AddUserTemplateRecord(tr)
  70. if err != nil {
  71. utils.FileLog.Info(fmt.Sprintf("AddUserTemplateRecord Err:%s", err.Error()))
  72. }
  73. }()
  74. }
  75. return
  76. }
  77. type SendTemplateResponse struct {
  78. Errcode int `json:"errcode"`
  79. Errmsg string `json:"errmsg"`
  80. MsgID int `json:"msgid"`
  81. }
  82. // SendCompanyApplyWxTemplateMsg 发送待办消息
  83. func SendCompanyApplyWxTemplateMsg(mobile, redirectUrl, wxAppPath string, wxMsgMap map[int]string) (err error) {
  84. var msg string
  85. defer func() {
  86. if err != nil {
  87. go alarm_msg.SendAlarmMsg(fmt.Sprintf("发送模版消息失败,Err:%s,%s", err.Error(), msg), 3)
  88. //go utils.SendEmail("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  89. utils.FileLog.Info("发送模版消息失败,Err:%s,%s", err.Error(), msg)
  90. }
  91. if msg != "" {
  92. utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
  93. }
  94. }()
  95. utils.FileLog.Info("%s", "services SendMsg")
  96. accessToken, err := WxGetRedisAccessToken(utils.AdminWxAppId, utils.AdminWxAppSecret)
  97. if err != nil {
  98. msg = "GetWxAccessToken Err:" + err.Error()
  99. return
  100. }
  101. if accessToken == "" {
  102. msg = "accessToken is empty"
  103. return
  104. }
  105. utils.FileLog.Info("mobile:%s", mobile)
  106. //获取openid列表
  107. openIdStr := WxAdminOpenIdGet()
  108. adminOpenIdList, err := admin.GetOpenIdListByMobile(mobile, openIdStr)
  109. if err != nil {
  110. msg = "get openIdList err:" + err.Error()
  111. return
  112. }
  113. openIdList := make([]*wx_user.OpenIdList, 0)
  114. for _, v := range adminOpenIdList {
  115. tmp := new(wx_user.OpenIdList)
  116. tmp.OpenId = v.OpenId
  117. openIdList = append(openIdList, tmp)
  118. }
  119. utils.FileLog.Info("openIdListCount:%s", len(openIdList))
  120. //fmt.Println("openIdListCount:", len(openIdList))
  121. if len(openIdList) > 0 && utils.TemplateIdByCompanyApply != "" {
  122. utils.FileLog.Info("start send")
  123. sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  124. fmt.Println("send start")
  125. utils.FileLog.Info("send start")
  126. sendMap := make(map[string]interface{})
  127. sendData := make(map[string]interface{})
  128. var first, keyword1, keyword2, keyword3, remark string
  129. if tmpStr, ok := wxMsgMap[0]; ok {
  130. first = tmpStr
  131. } else {
  132. first = "Hi,有新的订单需要审批"
  133. }
  134. if tmpStr, ok := wxMsgMap[1]; ok {
  135. keyword1 = tmpStr
  136. }
  137. if tmpStr, ok := wxMsgMap[2]; ok {
  138. keyword2 = tmpStr
  139. }
  140. if tmpStr, ok := wxMsgMap[3]; ok {
  141. keyword3 = tmpStr
  142. }
  143. if tmpStr, ok := wxMsgMap[4]; ok {
  144. remark = tmpStr
  145. }
  146. sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  147. sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  148. sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  149. sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
  150. sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
  151. sendMap["template_id"] = utils.TemplateIdByCompanyApply
  152. sendMap["url"] = redirectUrl
  153. sendMap["data"] = sendData
  154. //小程序信息
  155. if wxAppPath != "" {
  156. sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId2, "pagepath": wxAppPath}
  157. }
  158. sendTemplateMsg(sendUrl, sendMap, openIdList, mobile, utils.TEMPLATE_MSG_APPLY)
  159. }
  160. utils.FileLog.Info("send end")
  161. return
  162. }
  163. // SendWxMsgWithRoadshowDetailResult 路演->销售收到处理结果
  164. func SendWxMsgWithRoadshowDetailResult(first, keyword1, keyword2, remark, mobile, redirectUrl, wxAppPath string) (err error) {
  165. var msg string
  166. defer func() {
  167. if err != nil {
  168. go alarm_msg.SendAlarmMsg(fmt.Sprintf("发送模版消息失败,Err:%s,%s", err.Error(), msg), 3)
  169. //go utils.SendEmail("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  170. utils.FileLog.Info("发送模版消息失败,Err:%s,%s", err.Error(), msg)
  171. }
  172. if msg != "" {
  173. utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
  174. }
  175. }()
  176. utils.FileLog.Info("%s", "services SendMsg")
  177. accessToken, err := WxGetRedisAccessToken(utils.AdminWxAppId, utils.AdminWxAppSecret)
  178. if err != nil {
  179. msg = "GetWxAccessToken Err:" + err.Error()
  180. return
  181. }
  182. if accessToken == "" {
  183. msg = "accessToken is empty"
  184. return
  185. }
  186. utils.FileLog.Info("mobile:%s", mobile)
  187. //获取openid列表
  188. openIdStr := WxAdminOpenIdGet()
  189. adminOpenIdList, err := admin.GetOpenIdListByMobile(mobile, openIdStr)
  190. if err != nil {
  191. msg = "get openIdList err:" + err.Error()
  192. return
  193. }
  194. openIdList := make([]*wx_user.OpenIdList, 0)
  195. for _, v := range adminOpenIdList {
  196. tmp := new(wx_user.OpenIdList)
  197. tmp.OpenId = v.OpenId
  198. openIdList = append(openIdList, tmp)
  199. }
  200. utils.FileLog.Info("openIdListCount:%s", len(openIdList))
  201. //fmt.Println("openIdListCount:", len(openIdList))
  202. if len(openIdList) > 0 && utils.TemplateIdByCompanyApply != "" {
  203. utils.FileLog.Info("start send")
  204. sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  205. fmt.Println("send start")
  206. utils.FileLog.Info("send start")
  207. sendMap := make(map[string]interface{})
  208. sendData := make(map[string]interface{})
  209. sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  210. sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  211. sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  212. sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
  213. sendMap["template_id"] = utils.WxMsgTemplateIdWithRoadshowDetailResult
  214. sendMap["url"] = redirectUrl
  215. sendMap["data"] = sendData
  216. //小程序信息
  217. if wxAppPath != "" {
  218. sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId2, "pagepath": wxAppPath}
  219. }
  220. sendTemplateMsg(sendUrl, sendMap, openIdList, wxAppPath, utils.TEMPLATE_MSG_ACTIVITY_APPOINTMENT)
  221. }
  222. utils.FileLog.Info("send end")
  223. return
  224. }
  225. // SendWxMsgWithRoadshowPending 路演->研究员收到待处理的申请
  226. func SendWxMsgWithRoadshowPending(first, keyword1, keyword2, keyword3, keyword4, remark, wxAppPath, mobile string) (err error) {
  227. //utils.WxMsgTemplateIdWithRoadshowPending
  228. var msg string
  229. defer func() {
  230. if err != nil {
  231. //go utils.SendEmail("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  232. go alarm_msg.SendAlarmMsg("发送模版消息失败,Err:"+err.Error()+msg, 3)
  233. utils.FileLog.Info("发送模版消息失败,Err:" + err.Error() + msg)
  234. }
  235. if msg != "" {
  236. utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
  237. }
  238. }()
  239. utils.FileLog.Info("%s", "services SendMsg")
  240. accessToken, err := WxGetRedisAccessToken(utils.AdminWxAppId, utils.AdminWxAppSecret)
  241. if err != nil {
  242. msg = "GetWxAccessToken Err:" + err.Error()
  243. return
  244. }
  245. if accessToken == "" {
  246. msg = "accessToken is empty"
  247. return
  248. }
  249. //获取openid列表
  250. openIdStr := WxAdminOpenIdGet()
  251. adminOpenIdList, err := admin.GetOpenIdListByMobile(mobile, openIdStr)
  252. if err != nil {
  253. msg = "get openIdList err:" + err.Error()
  254. return
  255. }
  256. openIdList := make([]*wx_user.OpenIdList, 0)
  257. for _, v := range adminOpenIdList {
  258. tmp := new(wx_user.OpenIdList)
  259. tmp.OpenId = v.OpenId
  260. openIdList = append(openIdList, tmp)
  261. }
  262. utils.FileLog.Info("openIdListCount:%s", len(openIdList))
  263. //fmt.Println("openIdListCount:", len(openIdList))
  264. if len(openIdList) > 0 && utils.TemplateIdByCompanyApply != "" {
  265. utils.FileLog.Info("start send")
  266. sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  267. fmt.Println("send start")
  268. utils.FileLog.Info("send start")
  269. sendMap := make(map[string]interface{})
  270. sendData := make(map[string]interface{})
  271. sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  272. sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  273. sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  274. sendData["keyword3"] = map[string]interface{}{"value": keyword3, "color": "#173177"}
  275. sendData["keyword4"] = map[string]interface{}{"value": keyword4, "color": "#173177"}
  276. sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
  277. sendMap["template_id"] = utils.WxMsgTemplateIdWithRoadshowPending
  278. sendMap["data"] = sendData
  279. //小程序信息
  280. if wxAppPath != "" {
  281. sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId2, "pagepath": wxAppPath}
  282. }
  283. sendTemplateMsg(sendUrl, sendMap, openIdList, wxAppPath, utils.TEMPLATE_MSG_ACTIVITY_APPOINTMENT)
  284. }
  285. utils.FileLog.Info("send end")
  286. return
  287. }
  288. // SendWxMsgWithRoadshowDeleteNotice 路演->研究员收到活动删除通知
  289. func SendWxMsgWithRoadshowDeleteNotice(first, keyword1, keyword2, remark, wxAppPath, mobile string) (err error) {
  290. var msg string
  291. defer func() {
  292. if err != nil {
  293. //go utils.SendEmail("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05"), msg+";Err:"+err.Error(), utils.EmailSendToUsers)
  294. go alarm_msg.SendAlarmMsg("发送模版消息失败"+time.Now().Format("2006-01-02 15:04:05")+";Msg:"+msg+";Err:"+err.Error(), 3)
  295. utils.FileLog.Info("发送模版消息失败,Err:%s,%s", err.Error(), msg)
  296. }
  297. if msg != "" {
  298. utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
  299. }
  300. }()
  301. utils.FileLog.Info("%s", "services SendMsg")
  302. accessToken, err := WxGetRedisAccessToken(utils.AdminWxAppId, utils.AdminWxAppSecret)
  303. if err != nil {
  304. msg = "GetWxAccessToken Err:" + err.Error()
  305. return
  306. }
  307. if accessToken == "" {
  308. msg = "accessToken is empty"
  309. return
  310. }
  311. //获取openid列表
  312. openIdStr := WxAdminOpenIdGet()
  313. adminOpenIdList, err := admin.GetOpenIdListByMobile(mobile, openIdStr)
  314. if err != nil {
  315. msg = "get openIdList err:" + err.Error()
  316. return
  317. }
  318. openIdList := make([]*wx_user.OpenIdList, 0)
  319. for _, v := range adminOpenIdList {
  320. tmp := new(wx_user.OpenIdList)
  321. tmp.OpenId = v.OpenId
  322. openIdList = append(openIdList, tmp)
  323. }
  324. utils.FileLog.Info("openIdListCount:%s", len(openIdList))
  325. //fmt.Println("openIdListCount:", len(openIdList))
  326. if len(openIdList) > 0 && utils.TemplateIdByCompanyApply != "" {
  327. utils.FileLog.Info("start send")
  328. sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  329. sendMap := make(map[string]interface{})
  330. sendData := make(map[string]interface{})
  331. sendMap["template_id"] = utils.WxMsgTemplateIdWithRoadshowDeleteNotice
  332. sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  333. sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  334. sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  335. sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
  336. //小程序信息
  337. if wxAppPath != "" {
  338. sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId2, "pagepath": wxAppPath}
  339. }
  340. sendMap["data"] = sendData
  341. sendTemplateMsg(sendUrl, sendMap, openIdList, wxAppPath, utils.TEMPLATE_MSG_ACTIVITY_APPOINTMENT)
  342. }
  343. utils.FileLog.Info("send end")
  344. return
  345. }
  346. // SendSealFinishedWxTemplateMsg 给销售发送 用印申请已签回的模版消息
  347. func SendSealFinishedWxTemplateMsg(mobile string, companyName string, sealId int) (err error) {
  348. var msg string
  349. defer func() {
  350. if err != nil {
  351. fmt.Println("err:", err)
  352. go alarm_msg.SendAlarmMsg("发送模版消息失败,Err:"+err.Error()+";msg:"+msg, 3)
  353. utils.FileLog.Info(fmt.Sprintf("发送模版消息失败,Err:%s,%s", err.Error(), msg))
  354. }
  355. if msg != "" {
  356. utils.FileLog.Info("发送模版消息失败,msg:%s", msg)
  357. }
  358. }()
  359. utils.FileLog.Info("%s", "services SendMsg")
  360. accessToken, err := WxGetRedisAccessToken(utils.AdminWxAppId, utils.AdminWxAppSecret)
  361. if err != nil {
  362. msg = "GetWxAccessToken Err:" + err.Error()
  363. return
  364. }
  365. if accessToken == "" {
  366. msg = "accessToken is empty"
  367. return
  368. }
  369. utils.FileLog.Info("mobile:%s", mobile)
  370. openIdStr := WxAdminOpenIdGet()
  371. adminOpenIdList, err := admin.GetOpenIdListByMobile(mobile, openIdStr)
  372. if err != nil {
  373. msg = "get openIdList err:" + err.Error()
  374. return
  375. }
  376. openIdList := make([]*wx_user.OpenIdList, 0)
  377. for _, v := range adminOpenIdList {
  378. tmp := new(wx_user.OpenIdList)
  379. tmp.OpenId = v.OpenId
  380. openIdList = append(openIdList, tmp)
  381. }
  382. utils.FileLog.Info("openIdListCount:%s", len(openIdList))
  383. if len(openIdList) > 0 && utils.WxMsgTemplateIdWithSealApplyFinished != "" {
  384. utils.FileLog.Info("start send")
  385. sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  386. fmt.Println("send start")
  387. utils.FileLog.Info("send start")
  388. sendMap := make(map[string]interface{})
  389. sendData := make(map[string]interface{})
  390. first := "您的用印申请已签回,可前往提交转正/续约申请"
  391. keyword1 := companyName
  392. keyword2 := "已签回"
  393. remark := "点击查看用印详情"
  394. sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  395. sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  396. sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  397. sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
  398. sendMap["template_id"] = utils.WxMsgTemplateIdWithSealApplyFinished
  399. sendMap["url"] = "" //跳转地址
  400. sendMap["data"] = sendData
  401. // TODO 随手办公小程序的跳转地址
  402. wxAppPath := fmt.Sprintf("pages-approve/seal/detail?SealId=%d", sealId)
  403. sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxAppId2, "pagepath": wxAppPath}
  404. err = sendTemplateMsg(sendUrl, sendMap, openIdList, wxAppPath, utils.TEMPLATE_MSG_SEAL_FINISHED)
  405. }
  406. utils.FileLog.Info("send end")
  407. return
  408. }
  409. // SendYbQuestionDistributeWxMsg 推送研报小程序模板消息-问答社区分配
  410. func SendYbQuestionDistributeWxMsg(questionId, userId int, openid, questionTitle string) (err error) {
  411. var errMsg string
  412. defer func() {
  413. if err != nil {
  414. alarmMsg := fmt.Sprintf("SendMiniProgramReportWxMsg-推送问答社区分配模版消息失败; QuestionId: %d; Err: %s; Msg: %s", questionId, err.Error(), errMsg)
  415. utils.FileLog.Error(alarmMsg)
  416. go alarm_msg.SendAlarmMsg(alarmMsg, 3)
  417. }
  418. }()
  419. // todo 修改openID
  420. accessToken, err := WxGetRedisAccessToken(utils.AdminWxAppId, utils.AdminWxAppSecret)
  421. if err != nil {
  422. errMsg = "GetWxAccessToken Err:" + err.Error()
  423. return
  424. }
  425. if accessToken == "" {
  426. errMsg = "accessToken is empty"
  427. return
  428. }
  429. openIdList := make([]*wx_user.OpenIdList, 0)
  430. openIdList = append(openIdList, &wx_user.OpenIdList{
  431. OpenId: openid,
  432. UserId: userId,
  433. })
  434. sendUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
  435. sendMap := make(map[string]interface{})
  436. sendData := make(map[string]interface{})
  437. first := "您好,有新的提问待回复"
  438. keyword1 := questionTitle
  439. keyword2 := "待回复"
  440. remark := "请点击详情尽快处理"
  441. sendData["first"] = map[string]interface{}{"value": first, "color": "#173177"}
  442. sendData["keyword1"] = map[string]interface{}{"value": keyword1, "color": "#173177"}
  443. sendData["keyword2"] = map[string]interface{}{"value": keyword2, "color": "#173177"}
  444. sendData["remark"] = map[string]interface{}{"value": remark, "color": "#173177"}
  445. sendMap["template_id"] = utils.WxMsgTemplateIdWithYbCommunityQuestion
  446. sendMap["data"] = sendData
  447. wxAppPath := fmt.Sprintf("pages-question/answerDetail?id=%d", questionId)
  448. if wxAppPath != "" {
  449. sendMap["miniprogram"] = map[string]interface{}{"appid": utils.WxYbAppId, "pagepath": wxAppPath}
  450. }
  451. err = sendTemplateMsg(sendUrl, sendMap, openIdList, wxAppPath, utils.TEMPLATE_MSG_YB_COMMUNITY_QUESTION)
  452. return
  453. }