附近小店
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 

678 řádky
22 KiB

  1. package weapp
  2. import (
  3. "encoding/base64"
  4. "encoding/binary"
  5. "encoding/json"
  6. "encoding/xml"
  7. "errors"
  8. "fmt"
  9. "io"
  10. "io/ioutil"
  11. "net/http"
  12. "reflect"
  13. "strconv"
  14. "strings"
  15. "time"
  16. )
  17. // MsgType 消息类型
  18. type MsgType = string
  19. // 所有消息类型
  20. const (
  21. MsgText MsgType = "text" // 文本消息类型
  22. MsgImg = "image" // 图片消息类型
  23. MsgCard = "miniprogrampage" // 小程序卡片消息类型
  24. MsgEvent = "event" // 事件类型
  25. MsgTrans = "transfer_customer_service" // 转发客服消息
  26. )
  27. // EventType 事件类型
  28. type EventType string
  29. // 所有事件类型
  30. const (
  31. EventQuotaGet EventType = "get_quota" // 查询商户余额
  32. EventCheckBusiness = "check_biz" // 取消订单事件
  33. EventMediaCheckAsync = "wxa_media_check" // 异步校验图片/音频
  34. EventAddExpressOrder = "add_waybill" // 请求下单事件
  35. EventExpressPathUpdate = "add_express_path" // 运单轨迹更新事件
  36. EventExpressOrderCancel = "cancel_waybill" // 审核商户事件
  37. EventUserTempsessionEnter = "user_enter_tempsession" // 用户进入临时会话状态
  38. EventNearbyPoiAuditInfoAdd = "add_nearby_poi_audit_info" // 附近小程序添加地点审核状态通知
  39. EventDeliveryOrderStatusUpdate = "update_waybill_status" // 配送单配送状态更新通知
  40. EventAgentPosQuery = "transport_get_agent_pos" // 查询骑手当前位置信息
  41. EventAuthInfoGet = "get_auth_info" // 使用授权码拉取授权信息
  42. EventAuthAccountCancel = "cancel_auth_account" // 取消授权帐号
  43. EventDeliveryOrderAdd = "transport_add_order" // 真实发起下单任务
  44. EventDeliveryOrderTipsAdd = "transport_add_tips" // 对待接单状态的订单增加小费
  45. EventDeliveryOrderCancel = "transport_cancel_order" // 取消订单操作
  46. EventDeliveryOrderReturnConfirm = "transport_confirm_return_to_biz" // 异常妥投商户收货确认
  47. EventDeliveryOrderPreAdd = "transport_precreate_order" // 预下单
  48. EventDeliveryOrderPreCancel = "transport_precancel_order" // 预取消订单
  49. EventDeliveryOrderQuery = "transport_query_order_status" // 查询订单状态
  50. EventDeliveryOrderReadd = "transport_readd_order" // 下单
  51. EventPreAuthCodeGet = "get_pre_auth_code" // 获取预授权码
  52. EventRiderScoreSet = "transport_set_rider_score" // 给骑手评分
  53. )
  54. // Server 微信通知服务处理器
  55. type Server struct {
  56. appID string // 小程序 ID
  57. mchID string // 商户号
  58. apiKey string // 商户签名密钥
  59. token string // 微信服务器验证令牌
  60. aesKey []byte // base64 解码后的消息加密密钥
  61. validate bool // 是否验证请求来自微信服务器
  62. textMessageHandler func(*TextMessageResult) *TransferCustomerMessage
  63. imageMessageHandler func(*ImageMessageResult) *TransferCustomerMessage
  64. cardMessageHandler func(*CardMessageResult) *TransferCustomerMessage
  65. userTempsessionEnterHandler func(*UserTempsessionEnterResult)
  66. mediaCheckAsyncHandler func(*MediaCheckAsyncResult)
  67. expressPathUpdateHandler func(*ExpressPathUpdateResult)
  68. addNearbyPoiAuditHandler func(*AddNearbyPoiResult)
  69. addExpressOrderHandler func(*AddExpressOrderResult) *AddExpressOrderReturn
  70. expressOrderCancelHandler func(*CancelExpressOrderResult) *CancelExpressOrderReturn
  71. checkExpressBusinessHandler func(*CheckExpressBusinessResult) *CheckExpressBusinessReturn
  72. quotaGetHandler func(*GetExpressQuotaResult) *GetExpressQuotaReturn
  73. deliveryOrderStatusUpdateHandler func(*DeliveryOrderStatusUpdateResult) *DeliveryOrderStatusUpdateReturn
  74. agentPosQueryHandler func(*AgentPosQueryResult) *AgentPosQueryReturn
  75. authInfoGetHandler func(*AuthInfoGetResult) *AuthInfoGetReturn
  76. authAccountCancelHandler func(*CancelAuthResult) *CancelAuthReturn
  77. deliveryOrderAddHandler func(*DeliveryOrderAddResult) *DeliveryOrderAddReturn
  78. deliveryOrderTipsAddHandler func(*DeliveryOrderAddTipsResult) *DeliveryOrderAddTipsReturn
  79. deliveryOrderCancelHandler func(*DeliveryOrderCancelResult) *DeliveryOrderCancelReturn
  80. deliveryOrderReturnConfirmHandler func(*DeliveryOrderReturnConfirmResult) *DeliveryOrderReturnConfirmReturn
  81. deliveryOrderPreAddHandler func(*DeliveryOrderPreAddResult) *DeliveryOrderPreAddReturn
  82. deliveryOrderPreCancelHandler func(*DeliveryOrderPreCancelResult) *DeliveryOrderPreCancelReturn
  83. deliveryOrderQueryHandler func(*DeliveryOrderQueryResult) *DeliveryOrderQueryReturn
  84. deliveryOrderReaddHandler func(*DeliveryOrderReaddResult) *DeliveryOrderReaddReturn
  85. preAuthCodeGetHandler func(*PreAuthCodeGetResult) *PreAuthCodeGetReturn
  86. riderScoreSetHandler func(*RiderScoreSetResult) *RiderScoreSetReturn
  87. }
  88. // OnCustomerServiceTextMessage add handler to handle customer text service message.
  89. func (srv *Server) OnCustomerServiceTextMessage(fn func(*TextMessageResult) *TransferCustomerMessage) {
  90. srv.textMessageHandler = fn
  91. }
  92. // OnCustomerServiceImageMessage add handler to handle customer image service message.
  93. func (srv *Server) OnCustomerServiceImageMessage(fn func(*ImageMessageResult) *TransferCustomerMessage) {
  94. srv.imageMessageHandler = fn
  95. }
  96. // OnCustomerServiceCardMessage add handler to handle customer card service message.
  97. func (srv *Server) OnCustomerServiceCardMessage(fn func(*CardMessageResult) *TransferCustomerMessage) {
  98. srv.cardMessageHandler = fn
  99. }
  100. // OnUserTempsessionEnter add handler to handle customer service message.
  101. func (srv *Server) OnUserTempsessionEnter(fn func(*UserTempsessionEnterResult)) {
  102. srv.userTempsessionEnterHandler = fn
  103. }
  104. // OnMediaCheckAsync add handler to handle MediaCheckAsync.
  105. func (srv *Server) OnMediaCheckAsync(fn func(*MediaCheckAsyncResult)) {
  106. srv.mediaCheckAsyncHandler = fn
  107. }
  108. // OnExpressPathUpdate add handler to handle ExpressPathUpdate.
  109. func (srv *Server) OnExpressPathUpdate(fn func(*ExpressPathUpdateResult)) {
  110. srv.expressPathUpdateHandler = fn
  111. }
  112. // OnAddNearbyPoi add handler to handle AddNearbyPoiAudit.
  113. func (srv *Server) OnAddNearbyPoi(fn func(*AddNearbyPoiResult)) {
  114. srv.addNearbyPoiAuditHandler = fn
  115. }
  116. // OnAddExpressOrder add handler to handle AddExpressOrder.
  117. func (srv *Server) OnAddExpressOrder(fn func(*AddExpressOrderResult) *AddExpressOrderReturn) {
  118. srv.addExpressOrderHandler = fn
  119. }
  120. // OnCheckExpressBusiness add handler to handle CheckBusiness.
  121. func (srv *Server) OnCheckExpressBusiness(fn func(*CheckExpressBusinessResult) *CheckExpressBusinessReturn) {
  122. srv.checkExpressBusinessHandler = fn
  123. }
  124. // OnCancelExpressOrder add handler to handle ExpressOrderCancel.
  125. func (srv *Server) OnCancelExpressOrder(fn func(*CancelExpressOrderResult) *CancelExpressOrderReturn) {
  126. srv.expressOrderCancelHandler = fn
  127. }
  128. // OnGetExpressQuota add handler to handle QuotaGet.
  129. func (srv *Server) OnGetExpressQuota(fn func(*GetExpressQuotaResult) *GetExpressQuotaReturn) {
  130. srv.quotaGetHandler = fn
  131. }
  132. // OnDeliveryOrderStatusUpdate add handler to handle DeliveryOrderStatusUpdate.
  133. // OnDeliveryOrderStatusUpdate add handler to handle deliveryOrderStatusUpdate.
  134. func (srv *Server) OnDeliveryOrderStatusUpdate(fn func(*DeliveryOrderStatusUpdateResult) *DeliveryOrderStatusUpdateReturn) {
  135. srv.deliveryOrderStatusUpdateHandler = fn
  136. }
  137. // OnAgentPosQuery add handler to handle AgentPosQuery.
  138. func (srv *Server) OnAgentPosQuery(fn func(*AgentPosQueryResult) *AgentPosQueryReturn) {
  139. srv.agentPosQueryHandler = fn
  140. }
  141. // OnAuthInfoGet add handler to handle AuthInfoGet.
  142. func (srv *Server) OnAuthInfoGet(fn func(*AuthInfoGetResult) *AuthInfoGetReturn) {
  143. srv.authInfoGetHandler = fn
  144. }
  145. // OnCancelAuth add handler to handle deliveryOrderStatusUpdate.
  146. func (srv *Server) OnCancelAuth(fn func(*CancelAuthResult) *CancelAuthReturn) {
  147. srv.authAccountCancelHandler = fn
  148. }
  149. // OnDeliveryOrderAdd add handler to handle deliveryOrderStatusUpdate.
  150. func (srv *Server) OnDeliveryOrderAdd(fn func(*DeliveryOrderAddResult) *DeliveryOrderAddReturn) {
  151. srv.deliveryOrderAddHandler = fn
  152. }
  153. // OnDeliveryOrderAddTips add handler to handle deliveryOrderStatusUpdate.
  154. func (srv *Server) OnDeliveryOrderAddTips(fn func(*DeliveryOrderAddTipsResult) *DeliveryOrderAddTipsReturn) {
  155. srv.deliveryOrderTipsAddHandler = fn
  156. }
  157. // OnDeliveryOrderCancel add handler to handle deliveryOrderStatusUpdate.
  158. func (srv *Server) OnDeliveryOrderCancel(fn func(*DeliveryOrderCancelResult) *DeliveryOrderCancelReturn) {
  159. srv.deliveryOrderCancelHandler = fn
  160. }
  161. // OnDeliveryOrderReturnConfirm add handler to handle deliveryOrderStatusUpdate.
  162. func (srv *Server) OnDeliveryOrderReturnConfirm(fn func(*DeliveryOrderReturnConfirmResult) *DeliveryOrderReturnConfirmReturn) {
  163. srv.deliveryOrderReturnConfirmHandler = fn
  164. }
  165. // OnDeliveryOrderPreAdd add handler to handle deliveryOrderStatusUpdate.
  166. func (srv *Server) OnDeliveryOrderPreAdd(fn func(*DeliveryOrderPreAddResult) *DeliveryOrderPreAddReturn) {
  167. srv.deliveryOrderPreAddHandler = fn
  168. }
  169. // OnDeliveryOrderPreCancel add handler to handle deliveryOrderStatusUpdate.
  170. func (srv *Server) OnDeliveryOrderPreCancel(fn func(*DeliveryOrderPreCancelResult) *DeliveryOrderPreCancelReturn) {
  171. srv.deliveryOrderPreCancelHandler = fn
  172. }
  173. // OnDeliveryOrderQuery add handler to handle deliveryOrderStatusUpdate.
  174. func (srv *Server) OnDeliveryOrderQuery(fn func(*DeliveryOrderQueryResult) *DeliveryOrderQueryReturn) {
  175. srv.deliveryOrderQueryHandler = fn
  176. }
  177. // OnDeliveryOrderReadd add handler to handle deliveryOrderStatusUpdate.
  178. func (srv *Server) OnDeliveryOrderReadd(fn func(*DeliveryOrderReaddResult) *DeliveryOrderReaddReturn) {
  179. srv.deliveryOrderReaddHandler = fn
  180. }
  181. // OnPreAuthCodeGet add handler to handle preAuthCodeGet.
  182. func (srv *Server) OnPreAuthCodeGet(fn func(*PreAuthCodeGetResult) *PreAuthCodeGetReturn) {
  183. srv.preAuthCodeGetHandler = fn
  184. }
  185. // OnRiderScoreSet add handler to handle riderScoreSet.
  186. func (srv *Server) OnRiderScoreSet(fn func(*RiderScoreSetResult) *RiderScoreSetReturn) {
  187. srv.riderScoreSetHandler = fn
  188. }
  189. type dataType = string
  190. const (
  191. dataTypeJSON dataType = "application/json"
  192. dataTypeXML = "text/xml"
  193. )
  194. // NewServer 返回经过初始化的Server
  195. func NewServer(appID, token, aesKey, mchID, apiKey string, validate bool) (*Server, error) {
  196. key, err := base64.RawStdEncoding.DecodeString(aesKey)
  197. if err != nil {
  198. return nil, err
  199. }
  200. server := Server{
  201. appID: appID,
  202. mchID: mchID,
  203. apiKey: apiKey,
  204. token: token,
  205. aesKey: key,
  206. validate: validate,
  207. }
  208. return &server, nil
  209. }
  210. func getDataType(req *http.Request) dataType {
  211. content := req.Header.Get("Content-Type")
  212. switch {
  213. case strings.Contains(content, dataTypeJSON):
  214. return dataTypeJSON
  215. case strings.Contains(content, dataTypeXML):
  216. return dataTypeXML
  217. default:
  218. return content
  219. }
  220. }
  221. func unmarshal(data []byte, tp dataType, v interface{}) error {
  222. switch tp {
  223. case dataTypeJSON:
  224. if err := json.Unmarshal(data, v); err != nil {
  225. return err
  226. }
  227. case dataTypeXML:
  228. if err := xml.Unmarshal(data, v); err != nil {
  229. return err
  230. }
  231. default:
  232. return errors.New("invalid content type: " + tp)
  233. }
  234. return nil
  235. }
  236. func marshal(data interface{}, tp dataType) ([]byte, error) {
  237. switch tp {
  238. case dataTypeJSON:
  239. return json.Marshal(data)
  240. case dataTypeXML:
  241. return xml.Marshal(data)
  242. default:
  243. return nil, errors.New("invalid content type: " + tp)
  244. }
  245. }
  246. // 处理消息体
  247. func (srv *Server) handleRequest(w http.ResponseWriter, r *http.Request, isEncrpt bool, tp dataType) (interface{}, error) {
  248. raw, err := ioutil.ReadAll(r.Body)
  249. if err != nil {
  250. return nil, err
  251. }
  252. if isEncrpt { // 处理加密消息
  253. query := r.URL.Query()
  254. nonce, signature, timestamp := query.Get("nonce"), query.Get("signature"), query.Get("timestamp")
  255. // 检验消息是否来自微信服务器
  256. if !validateSignature(signature, srv.token, timestamp, nonce) {
  257. return nil, errors.New("failed to validate signature")
  258. }
  259. res := new(EncryptedResult)
  260. if err := unmarshal(raw, tp, res); err != nil {
  261. return nil, err
  262. }
  263. body, err := srv.decryptMsg(res.Encrypt)
  264. if err != nil {
  265. return nil, err
  266. }
  267. length := binary.BigEndian.Uint32(body[16:20])
  268. raw = body[20 : 20+length]
  269. }
  270. res := new(CommonServerResult)
  271. if err := unmarshal(raw, tp, res); err != nil {
  272. return nil, err
  273. }
  274. switch res.MsgType {
  275. case MsgText:
  276. msg := new(TextMessageResult)
  277. if err := unmarshal(raw, tp, msg); err != nil {
  278. return nil, err
  279. }
  280. if srv.textMessageHandler != nil {
  281. return srv.textMessageHandler(msg), nil
  282. }
  283. case MsgImg:
  284. msg := new(ImageMessageResult)
  285. if err := unmarshal(raw, tp, msg); err != nil {
  286. return nil, err
  287. }
  288. if srv.imageMessageHandler != nil {
  289. return srv.imageMessageHandler(msg), nil
  290. }
  291. case MsgCard:
  292. msg := new(CardMessageResult)
  293. if err := unmarshal(raw, tp, msg); err != nil {
  294. return nil, err
  295. }
  296. if srv.cardMessageHandler != nil {
  297. return srv.cardMessageHandler(msg), nil
  298. }
  299. case MsgEvent:
  300. switch res.Event {
  301. case EventUserTempsessionEnter:
  302. msg := new(UserTempsessionEnterResult)
  303. if err := unmarshal(raw, tp, msg); err != nil {
  304. return nil, err
  305. }
  306. if srv.userTempsessionEnterHandler != nil {
  307. srv.userTempsessionEnterHandler(msg)
  308. }
  309. case EventQuotaGet:
  310. msg := new(GetExpressQuotaResult)
  311. if err := unmarshal(raw, tp, msg); err != nil {
  312. return nil, err
  313. }
  314. if srv.quotaGetHandler != nil {
  315. return srv.quotaGetHandler(msg), nil
  316. }
  317. case EventMediaCheckAsync:
  318. msg := new(MediaCheckAsyncResult)
  319. if err := unmarshal(raw, tp, msg); err != nil {
  320. return nil, err
  321. }
  322. if srv.mediaCheckAsyncHandler != nil {
  323. srv.mediaCheckAsyncHandler(msg)
  324. }
  325. case EventAddExpressOrder:
  326. msg := new(AddExpressOrderResult)
  327. if err := unmarshal(raw, tp, msg); err != nil {
  328. return nil, err
  329. }
  330. if srv.addExpressOrderHandler != nil {
  331. return srv.addExpressOrderHandler(msg), nil
  332. }
  333. case EventExpressOrderCancel:
  334. msg := new(CancelExpressOrderResult)
  335. if err := unmarshal(raw, tp, msg); err != nil {
  336. return nil, err
  337. }
  338. if srv.expressOrderCancelHandler != nil {
  339. return srv.expressOrderCancelHandler(msg), nil
  340. }
  341. case EventCheckBusiness:
  342. msg := new(CheckExpressBusinessResult)
  343. if err := unmarshal(raw, tp, msg); err != nil {
  344. return nil, err
  345. }
  346. if srv.checkExpressBusinessHandler != nil {
  347. return srv.checkExpressBusinessHandler(msg), nil
  348. }
  349. case EventDeliveryOrderStatusUpdate:
  350. msg := new(DeliveryOrderStatusUpdateResult)
  351. if err := unmarshal(raw, tp, msg); err != nil {
  352. return nil, err
  353. }
  354. if srv.deliveryOrderStatusUpdateHandler != nil {
  355. return srv.deliveryOrderStatusUpdateHandler(msg), nil
  356. }
  357. case EventAgentPosQuery:
  358. msg := new(AgentPosQueryResult)
  359. if err := unmarshal(raw, tp, msg); err != nil {
  360. return nil, err
  361. }
  362. if srv.agentPosQueryHandler != nil {
  363. return srv.agentPosQueryHandler(msg), nil
  364. }
  365. case EventAuthInfoGet:
  366. msg := new(AuthInfoGetResult)
  367. if err := unmarshal(raw, tp, msg); err != nil {
  368. return nil, err
  369. }
  370. if srv.authInfoGetHandler != nil {
  371. return srv.authInfoGetHandler(msg), nil
  372. }
  373. case EventAuthAccountCancel:
  374. msg := new(CancelAuthResult)
  375. if err := unmarshal(raw, tp, msg); err != nil {
  376. return nil, err
  377. }
  378. if srv.authAccountCancelHandler != nil {
  379. return srv.authAccountCancelHandler(msg), nil
  380. }
  381. case EventDeliveryOrderAdd:
  382. msg := new(DeliveryOrderAddResult)
  383. if err := unmarshal(raw, tp, msg); err != nil {
  384. return nil, err
  385. }
  386. if srv.deliveryOrderAddHandler != nil {
  387. return srv.deliveryOrderAddHandler(msg), nil
  388. }
  389. case EventDeliveryOrderTipsAdd:
  390. msg := new(DeliveryOrderAddTipsResult)
  391. if err := unmarshal(raw, tp, msg); err != nil {
  392. return nil, err
  393. }
  394. if srv.deliveryOrderTipsAddHandler != nil {
  395. return srv.deliveryOrderTipsAddHandler(msg), nil
  396. }
  397. case EventDeliveryOrderCancel:
  398. msg := new(DeliveryOrderCancelResult)
  399. if err := unmarshal(raw, tp, msg); err != nil {
  400. return nil, err
  401. }
  402. if srv.deliveryOrderCancelHandler != nil {
  403. return srv.deliveryOrderCancelHandler(msg), nil
  404. }
  405. case EventDeliveryOrderReturnConfirm:
  406. msg := new(DeliveryOrderReturnConfirmResult)
  407. if err := unmarshal(raw, tp, msg); err != nil {
  408. return nil, err
  409. }
  410. if srv.deliveryOrderReturnConfirmHandler != nil {
  411. return srv.deliveryOrderReturnConfirmHandler(msg), nil
  412. }
  413. case EventDeliveryOrderPreAdd:
  414. msg := new(DeliveryOrderPreAddResult)
  415. if err := unmarshal(raw, tp, msg); err != nil {
  416. return nil, err
  417. }
  418. if srv.deliveryOrderPreAddHandler != nil {
  419. return srv.deliveryOrderPreAddHandler(msg), nil
  420. }
  421. case EventDeliveryOrderPreCancel:
  422. msg := new(DeliveryOrderPreCancelResult)
  423. if err := unmarshal(raw, tp, msg); err != nil {
  424. return nil, err
  425. }
  426. if srv.deliveryOrderPreCancelHandler != nil {
  427. return srv.deliveryOrderPreCancelHandler(msg), nil
  428. }
  429. case EventDeliveryOrderQuery:
  430. msg := new(DeliveryOrderQueryResult)
  431. if err := unmarshal(raw, tp, msg); err != nil {
  432. return nil, err
  433. }
  434. if srv.deliveryOrderQueryHandler != nil {
  435. return srv.deliveryOrderQueryHandler(msg), nil
  436. }
  437. case EventDeliveryOrderReadd:
  438. msg := new(DeliveryOrderReaddResult)
  439. if err := unmarshal(raw, tp, msg); err != nil {
  440. return nil, err
  441. }
  442. if srv.deliveryOrderReaddHandler != nil {
  443. return srv.deliveryOrderReaddHandler(msg), nil
  444. }
  445. case EventPreAuthCodeGet:
  446. msg := new(PreAuthCodeGetResult)
  447. if err := unmarshal(raw, tp, msg); err != nil {
  448. return nil, err
  449. }
  450. if srv.preAuthCodeGetHandler != nil {
  451. return srv.preAuthCodeGetHandler(msg), nil
  452. }
  453. case EventRiderScoreSet:
  454. msg := new(RiderScoreSetResult)
  455. if err := unmarshal(raw, tp, msg); err != nil {
  456. return nil, err
  457. }
  458. if srv.riderScoreSetHandler != nil {
  459. return srv.riderScoreSetHandler(msg), nil
  460. }
  461. case EventExpressPathUpdate:
  462. msg := new(ExpressPathUpdateResult)
  463. if err := unmarshal(raw, tp, msg); err != nil {
  464. return nil, err
  465. }
  466. if srv.expressPathUpdateHandler != nil {
  467. srv.expressPathUpdateHandler(msg)
  468. }
  469. case EventNearbyPoiAuditInfoAdd:
  470. msg := new(AddNearbyPoiResult)
  471. if err := unmarshal(raw, tp, msg); err != nil {
  472. return nil, err
  473. }
  474. if srv.addNearbyPoiAuditHandler != nil {
  475. srv.addNearbyPoiAuditHandler(msg)
  476. }
  477. default:
  478. return nil, fmt.Errorf("unexpected message type '%s'", res.MsgType)
  479. }
  480. default:
  481. return nil, fmt.Errorf("unexpected message type '%s'", res.MsgType)
  482. }
  483. return nil, nil
  484. }
  485. // 判断 interface{} 是否为空
  486. func isNil(i interface{}) bool {
  487. defer func() {
  488. recover()
  489. }()
  490. vi := reflect.ValueOf(i)
  491. return vi.IsNil()
  492. }
  493. // Serve 接收并处理微信通知服务
  494. func (srv *Server) Serve(w http.ResponseWriter, r *http.Request) error {
  495. switch r.Method {
  496. case "POST":
  497. tp := getDataType(r)
  498. isEncrpt := isEncrypted(r)
  499. res, err := srv.handleRequest(w, r, isEncrpt, tp)
  500. if err != nil {
  501. return fmt.Errorf("handle request content error: %s", err)
  502. }
  503. if !isNil(res) {
  504. raw, err := marshal(res, tp)
  505. if err != nil {
  506. return err
  507. }
  508. if isEncrpt {
  509. res, err := srv.encryptMsg(string(raw), time.Now().Unix())
  510. if err != nil {
  511. return err
  512. }
  513. raw, err = marshal(res, tp)
  514. if err != nil {
  515. return err
  516. }
  517. }
  518. w.WriteHeader(http.StatusOK)
  519. w.Header().Set("Content-Type", tp)
  520. if _, err := w.Write(raw); err != nil {
  521. return err
  522. }
  523. } else {
  524. w.Header().Set("Content-Type", "text/plain; charset=utf-8") // normal header
  525. w.WriteHeader(http.StatusOK)
  526. _, err = io.WriteString(w, "success")
  527. if err != nil {
  528. return err
  529. }
  530. }
  531. return nil
  532. case "GET":
  533. if srv.validate { // 请求来自微信验证成功后原样返回 echostr 参数内容
  534. if !srv.validateServer(r) {
  535. return errors.New("验证消息来自微信服务器失败")
  536. }
  537. w.Header().Set("Content-Type", "text/plain; charset=utf-8") // normal header
  538. w.WriteHeader(http.StatusOK)
  539. echostr := r.URL.Query().Get("echostr")
  540. _, err := io.WriteString(w, echostr)
  541. if err != nil {
  542. return err
  543. }
  544. }
  545. return nil
  546. default:
  547. return errors.New("invalid request method: " + r.Method)
  548. }
  549. }
  550. // 判断消息是否加密
  551. func isEncrypted(req *http.Request) bool {
  552. return req.URL.Query().Get("encrypt_type") == "aes"
  553. }
  554. // 验证消息的确来自微信服务器
  555. // 1.将token、timestamp、nonce三个参数进行字典序排序
  556. // 2.将三个参数字符串拼接成一个字符串进行sha1加密
  557. // 3.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
  558. func (srv *Server) validateServer(req *http.Request) bool {
  559. query := req.URL.Query()
  560. nonce := query.Get("nonce")
  561. signature := query.Get("signature")
  562. timestamp := query.Get("timestamp")
  563. return validateSignature(signature, nonce, timestamp, srv.token)
  564. }
  565. // 加密消息
  566. func (srv *Server) encryptMsg(message string, timestamp int64) (*EncryptedMsgRequest, error) {
  567. key := srv.aesKey
  568. //获得16位随机字符串,填充到明文之前
  569. nonce := randomString(16)
  570. text := nonce + strconv.Itoa(len(message)) + message + srv.appID
  571. plaintext := pkcs7encode([]byte(text))
  572. cipher, err := cbcEncrypt(key, plaintext, key)
  573. if err != nil {
  574. return nil, err
  575. }
  576. encrypt := base64.StdEncoding.EncodeToString(cipher)
  577. timestr := strconv.FormatInt(timestamp, 10)
  578. //生成安全签名
  579. signature := createSignature(srv.token, timestr, nonce, encrypt)
  580. request := EncryptedMsgRequest{
  581. Nonce: nonce,
  582. Encrypt: encrypt,
  583. TimeStamp: timestr,
  584. MsgSignature: signature,
  585. }
  586. return &request, nil
  587. }
  588. // 检验消息的真实性,并且获取解密后的明文.
  589. func (srv *Server) decryptMsg(encrypted string) ([]byte, error) {
  590. key := srv.aesKey
  591. ciphertext, err := base64.StdEncoding.DecodeString(encrypted)
  592. if err != nil {
  593. return nil, err
  594. }
  595. data, err := cbcDecrypt(key, ciphertext, key)
  596. if err != nil {
  597. return nil, err
  598. }
  599. return data, nil
  600. }