package main import ( "encoding/json" "errors" "io/ioutil" "log" "os" ) //chat state that we might be use for collecting infomation from user type chatState struct { //back pointer style information, managed by general process OpenID string `json:"OpenID"` //whom is this belongs to Procedure string `json:"Procedure"` //which procedure this belongs to //below is managed by procedure only //real state information Name string `json:"Name"` //state name Expire int32 `json:"Expire"` //unix timestamp when this state expire //persistant sate Save map[string]string `json:"Save"` //the state save some data for later usage //runtime memory only response string //被动回复消息的内容 } //for individual state func getCurrentState(openID string, procedure string) (result chatState, err error) { path := getProcedurePath(openID, procedure) //log.Printf("read state from %s\r\n", path) body, err := ioutil.ReadFile(path) if err != nil { //read file error if isFileExist(path) { log.Println("Error session reading " + path) } return //empty and expired session } err = json.Unmarshal(body, &result) if err != nil { log.Printf("Session Content [path=%s] not correct: ", path) log.Println(err) } err = sanityCheckState(openID, procedure, result) return } func sanityCheckState(openID, procedure string, result chatState) (err error) { //check whether state is for the correct openID and procedure if result.OpenID != openID { err = errors.New("Error: State for " + openID + " is actually for " + result.OpenID) return } if result.Procedure != procedure { err = errors.New("Error: Proecdure for " + procedure + " is actually for " + result.Procedure) return } return } func setCurrentState(openID, procedure string, state chatState) (newState chatState, err error) { state.OpenID = openID state.Procedure = procedure j, err := json.Marshal(state) if err != nil { return } path := getProcedurePath(openID, procedure) err = ioutil.WriteFile(path, j, 0600) if err != nil { log.Println("write state error" + path) log.Println(err) return } newState = state return } func deleteChatState(openID, procedure string) (err error) { path := getProcedurePath(openID, procedure) err = os.Remove(path) return } //ValidationResult After input validation, what is the result type ValidationResult struct { accept bool Hint string Error string Warning string } //Validator function type for validating all wechat inputs type Validator func(s chatState) ValidationResult func saveChatState(state chatState) { }