|
- 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 {
- Name string `json:"Name"` //state name
- Expire int32 `json:"Expire"` //unix timestamp when this state expire
- Send struct { //anything we need to send?
- Type string `json:"Type"` //what type of message
- Message map[string]string `json:"Message"` //the message to be sent,key value pair to describe the message
- } `json:"Send"`
-
- Receive struct { //anything we expect to receive
- Validator string `json:"Validator"`
- Hint string `json:"Hint"`
- Message map[string]string `json:"Message"` //the description for receiving message
- } `json:"Receive"`
-
- Save map[string]string `json:"Save"` //the state save some data for later usage
- }
-
- //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)
- }
- //we don't check Expire, we give the caller full control on
- //how to deal wiht expired session
- return
- }
-
- func setCurrentState(openID, procedure string, state chatState) (newState chatState, err error) {
- 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
-
- //start a procedure
- func startProcedure(openID, procedure string) (err error) {
- //init procedure state
- init := getProcedureInit(openID, procedure)
- if init == nil {
- msg := "FATAL: cannot initialize procedure [" + procedure + "] "
- err = errors.New(msg)
- return
- }
- //init and get initial state
- state := init(openID)
-
- //do the real concret work for processing the state
- err = processProcedureState(state)
- return
- }
-
- //resume a previous Procedure
- func resumeProcedure(procedure string) {
-
- }
-
- func stopProcedure(procedure string) {
-
- }
-
- func processProcedureState(state chatState) (err error) {
- log.Println(state)
- return
- }
-
- type initProcedureFunction func(openid string) (initState chatState)
-
- func getProcedureInit(openID, procedure string) initProcedureFunction {
- initFunc := map[string]initProcedureFunction{
- "TestDummy": nil,
- "TestEcho": initTestEcho,
- "GetBasicUserInfo": initGetBasicUserInfo,
- "GetEmailAddr": initGetBasicUserInfo,
- }
- return initFunc[procedure]
- }
-
- func initTestEcho(openid string) (r chatState) {
- r.Name = openid
- r.Expire = 0
- return
- }
|