Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

202 Zeilen
6.4KB

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "net/http/httputil"
  7. "net/url"
  8. "strconv"
  9. "time"
  10. )
  11. //PathsConfig all system available pathes
  12. type PathsConfig struct {
  13. Angular2App string `json:"angular2_app"`
  14. }
  15. //TODO: setup GlobalPath Config, from reading file
  16. //GlobalPath all global pathes configurations
  17. var GlobalPath = PathsConfig{
  18. "/mnt/data/workspace/angular.ts/wechat/ng2-admin/dist/"}
  19. //KFUsers info cache about current customer service
  20. var KFUsers kfCache
  21. func main() {
  22. err := readConfig() //wechat API config
  23. if err != nil {
  24. log.Println(err)
  25. log.Fatal("unable to read server_config.json, program quit")
  26. return
  27. }
  28. err = readCRMConfig()
  29. if err != nil {
  30. log.Println(err)
  31. log.Fatal("unable to read crm_config.json, program quit")
  32. }
  33. err = IntraAPIConfig.readConfig()
  34. if err != nil {
  35. log.Println(err)
  36. log.Fatal("unable to read intra-api-config, program quit")
  37. }
  38. initAllProc()
  39. setupRootFileServer()
  40. startSessionManager(2048)
  41. KFUsers.kfRenewList()
  42. //always the last one
  43. setupHTTPHandler()
  44. }
  45. func setupHTTPHandler() {
  46. //setup handler
  47. //http.HandleFunc("/", webrootHandler)
  48. http.HandleFunc("/api", apiV1Main)
  49. http.HandleFunc("/upload", uploadHandler)
  50. http.HandleFunc("/crmfiles/", crmAttachmentHandler)
  51. http.HandleFunc("/dumprequest", dumpReuestHandler)
  52. http.HandleFunc("/MP_verify_6JqVkftKr39GMakA.txt", mpDomainAuthSecret)
  53. http.HandleFunc("/profile_newly_register", initialRegistrationHandler)
  54. http.HandleFunc("/iapi/getAccessToken", supplyAccessToken)
  55. http.HandleFunc("/iapi/createWechatQr", iapiCreateWechatQrCode)
  56. http.ListenAndServe(":65500", nil)
  57. }
  58. func startSessionManager(concurrent int) {
  59. m := SessionManager{}
  60. AllInMessage = make(chan InWechatMsg, concurrent)
  61. go m.startSessionManager(AllInMessage)
  62. }
  63. func setupRootFileServer() {
  64. http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  65. http.ServeFile(w, r, GlobalPath.Angular2App+r.URL.Path[1:])
  66. })
  67. //fs := http.FileServer(http.Dir("/mnt/data/workspace/angular.ts/ng2-admin/dist"))
  68. //http.Handle("/test", http.StripPrefix("/test", fs))
  69. //fs := http.FileServer(http.Dir("/mnt/data/workspace/angular.ts/wechat/ng2-admin/dist"))
  70. //http.Handle("/", fs)
  71. }
  72. func dumpReuestHandler(w http.ResponseWriter, r *http.Request) {
  73. logRequestDebug(httputil.DumpRequest(r, true))
  74. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  75. w.Header().Set("Access-Control-Allow-Origin", "http://192.168.1.39:4200")
  76. w.Header().Set("Access-Control-Allow-Headers", "Authorziation11,Authorziation12")
  77. w.Header().Set("Access-Control-Allow-Credentials", "true")
  78. w.Header().Set("Access-Control-Expose-Headers", "Set-Cookie,myheader,*")
  79. w.Header().Set("myheader", "myheader-data")
  80. expiration := time.Now().Add(10 * 365 * 24 * time.Hour)
  81. str := time.Now().String()
  82. cookie := http.Cookie{Name: "username", Value: str, Expires: expiration}
  83. http.SetCookie(w, &cookie)
  84. fmt.Fprintf(w, `{"status":"OK"}`)
  85. for _, c := range r.Cookies() {
  86. log.Println(c.Name)
  87. log.Println(c.Value)
  88. }
  89. }
  90. func supplyAccessToken(w http.ResponseWriter, r *http.Request) {
  91. //logRequestDebug(httputil.DumpRequest(r, true))
  92. if checkSignatureByToken(r, IntraAPIConfig.CRMSecrete) {
  93. atk, _ := GetAccessToken()
  94. fmt.Fprint(w, atk)
  95. } else {
  96. w.WriteHeader(401)
  97. fmt.Fprint(w, "unauthorized")
  98. }
  99. }
  100. func iapiCreateWechatQrCode(w http.ResponseWriter, r *http.Request) {
  101. logRequestDebug(httputil.DumpRequest(r, true))
  102. if !checkSignatureByToken(r, IntraAPIConfig.CRMSecrete) {
  103. w.WriteHeader(http.StatusUnauthorized)
  104. fmt.Fprint(w, "unauthorized")
  105. return
  106. }
  107. rq := r.URL.RawQuery
  108. m, _ := url.ParseQuery(rq)
  109. qrValue, qok := m["qrValue"]
  110. expire, eok := m["expire"]
  111. if !qok || !eok {
  112. w.WriteHeader(http.StatusUnprocessableEntity)
  113. fmt.Fprintf(w, "parameter not correct, bad api call %s", time.Now().Format(getCrmTimeLayout()))
  114. return
  115. }
  116. if isStrInt(qrValue[0]) && isStrInt(expire[0]) {
  117. intVal, _ := strconv.Atoi(qrValue[0])
  118. intExpire, _ := strconv.Atoi(expire[0])
  119. jsonB, err := iapiCreateTempQr(int32(intVal), int32(intExpire))
  120. if err == nil {
  121. w.Write(jsonB)
  122. } else {
  123. fmt.Fprintf(w, "%s", err)
  124. }
  125. return
  126. }
  127. if !isStrInt(qrValue[0]) && expire[0] == "0" {
  128. jsonB, err := isapiCreatePermQr(qrValue[0])
  129. if err == nil {
  130. w.Write(jsonB)
  131. } else {
  132. fmt.Fprintf(w, "%s", err)
  133. }
  134. return
  135. }
  136. }
  137. func isStrInt(v string) bool {
  138. if _, err := strconv.Atoi(v); err == nil {
  139. return true
  140. }
  141. return false
  142. }
  143. // 用户在网页授权页同意授权给公众号后,微信会将授权数据传给一个回调页面,回调页面需在此域名下,以确保安全可靠。
  144. // 注意事项:
  145. // 1、回调页面域名或路径需使用字母、数字及“-”的组合(例:wx.qq.com或wx.qq.com/mp),不支持IP地址、端口号及短链域名。填写的域名或路径需与实际回调URL中的域名或路径相同。
  146. // 2、填写的域名须通过ICP备案的验证。
  147. // 3、将文件MP_verify_6JqVkftKr39GMakA.txt(点击下载)上传至填写域名或路径指向的web服务器(或虚拟主机)的目录(若填写域名,将文件放置在域名根目录下,例如wx.qq.com/MP_verify_6JqVkftKr39GMakA.txt;若填写路径,将文件放置在路径目录下,例如wx.qq.com/mp/MP_verify_6JqVkftKr39GMakA.txt),并确保可以访问。
  148. func mpDomainAuthSecret(w http.ResponseWriter, r *http.Request) {
  149. fmt.Fprintf(w, "6JqVkftKr39GMakA")
  150. //由于需要什么ICP备案,这个功能不能使用
  151. }
  152. //for user's initial registration, especially for wechat users
  153. //they visit a url that is specifically designed for them to
  154. //auth and input their profile data.
  155. //the url's query string will contains a token and a signature
  156. //so that it's verified, by single get request, to allow people to
  157. //enter their details into the CRM system.
  158. //
  159. //this handler, check's the query sting ,set an auth cookie to the client
  160. //and serve angular app, through an URL "/profile/edit"
  161. //or if the user has already been registered,
  162. //redirect user to a URL "/pages/dashboard"
  163. //
  164. func initialRegistrationHandler(w http.ResponseWriter, r *http.Request) {
  165. //TODO: verify url parameters and make sure its username is correctly set
  166. //
  167. expiration := time.Now().Add(10 * 365 * 24 * time.Hour)
  168. str := time.Now().String()
  169. cookie := http.Cookie{Name: "username", Value: str, Expires: expiration}
  170. http.SetCookie(w, &cookie)
  171. cookie = http.Cookie{Name: "signature", Value: "abcee", Expires: expiration}
  172. http.SetCookie(w, &cookie)
  173. http.Redirect(w, r, "http://192.168.1.39:4200/#pages/charts/chartist-js", 307) //302 temp redirect
  174. }