No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

131 líneas
3.3KB

  1. package main
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "io/ioutil"
  6. "log"
  7. "os"
  8. )
  9. //chat state that we might be use for collecting infomation from user
  10. type chatState struct {
  11. Name string `json:"Name"` //state name
  12. Expire int32 `json:"Expire"` //unix timestamp when this state expire
  13. Send struct { //anything we need to send?
  14. Type string `json:"Type"` //what type of message
  15. Message map[string]string `json:"Message"` //the message to be sent,key value pair to describe the message
  16. } `json:"Send"`
  17. Receive struct { //anything we expect to receive
  18. Validator string `json:"Validator"`
  19. Hint string `json:"Hint"`
  20. Message map[string]string `json:"Message"` //the description for receiving message
  21. } `json:"Receive"`
  22. Save map[string]string `json:"Save"` //the state save some data for later usage
  23. }
  24. //for individual state
  25. func getCurrentState(openID string, procedure string) (result chatState, err error) {
  26. path := getProcedurePath(openID, procedure)
  27. log.Printf("read state from %s\r\n", path)
  28. body, err := ioutil.ReadFile(path)
  29. if err != nil { //read file error
  30. if isFileExist(path) {
  31. log.Println("Error session reading " + path)
  32. }
  33. return //empty and expired session
  34. }
  35. err = json.Unmarshal(body, &result)
  36. if err != nil {
  37. log.Printf("Session Content [path=%s] not correct: ", path)
  38. log.Println(err)
  39. }
  40. //we don't check Expire, we give the caller full control on
  41. //how to deal wiht expired session
  42. return
  43. }
  44. func setCurrentState(openID, procedure string, state chatState) (newState chatState, err error) {
  45. j, err := json.Marshal(state)
  46. if err != nil {
  47. return
  48. }
  49. path := getProcedurePath(openID, procedure)
  50. err = ioutil.WriteFile(path, j, 0600)
  51. if err != nil {
  52. log.Println("write state error" + path)
  53. log.Println(err)
  54. return
  55. }
  56. newState = state
  57. return
  58. }
  59. func deleteChatState(openID, procedure string) (err error) {
  60. path := getProcedurePath(openID, procedure)
  61. err = os.Remove(path)
  62. return
  63. }
  64. //ValidationResult After input validation, what is the result
  65. type ValidationResult struct {
  66. accept bool
  67. Hint string
  68. Error string
  69. Warning string
  70. }
  71. //Validator function type for validating all wechat inputs
  72. type Validator func(s chatState) ValidationResult
  73. //start a procedure
  74. func startProcedure(openID, procedure string) (err error) {
  75. //init procedure state
  76. init := getProcedureInit(openID, procedure)
  77. if init == nil {
  78. msg := "FATAL: cannot initialize procedure [" + procedure + "] "
  79. err = errors.New(msg)
  80. return
  81. }
  82. //init and get initial state
  83. state := init(openID)
  84. //do the real concret work for processing the state
  85. err = processProcedureState(state)
  86. return
  87. }
  88. //resume a previous Procedure
  89. func resumeProcedure(procedure string) {
  90. }
  91. func stopProcedure(procedure string) {
  92. }
  93. func processProcedureState(state chatState) (err error) {
  94. log.Println(state)
  95. return
  96. }
  97. type initProcedureFunction func(openid string) (initState chatState)
  98. func getProcedureInit(openID, procedure string) initProcedureFunction {
  99. initFunc := map[string]initProcedureFunction{
  100. "TestDummy": nil,
  101. "TestEcho": initTestEcho,
  102. "GetBasicUserInfo": initGetBasicUserInfo,
  103. "GetEmailAddr": initGetBasicUserInfo,
  104. }
  105. return initFunc[procedure]
  106. }
  107. func initTestEcho(openid string) (r chatState) {
  108. r.Name = openid
  109. r.Expire = 0
  110. return
  111. }