-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathwechatApi.go
More file actions
157 lines (136 loc) · 3.91 KB
/
wechatApi.go
File metadata and controls
157 lines (136 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package wechatApi
import (
"errors"
"fmt"
"github.com/duck-lab/wechat-api/accessToken"
"github.com/duck-lab/wechat-api/menu"
"time"
)
//API is the outlet of all APIs
type API struct {
endpoint string
baseURL string
appID string
appSecret string
tokenStorageMode int
currentToken accessToken.Data
calls map[string]int
}
var api = API{
endpoint: "https://api.weixin.qq.com",
baseURL: "https://api.weixin.qq.com/cgi-bin",
tokenStorageMode: accessToken.StoreInMemory,
calls: map[string]int{},
}
//New is the start point
//For the convience of get the accure calls, use single instance
func New(appID string, appSecret string) API {
api.appID = appID
api.appSecret = appSecret
return api
}
//SetEndpoint let the user can chose which api server to use
func (api *API) SetEndpoint(endpoint string) {
api.endpoint = endpoint
api.baseURL = api.endpoint + "/cgi-bin"
}
//SetTokenStorageMode ...
func (api *API) SetTokenStorageMode(mode int, params interface{}) bool {
if mode == accessToken.StoreInMemory {
}
if mode == accessToken.StoreInFile {
file, ok := params.(accessToken.StoreInFileParams)
fmt.Println(file, ok)
}
if mode == accessToken.StoreInRedis {
redis, ok := params.(accessToken.StoreInRedisParams)
fmt.Println(redis, ok)
}
return false
}
func (api *API) getCurrentToken() (accessToken.Data, error) {
if api.tokenStorageMode == accessToken.StoreInMemory {
return api.currentToken, nil
}
if api.tokenStorageMode == accessToken.StoreInFile {
//TODO: read file
}
if api.tokenStorageMode == accessToken.StoreInRedis {
//TODO: read redis
}
return accessToken.Data{}, errors.New("To be implemented")
}
func (api *API) setCurrentToken(token accessToken.Data) bool {
if api.tokenStorageMode == accessToken.StoreInMemory {
api.currentToken = token
return true
}
return false
}
func getCallKey(apiName string) string {
now := time.Now()
return fmt.Sprintf("%d-%d-%d-%s", now.Year(), now.Month(), now.Day(), apiName)
}
func (api *API) getCall(apiName string) int {
return api.calls[getCallKey(apiName)]
}
func (api *API) callIncr(apiName string) int {
//Todo: support multi routines
key := getCallKey(apiName)
api.calls[key] = api.calls[key] + 1
fmt.Println(api.calls)
return api.calls[key]
}
//GetAccessToken can let user fetch the access token
func (api *API) GetAccessToken() (accessToken.Data, error) {
current, err := api.getCurrentToken()
if err != nil {
return accessToken.Data{}, err
}
if current.ExpiresTime.Unix() > time.Now().Unix() {
return current, nil
}
if api.tokenStorageMode == accessToken.StoreInMemory {
data, err := accessToken.Fetch(api.appID, api.appSecret, api.baseURL)
api.callIncr(accessToken.APINameFetch)
api.setCurrentToken(data)
return data, err
}
return accessToken.Data{}, errors.New("To be implemented")
}
//CreateMenu is used to create Menu
func (api *API) CreateMenu(model menu.Model) error {
token, err := api.GetAccessToken()
if err != nil {
return err
}
api.callIncr(menu.APINameCreate)
return menu.Create(model, api.baseURL, token.AccessToken)
}
//CreateConditionalMenu is used to create customized Menu
func (api *API) CreateConditionalMenu(model menu.ConditionalMenu) (string, error) {
token, err := api.GetAccessToken()
if err != nil {
return "", err
}
api.callIncr(menu.APINameCreateConditional)
return menu.CreateConditional(model, api.baseURL, token.AccessToken)
}
//FetchMenuList is used to fetch all Menu
func (api *API) FetchMenuList() (menu.FetchedList, error) {
token, err := api.GetAccessToken()
if err != nil {
return menu.FetchedList{}, err
}
api.callIncr(menu.APINameFetchedList)
return menu.FetchList(api.baseURL, token.AccessToken)
}
//DeleteAllMenu ...
func (api *API) DeleteAllMenu() error {
token, err := api.GetAccessToken()
if err != nil {
return err
}
api.callIncr(menu.APINameDeleteAll)
return menu.DeleteAll(api.baseURL, token.AccessToken)
}