支持热登陆 ✨
This commit is contained in:
parent
2761e43c49
commit
a8c646b33d
59
bot.go
59
bot.go
@ -7,15 +7,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Bot struct {
|
type Bot struct {
|
||||||
ScanCallBack func(body []byte)
|
ScanCallBack func(body []byte)
|
||||||
LoginCallBack func(body []byte)
|
LoginCallBack func(body []byte)
|
||||||
UUIDCallback func(uuid string)
|
UUIDCallback func(uuid string)
|
||||||
MessageHandler func(msg *Message)
|
MessageHandler func(msg *Message)
|
||||||
err error
|
isHot bool
|
||||||
exit chan bool
|
err error
|
||||||
Caller *Caller
|
exit chan bool
|
||||||
self *Self
|
Caller *Caller
|
||||||
storage *Storage
|
self *Self
|
||||||
|
storage *Storage
|
||||||
|
hotReloadStorage HotReloadStorage
|
||||||
|
mode mode
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断当前用户是否正常在线
|
// 判断当前用户是否正常在线
|
||||||
@ -39,6 +42,20 @@ func (b *Bot) GetCurrentUser() (*Self, error) {
|
|||||||
return b.self, nil
|
return b.self, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Bot) HotLogin(storage HotReloadStorage) error {
|
||||||
|
b.isHot = true
|
||||||
|
b.hotReloadStorage = storage
|
||||||
|
if err := storage.Load(); err != nil {
|
||||||
|
return b.Login()
|
||||||
|
}
|
||||||
|
cookies := storage.GetCookie()
|
||||||
|
path := b.Caller.Client.getBaseUrl()
|
||||||
|
b.Caller.Client.Jar.SetCookies(path, cookies)
|
||||||
|
b.storage.LoginInfo = storage.GetLoginInfo()
|
||||||
|
b.storage.Request = storage.GetBaseRequest()
|
||||||
|
return b.webInit()
|
||||||
|
}
|
||||||
|
|
||||||
// 用户登录
|
// 用户登录
|
||||||
// 该方法会一直阻塞,直到用户扫码登录,或者二维码过期
|
// 该方法会一直阻塞,直到用户扫码登录,或者二维码过期
|
||||||
func (b *Bot) Login() error {
|
func (b *Bot) Login() error {
|
||||||
@ -105,8 +122,22 @@ func (b *Bot) login(data []byte) error {
|
|||||||
|
|
||||||
// 将BaseRequest存到storage里面方便后续调用
|
// 将BaseRequest存到storage里面方便后续调用
|
||||||
b.storage.Request = request
|
b.storage.Request = request
|
||||||
|
|
||||||
|
if b.isHot {
|
||||||
|
cookies := b.Caller.Client.getCookies()
|
||||||
|
if err := b.hotReloadStorage.Dump(cookies, request, info); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return b.webInit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bot) webInit() error {
|
||||||
|
req := b.storage.Request
|
||||||
|
info := b.storage.LoginInfo
|
||||||
// 获取初始化的用户信息和一些必要的参数
|
// 获取初始化的用户信息和一些必要的参数
|
||||||
resp, err := b.Caller.WebInit(request)
|
resp, err := b.Caller.WebInit(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -116,7 +147,7 @@ func (b *Bot) login(data []byte) error {
|
|||||||
b.storage.Response = resp
|
b.storage.Response = resp
|
||||||
|
|
||||||
// 通知手机客户端已经登录
|
// 通知手机客户端已经登录
|
||||||
if err = b.Caller.WebWxStatusNotify(request, resp, info); err != nil {
|
if err = b.Caller.WebWxStatusNotify(req, resp, info); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 开启协程,轮训获取是否有新的消息返回
|
// 开启协程,轮训获取是否有新的消息返回
|
||||||
@ -208,12 +239,6 @@ func DefaultBot(modes ...mode) *Bot {
|
|||||||
return NewBot(DefaultCaller(urlManager))
|
return NewBot(DefaultCaller(urlManager))
|
||||||
}
|
}
|
||||||
|
|
||||||
type Storage struct {
|
|
||||||
LoginInfo *LoginInfo
|
|
||||||
Request *BaseRequest
|
|
||||||
Response *WebInitResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetQrcodeUrl(uuid string) string {
|
func GetQrcodeUrl(uuid string) string {
|
||||||
return qrcodeUrl + uuid
|
return qrcodeUrl + uuid
|
||||||
}
|
}
|
||||||
|
15
bot_test.go
15
bot_test.go
@ -220,3 +220,18 @@ func TestAgreeFriendsAdd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
bot.Block()
|
bot.Block()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHotLogin(t *testing.T) {
|
||||||
|
bot := defaultBot()
|
||||||
|
s := NewFileHotReloadStorage("2.json")
|
||||||
|
if err := bot.HotLogin(s); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self, err := bot.GetCurrentUser()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Log(self.NickName)
|
||||||
|
}
|
||||||
|
678
client.go
678
client.go
@ -1,454 +1,464 @@
|
|||||||
package openwechat
|
package openwechat
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/cookiejar"
|
"net/http/cookiejar"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// http请求客户端
|
// http请求客户端
|
||||||
// 客户端需要维持Session会话
|
// 客户端需要维持Session会话
|
||||||
// 并且客户端不允许跳转
|
// 并且客户端不允许跳转
|
||||||
type Client struct {
|
type Client struct {
|
||||||
*http.Client
|
*http.Client
|
||||||
UrlManager
|
UrlManager
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(client *http.Client, urlManager UrlManager) *Client {
|
func NewClient(client *http.Client, urlManager UrlManager) *Client {
|
||||||
return &Client{Client: client, UrlManager: urlManager}
|
return &Client{Client: client, UrlManager: urlManager}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自动存储cookie
|
// 自动存储cookie
|
||||||
// 设置客户端不自动跳转
|
// 设置客户端不自动跳转
|
||||||
func DefaultClient(urlManager UrlManager) *Client {
|
func DefaultClient(urlManager UrlManager) *Client {
|
||||||
jar, _ := cookiejar.New(nil)
|
jar, _ := cookiejar.New(nil)
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||||
return http.ErrUseLastResponse
|
return http.ErrUseLastResponse
|
||||||
},
|
},
|
||||||
Jar: jar,
|
Jar: jar,
|
||||||
}
|
}
|
||||||
return NewClient(client, urlManager)
|
return NewClient(client, urlManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getBaseUrl() *url.URL {
|
||||||
|
path, _ := url.Parse(c.UrlManager.baseUrl)
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) getCookies() []*http.Cookie {
|
||||||
|
path := c.getBaseUrl()
|
||||||
|
return c.Jar.Cookies(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取登录的uuid
|
// 获取登录的uuid
|
||||||
func (c *Client) GetLoginUUID() (*http.Response, error) {
|
func (c *Client) GetLoginUUID() (*http.Response, error) {
|
||||||
path, _ := url.Parse(jsLoginUrl)
|
path, _ := url.Parse(jsLoginUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("appid", appId)
|
params.Add("appid", appId)
|
||||||
params.Add("redirect_uri", c.webWxNewLoginPageUrl)
|
params.Add("redirect_uri", c.webWxNewLoginPageUrl)
|
||||||
params.Add("fun", "new")
|
params.Add("fun", "new")
|
||||||
params.Add("lang", "zh_CN")
|
params.Add("lang", "zh_CN")
|
||||||
params.Add("_", strconv.FormatInt(time.Now().Unix(), 10))
|
params.Add("_", strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.Get(path.String())
|
return c.Get(path.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取登录的二维吗
|
// 获取登录的二维吗
|
||||||
func (c *Client) GetLoginQrcode(uuid string) (*http.Response, error) {
|
func (c *Client) GetLoginQrcode(uuid string) (*http.Response, error) {
|
||||||
path := qrcodeUrl + uuid
|
path := qrcodeUrl + uuid
|
||||||
return c.Get(path)
|
return c.Get(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否登录
|
// 检查是否登录
|
||||||
func (c *Client) CheckLogin(uuid string) (*http.Response, error) {
|
func (c *Client) CheckLogin(uuid string) (*http.Response, error) {
|
||||||
path, _ := url.Parse(loginUrl)
|
path, _ := url.Parse(loginUrl)
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("r", strconv.FormatInt(now/1579, 10))
|
params.Add("r", strconv.FormatInt(now/1579, 10))
|
||||||
params.Add("_", strconv.FormatInt(now, 10))
|
params.Add("_", strconv.FormatInt(now, 10))
|
||||||
params.Add("loginicon", "true")
|
params.Add("loginicon", "true")
|
||||||
params.Add("uuid", uuid)
|
params.Add("uuid", uuid)
|
||||||
params.Add("tip", "0")
|
params.Add("tip", "0")
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.Get(path.String())
|
return c.Get(path.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLoginInfo 请求获取LoginInfo
|
// GetLoginInfo 请求获取LoginInfo
|
||||||
func (c *Client) GetLoginInfo(path string) (*http.Response, error) {
|
func (c *Client) GetLoginInfo(path string) (*http.Response, error) {
|
||||||
req, _ := http.NewRequest(http.MethodGet, path, nil)
|
req, _ := http.NewRequest(http.MethodGet, path, nil)
|
||||||
req.Header.Add("client-version", uosPatchClientVersion)
|
req.Header.Add("client-version", uosPatchClientVersion)
|
||||||
req.Header.Add("extspam", uosPatchExtspam)
|
req.Header.Add("extspam", uosPatchExtspam)
|
||||||
return c.Do(req)
|
return c.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 请求获取初始化信息
|
// 请求获取初始化信息
|
||||||
func (c *Client) WebInit(request *BaseRequest) (*http.Response, error) {
|
func (c *Client) WebInit(request *BaseRequest) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxInitUrl)
|
path, _ := url.Parse(c.webWxInitUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("_", fmt.Sprintf("%d", time.Now().Unix()))
|
params.Add("_", fmt.Sprintf("%d", time.Now().Unix()))
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
content := struct{ BaseRequest *BaseRequest }{BaseRequest: request}
|
content := struct{ BaseRequest *BaseRequest }{BaseRequest: request}
|
||||||
body, err := ToBuffer(content)
|
body, err := ToBuffer(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return c.Post(path.String(), jsonContentType, body)
|
return c.Post(path.String(), jsonContentType, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 通知手机已登录
|
// 通知手机已登录
|
||||||
func (c *Client) WebWxStatusNotify(request *BaseRequest, response *WebInitResponse, info *LoginInfo) (*http.Response, error) {
|
func (c *Client) WebWxStatusNotify(request *BaseRequest, response *WebInitResponse, info *LoginInfo) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxStatusNotifyUrl)
|
path, _ := url.Parse(c.webWxStatusNotifyUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("lang", "zh_CN")
|
params.Add("lang", "zh_CN")
|
||||||
params.Add("pass_ticket", info.PassTicket)
|
params.Add("pass_ticket", info.PassTicket)
|
||||||
username := response.User.UserName
|
username := response.User.UserName
|
||||||
content := map[string]interface{}{
|
content := map[string]interface{}{
|
||||||
"BaseRequest": request,
|
"BaseRequest": request,
|
||||||
"ClientMsgId": time.Now().Unix(),
|
"ClientMsgId": time.Now().Unix(),
|
||||||
"Code": 3,
|
"Code": 3,
|
||||||
"FromUserName": username,
|
"FromUserName": username,
|
||||||
"ToUserName": username,
|
"ToUserName": username,
|
||||||
}
|
}
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
buffer, _ := ToBuffer(content)
|
buffer, _ := ToBuffer(content)
|
||||||
req, _ := http.NewRequest(http.MethodPost, path.String(), buffer)
|
req, _ := http.NewRequest(http.MethodPost, path.String(), buffer)
|
||||||
req.Header.Add("Content-Type", jsonContentType)
|
req.Header.Add("Content-Type", jsonContentType)
|
||||||
return c.Do(req)
|
return c.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 异步检查是否有新的消息返回
|
// 异步检查是否有新的消息返回
|
||||||
func (c *Client) SyncCheck(info *LoginInfo, response *WebInitResponse) (*http.Response, error) {
|
func (c *Client) SyncCheck(info *LoginInfo, response *WebInitResponse) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.syncCheckUrl)
|
path, _ := url.Parse(c.syncCheckUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("r", strconv.FormatInt(time.Now().Unix(), 10))
|
params.Add("r", strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
params.Add("skey", info.SKey)
|
params.Add("skey", info.SKey)
|
||||||
params.Add("sid", info.WxSid)
|
params.Add("sid", info.WxSid)
|
||||||
params.Add("uin", strconv.Itoa(info.WxUin))
|
params.Add("uin", strconv.Itoa(info.WxUin))
|
||||||
params.Add("deviceid", GetRandomDeviceId())
|
params.Add("deviceid", GetRandomDeviceId())
|
||||||
params.Add("_", strconv.FormatInt(time.Now().Unix(), 10))
|
params.Add("_", strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
var syncKeyStringSlice []string
|
var syncKeyStringSlice []string
|
||||||
// 将SyncKey里面的元素按照特定的格式拼接起来
|
// 将SyncKey里面的元素按照特定的格式拼接起来
|
||||||
for _, item := range response.SyncKey.List {
|
for _, item := range response.SyncKey.List {
|
||||||
i := fmt.Sprintf("%d_%d", item.Key, item.Val)
|
i := fmt.Sprintf("%d_%d", item.Key, item.Val)
|
||||||
syncKeyStringSlice = append(syncKeyStringSlice, i)
|
syncKeyStringSlice = append(syncKeyStringSlice, i)
|
||||||
}
|
}
|
||||||
syncKey := strings.Join(syncKeyStringSlice, "|")
|
syncKey := strings.Join(syncKeyStringSlice, "|")
|
||||||
params.Add("synckey", syncKey)
|
params.Add("synckey", syncKey)
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
req, _ := http.NewRequest(http.MethodGet, path.String(), nil)
|
req, _ := http.NewRequest(http.MethodGet, path.String(), nil)
|
||||||
return c.Do(req)
|
return c.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取联系人信息
|
// 获取联系人信息
|
||||||
func (c *Client) WebWxGetContact(info *LoginInfo) (*http.Response, error) {
|
func (c *Client) WebWxGetContact(info *LoginInfo) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxGetContactUrl)
|
path, _ := url.Parse(c.webWxGetContactUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("r", strconv.FormatInt(time.Now().Unix(), 10))
|
params.Add("r", strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
params.Add("skey", info.SKey)
|
params.Add("skey", info.SKey)
|
||||||
params.Add("req", "0")
|
params.Add("req", "0")
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.Get(path.String())
|
return c.Get(path.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取联系人详情
|
// 获取联系人详情
|
||||||
func (c *Client) WebWxBatchGetContact(members Members, request *BaseRequest) (*http.Response, error) {
|
func (c *Client) WebWxBatchGetContact(members Members, request *BaseRequest) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxBatchGetContactUrl)
|
path, _ := url.Parse(c.webWxBatchGetContactUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("type", "ex")
|
params.Add("type", "ex")
|
||||||
params.Add("r", strconv.FormatInt(time.Now().Unix(), 10))
|
params.Add("r", strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
list := NewUserDetailItemList(members)
|
list := NewUserDetailItemList(members)
|
||||||
content := map[string]interface{}{
|
content := map[string]interface{}{
|
||||||
"BaseRequest": request,
|
"BaseRequest": request,
|
||||||
"Count": members.Count(),
|
"Count": members.Count(),
|
||||||
"List": list,
|
"List": list,
|
||||||
}
|
}
|
||||||
body, _ := ToBuffer(content)
|
body, _ := ToBuffer(content)
|
||||||
req, _ := http.NewRequest(http.MethodPost, path.String(), body)
|
req, _ := http.NewRequest(http.MethodPost, path.String(), body)
|
||||||
req.Header.Add("Content-Type", jsonContentType)
|
req.Header.Add("Content-Type", jsonContentType)
|
||||||
return c.Do(req)
|
return c.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取消息接口
|
// 获取消息接口
|
||||||
func (c *Client) WebWxSync(request *BaseRequest, response *WebInitResponse, info *LoginInfo) (*http.Response, error) {
|
func (c *Client) WebWxSync(request *BaseRequest, response *WebInitResponse, info *LoginInfo) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxSyncUrl)
|
path, _ := url.Parse(c.webWxSyncUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("sid", info.WxSid)
|
params.Add("sid", info.WxSid)
|
||||||
params.Add("skey", info.SKey)
|
params.Add("skey", info.SKey)
|
||||||
params.Add("pass_ticket", info.PassTicket)
|
params.Add("pass_ticket", info.PassTicket)
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
content := map[string]interface{}{
|
content := map[string]interface{}{
|
||||||
"BaseRequest": request,
|
"BaseRequest": request,
|
||||||
"SyncKey": response.SyncKey,
|
"SyncKey": response.SyncKey,
|
||||||
"rr": strconv.FormatInt(time.Now().Unix(), 10),
|
"rr": strconv.FormatInt(time.Now().Unix(), 10),
|
||||||
}
|
}
|
||||||
data, _ := json.Marshal(content)
|
data, _ := json.Marshal(content)
|
||||||
body := bytes.NewBuffer(data)
|
body := bytes.NewBuffer(data)
|
||||||
req, _ := http.NewRequest(http.MethodPost, path.String(), body)
|
req, _ := http.NewRequest(http.MethodPost, path.String(), body)
|
||||||
req.Header.Add("Content-Type", jsonContentType)
|
req.Header.Add("Content-Type", jsonContentType)
|
||||||
return c.Do(req)
|
return c.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送消息
|
// 发送消息
|
||||||
func (c *Client) sendMessage(request *BaseRequest, url string, msg *SendMessage) (*http.Response, error) {
|
func (c *Client) sendMessage(request *BaseRequest, url string, msg *SendMessage) (*http.Response, error) {
|
||||||
content := map[string]interface{}{
|
content := map[string]interface{}{
|
||||||
"BaseRequest": request,
|
"BaseRequest": request,
|
||||||
"Msg": msg,
|
"Msg": msg,
|
||||||
"Scene": 0,
|
"Scene": 0,
|
||||||
}
|
}
|
||||||
body, _ := ToBuffer(content)
|
body, _ := ToBuffer(content)
|
||||||
req, _ := http.NewRequest(http.MethodPost, url, body)
|
req, _ := http.NewRequest(http.MethodPost, url, body)
|
||||||
req.Header.Add("Content-Type", jsonContentType)
|
req.Header.Add("Content-Type", jsonContentType)
|
||||||
return c.Do(req)
|
return c.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送文本消息
|
// 发送文本消息
|
||||||
func (c *Client) WebWxSendMsg(msg *SendMessage, info *LoginInfo, request *BaseRequest) (*http.Response, error) {
|
func (c *Client) WebWxSendMsg(msg *SendMessage, info *LoginInfo, request *BaseRequest) (*http.Response, error) {
|
||||||
msg.Type = TextMessage
|
msg.Type = TextMessage
|
||||||
path, _ := url.Parse(c.webWxSendMsgUrl)
|
path, _ := url.Parse(c.webWxSendMsgUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("lang", "zh_CN")
|
params.Add("lang", "zh_CN")
|
||||||
params.Add("pass_ticket", info.PassTicket)
|
params.Add("pass_ticket", info.PassTicket)
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.sendMessage(request, path.String(), msg)
|
return c.sendMessage(request, path.String(), msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户的头像
|
// 获取用户的头像
|
||||||
func (c *Client) WebWxGetHeadImg(headImageUrl string) (*http.Response, error) {
|
func (c *Client) WebWxGetHeadImg(headImageUrl string) (*http.Response, error) {
|
||||||
path := c.baseUrl + headImageUrl
|
path := c.baseUrl + headImageUrl
|
||||||
return c.Get(path)
|
return c.Get(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上传文件
|
// 上传文件
|
||||||
func (c *Client) WebWxUploadMedia(file *os.File, request *BaseRequest, info *LoginInfo, forUserName, toUserName, contentType, mediaType string) (*http.Response, error) {
|
func (c *Client) WebWxUploadMedia(file *os.File, request *BaseRequest, info *LoginInfo, forUserName, toUserName, contentType, mediaType string) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxUpLoadMediaUrl)
|
path, _ := url.Parse(c.webWxUpLoadMediaUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("f", "json")
|
params.Add("f", "json")
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
sate, err := file.Stat()
|
sate, err := file.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
buffer := bytes.Buffer{}
|
buffer := bytes.Buffer{}
|
||||||
if _, err := buffer.ReadFrom(file); err != nil {
|
if _, err := buffer.ReadFrom(file); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data := buffer.Bytes()
|
data := buffer.Bytes()
|
||||||
fileMd5 := fmt.Sprintf("%x", md5.Sum(data))
|
fileMd5 := fmt.Sprintf("%x", md5.Sum(data))
|
||||||
cookies := c.Jar.Cookies(path)
|
cookies := c.Jar.Cookies(path)
|
||||||
uploadMediaRequest := map[string]interface{}{
|
uploadMediaRequest := map[string]interface{}{
|
||||||
"UploadType": 2,
|
"UploadType": 2,
|
||||||
"BaseRequest": request,
|
"BaseRequest": request,
|
||||||
"ClientMediaId": time.Now().Unix() * 1e4,
|
"ClientMediaId": time.Now().Unix() * 1e4,
|
||||||
"TotalLen": sate.Size(),
|
"TotalLen": sate.Size(),
|
||||||
"StartPos": 0,
|
"StartPos": 0,
|
||||||
"DataLen": sate.Size(),
|
"DataLen": sate.Size(),
|
||||||
"MediaType": 4,
|
"MediaType": 4,
|
||||||
"FromUserName": forUserName,
|
"FromUserName": forUserName,
|
||||||
"ToUserName": toUserName,
|
"ToUserName": toUserName,
|
||||||
"FileMd5": fileMd5,
|
"FileMd5": fileMd5,
|
||||||
}
|
}
|
||||||
uploadMediaRequestByte, err := json.Marshal(uploadMediaRequest)
|
uploadMediaRequestByte, err := json.Marshal(uploadMediaRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
content := map[string]interface{}{
|
content := map[string]interface{}{
|
||||||
"id": "WU_FILE_0",
|
"id": "WU_FILE_0",
|
||||||
"name": file.Name(),
|
"name": file.Name(),
|
||||||
"type": contentType,
|
"type": contentType,
|
||||||
"lastModifiedDate": time.Now().Format(http.TimeFormat),
|
"lastModifiedDate": time.Now().Format(http.TimeFormat),
|
||||||
"size": sate.Size(),
|
"size": sate.Size(),
|
||||||
"mediatype": mediaType,
|
"mediatype": mediaType,
|
||||||
"webwx_data_ticket": getWebWxDataTicket(cookies),
|
"webwx_data_ticket": getWebWxDataTicket(cookies),
|
||||||
"pass_ticket": info.PassTicket,
|
"pass_ticket": info.PassTicket,
|
||||||
}
|
}
|
||||||
body, err := ToBuffer(content)
|
body, err := ToBuffer(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
writer := multipart.NewWriter(body)
|
writer := multipart.NewWriter(body)
|
||||||
if err = writer.WriteField("uploadmediarequest", string(uploadMediaRequestByte)); err != nil {
|
if err = writer.WriteField("uploadmediarequest", string(uploadMediaRequestByte)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if w, err := writer.CreateFormFile("filename", file.Name()); err != nil {
|
if w, err := writer.CreateFormFile("filename", file.Name()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
if _, err = w.Write(data); err != nil {
|
if _, err = w.Write(data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ct := writer.FormDataContentType()
|
ct := writer.FormDataContentType()
|
||||||
if err = writer.Close(); err != nil {
|
if err = writer.Close(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return c.Post(path.String(), ct, body)
|
return c.Post(path.String(), ct, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送图片
|
// 发送图片
|
||||||
// 这个接口依赖上传文件的接口
|
// 这个接口依赖上传文件的接口
|
||||||
// 发送的图片必须是已经成功上传的图片
|
// 发送的图片必须是已经成功上传的图片
|
||||||
func (c *Client) WebWxSendMsgImg(msg *SendMessage, request *BaseRequest, info *LoginInfo) (*http.Response, error) {
|
func (c *Client) WebWxSendMsgImg(msg *SendMessage, request *BaseRequest, info *LoginInfo) (*http.Response, error) {
|
||||||
msg.Type = ImageMessage
|
msg.Type = ImageMessage
|
||||||
path, _ := url.Parse(c.webWxSendMsgImgUrl)
|
path, _ := url.Parse(c.webWxSendMsgImgUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("fun", "async")
|
params.Add("fun", "async")
|
||||||
params.Add("f", "json")
|
params.Add("f", "json")
|
||||||
params.Add("lang", "zh_CN")
|
params.Add("lang", "zh_CN")
|
||||||
params.Add("pass_ticket", info.PassTicket)
|
params.Add("pass_ticket", info.PassTicket)
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.sendMessage(request, path.String(), msg)
|
return c.sendMessage(request, path.String(), msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送文件信息
|
// 发送文件信息
|
||||||
func (c *Client) WebWxSendAppMsg(msg *SendMessage, request *BaseRequest) (*http.Response, error) {
|
func (c *Client) WebWxSendAppMsg(msg *SendMessage, request *BaseRequest) (*http.Response, error) {
|
||||||
msg.Type = AppMessage
|
msg.Type = AppMessage
|
||||||
path, _ := url.Parse(c.webWxSendAppMsgUrl)
|
path, _ := url.Parse(c.webWxSendAppMsgUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("fun", "async")
|
params.Add("fun", "async")
|
||||||
params.Add("f", "json")
|
params.Add("f", "json")
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.sendMessage(request, path.String(), msg)
|
return c.sendMessage(request, path.String(), msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户重命名接口
|
// 用户重命名接口
|
||||||
func (c *Client) WebWxOplog(request *BaseRequest, remarkName, userName string) (*http.Response, error) {
|
func (c *Client) WebWxOplog(request *BaseRequest, remarkName, userName string) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxOplogUrl)
|
path, _ := url.Parse(c.webWxOplogUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("lang", "zh_CN")
|
params.Add("lang", "zh_CN")
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
content := map[string]interface{}{
|
content := map[string]interface{}{
|
||||||
"BaseRequest": request,
|
"BaseRequest": request,
|
||||||
"CmdId": 2,
|
"CmdId": 2,
|
||||||
"RemarkName": remarkName,
|
"RemarkName": remarkName,
|
||||||
"UserName": userName,
|
"UserName": userName,
|
||||||
}
|
}
|
||||||
body, _ := ToBuffer(content)
|
body, _ := ToBuffer(content)
|
||||||
req, _ := http.NewRequest(http.MethodPost, path.String(), body)
|
req, _ := http.NewRequest(http.MethodPost, path.String(), body)
|
||||||
req.Header.Add("Content-Type", jsonContentType)
|
req.Header.Add("Content-Type", jsonContentType)
|
||||||
return c.Do(req)
|
return c.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加用户为好友接口
|
// 添加用户为好友接口
|
||||||
func (c *Client) WebWxVerifyUser(storage *Storage, info RecommendInfo, verifyContent string) (*http.Response, error) {
|
func (c *Client) WebWxVerifyUser(storage *Storage, info RecommendInfo, verifyContent string) (*http.Response, error) {
|
||||||
loginInfo := storage.LoginInfo
|
loginInfo := storage.LoginInfo
|
||||||
path, _ := url.Parse(c.webWxVerifyUserUrl)
|
path, _ := url.Parse(c.webWxVerifyUserUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("r", strconv.FormatInt(time.Now().Unix(), 10))
|
params.Add("r", strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
params.Add("lang", "zh_CN")
|
params.Add("lang", "zh_CN")
|
||||||
params.Add("pass_ticket", loginInfo.PassTicket)
|
params.Add("pass_ticket", loginInfo.PassTicket)
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
content := map[string]interface{}{
|
content := map[string]interface{}{
|
||||||
"BaseRequest": storage.Request,
|
"BaseRequest": storage.Request,
|
||||||
"Opcode": 3,
|
"Opcode": 3,
|
||||||
"SceneList": [1]int{33},
|
"SceneList": [1]int{33},
|
||||||
"SceneListCount": 1,
|
"SceneListCount": 1,
|
||||||
"VerifyContent": verifyContent,
|
"VerifyContent": verifyContent,
|
||||||
"VerifyUserList": []interface{}{map[string]string{
|
"VerifyUserList": []interface{}{map[string]string{
|
||||||
"Value": info.UserName,
|
"Value": info.UserName,
|
||||||
"VerifyUserTicket": info.Ticket,
|
"VerifyUserTicket": info.Ticket,
|
||||||
}},
|
}},
|
||||||
"VerifyUserListSize": 1,
|
"VerifyUserListSize": 1,
|
||||||
"skey": loginInfo.SKey,
|
"skey": loginInfo.SKey,
|
||||||
}
|
}
|
||||||
body, _ := ToBuffer(content)
|
body, _ := ToBuffer(content)
|
||||||
req, _ := http.NewRequest(http.MethodPost, path.String(), body)
|
req, _ := http.NewRequest(http.MethodPost, path.String(), body)
|
||||||
req.Header.Add("Content-Type", jsonContentType)
|
req.Header.Add("Content-Type", jsonContentType)
|
||||||
return c.Do(req)
|
return c.Do(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取图片消息的图片响应
|
// 获取图片消息的图片响应
|
||||||
func (c *Client) WebWxGetMsgImg(msg *Message, info *LoginInfo) (*http.Response, error) {
|
func (c *Client) WebWxGetMsgImg(msg *Message, info *LoginInfo) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxGetMsgImgUrl)
|
path, _ := url.Parse(c.webWxGetMsgImgUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("MsgID", msg.MsgId)
|
params.Add("MsgID", msg.MsgId)
|
||||||
params.Add("skey", info.SKey)
|
params.Add("skey", info.SKey)
|
||||||
params.Add("type", "slave")
|
params.Add("type", "slave")
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.Get(path.String())
|
return c.Get(path.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取语音消息的语音响应
|
// 获取语音消息的语音响应
|
||||||
func (c *Client) WebWxGetVoice(msg *Message, info *LoginInfo) (*http.Response, error) {
|
func (c *Client) WebWxGetVoice(msg *Message, info *LoginInfo) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxGetVoiceUrl)
|
path, _ := url.Parse(c.webWxGetVoiceUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("msgid", msg.MsgId)
|
params.Add("msgid", msg.MsgId)
|
||||||
params.Add("skey", info.SKey)
|
params.Add("skey", info.SKey)
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.Get(path.String())
|
return c.Get(path.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取视频消息的视频响应
|
// 获取视频消息的视频响应
|
||||||
func (c *Client) WebWxGetVideo(msg *Message, info *LoginInfo) (*http.Response, error) {
|
func (c *Client) WebWxGetVideo(msg *Message, info *LoginInfo) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxGetVideoUrl)
|
path, _ := url.Parse(c.webWxGetVideoUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("msgid", msg.MsgId)
|
params.Add("msgid", msg.MsgId)
|
||||||
params.Add("skey", info.SKey)
|
params.Add("skey", info.SKey)
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.Get(path.String())
|
return c.Get(path.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取文件消息的文件响应
|
// 获取文件消息的文件响应
|
||||||
func (c *Client) WebWxGetMedia(msg *Message, info *LoginInfo) (*http.Response, error) {
|
func (c *Client) WebWxGetMedia(msg *Message, info *LoginInfo) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxGetMediaUrl)
|
path, _ := url.Parse(c.webWxGetMediaUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("sender", msg.FromUserName)
|
params.Add("sender", msg.FromUserName)
|
||||||
params.Add("mediaid", msg.MediaId)
|
params.Add("mediaid", msg.MediaId)
|
||||||
params.Add("encryfilename", msg.EncryFileName)
|
params.Add("encryfilename", msg.EncryFileName)
|
||||||
params.Add("fromuser", fmt.Sprintf("%d", info.WxUin))
|
params.Add("fromuser", fmt.Sprintf("%d", info.WxUin))
|
||||||
params.Add("pass_ticket", info.PassTicket)
|
params.Add("pass_ticket", info.PassTicket)
|
||||||
params.Add("webwx_data_ticket", getWebWxDataTicket(c.Jar.Cookies(path)))
|
params.Add("webwx_data_ticket", getWebWxDataTicket(c.Jar.Cookies(path)))
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.Get(path.String())
|
return c.Get(path.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用户退出
|
// 用户退出
|
||||||
func (c *Client) Logout(info *LoginInfo) (*http.Response, error) {
|
func (c *Client) Logout(info *LoginInfo) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxLogoutUrl)
|
path, _ := url.Parse(c.webWxLogoutUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("redirect", "1")
|
params.Add("redirect", "1")
|
||||||
params.Add("type", "1")
|
params.Add("type", "1")
|
||||||
params.Add("skey", info.SKey)
|
params.Add("skey", info.SKey)
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
return c.Get(path.String())
|
return c.Get(path.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加用户进群聊
|
// 添加用户进群聊
|
||||||
func (c *Client) AddMemberIntoChatRoom(req *BaseRequest, info *LoginInfo, group *Group, friends ...*Friend) (*http.Response, error) {
|
func (c *Client) AddMemberIntoChatRoom(req *BaseRequest, info *LoginInfo, group *Group, friends ...*Friend) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxUpdateChatRoomUrl)
|
path, _ := url.Parse(c.webWxUpdateChatRoomUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("fun", "addmember")
|
params.Add("fun", "addmember")
|
||||||
params.Add("pass_ticket", info.PassTicket)
|
params.Add("pass_ticket", info.PassTicket)
|
||||||
params.Add("lang", "zh_CN")
|
params.Add("lang", "zh_CN")
|
||||||
path.RawQuery = params.Encode()
|
path.RawQuery = params.Encode()
|
||||||
addMemberList := make([]string, 0)
|
addMemberList := make([]string, 0)
|
||||||
for _, friend := range friends {
|
for _, friend := range friends {
|
||||||
addMemberList = append(addMemberList, friend.UserName)
|
addMemberList = append(addMemberList, friend.UserName)
|
||||||
}
|
}
|
||||||
content := map[string]interface{}{
|
content := map[string]interface{}{
|
||||||
"ChatRoomName": group.UserName,
|
"ChatRoomName": group.UserName,
|
||||||
"BaseRequest": req,
|
"BaseRequest": req,
|
||||||
"AddMemberList": strings.Join(addMemberList, ","),
|
"AddMemberList": strings.Join(addMemberList, ","),
|
||||||
}
|
}
|
||||||
buffer, _ := ToBuffer(content)
|
buffer, _ := ToBuffer(content)
|
||||||
return c.Post(path.String(), jsonContentType, buffer)
|
return c.Post(path.String(), jsonContentType, buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从群聊中移除用户
|
// 从群聊中移除用户
|
||||||
func (c *Client) RemoveMemberFromChatRoom(req *BaseRequest, info *LoginInfo, group *Group, friends ...*User) (*http.Response, error) {
|
func (c *Client) RemoveMemberFromChatRoom(req *BaseRequest, info *LoginInfo, group *Group, friends ...*User) (*http.Response, error) {
|
||||||
path, _ := url.Parse(c.webWxUpdateChatRoomUrl)
|
path, _ := url.Parse(c.webWxUpdateChatRoomUrl)
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Add("fun", "delmember")
|
params.Add("fun", "delmember")
|
||||||
params.Add("lang", "zh_CN")
|
params.Add("lang", "zh_CN")
|
||||||
params.Add("pass_ticket", info.PassTicket)
|
params.Add("pass_ticket", info.PassTicket)
|
||||||
delMemberList := make([]string, 0)
|
delMemberList := make([]string, 0)
|
||||||
for _, friend := range friends {
|
for _, friend := range friends {
|
||||||
delMemberList = append(delMemberList, friend.UserName)
|
delMemberList = append(delMemberList, friend.UserName)
|
||||||
}
|
}
|
||||||
content := map[string]interface{}{
|
content := map[string]interface{}{
|
||||||
"ChatRoomName": group.UserName,
|
"ChatRoomName": group.UserName,
|
||||||
"BaseRequest": req,
|
"BaseRequest": req,
|
||||||
"DelMemberList": strings.Join(delMemberList, ","),
|
"DelMemberList": strings.Join(delMemberList, ","),
|
||||||
}
|
}
|
||||||
buffer, _ := ToBuffer(content)
|
buffer, _ := ToBuffer(content)
|
||||||
return c.Post(path.String(), jsonContentType, buffer)
|
return c.Post(path.String(), jsonContentType, buffer)
|
||||||
}
|
}
|
||||||
|
90
stroage.go
90
stroage.go
@ -1,3 +1,93 @@
|
|||||||
package openwechat
|
package openwechat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Storage struct {
|
||||||
|
LoginInfo *LoginInfo
|
||||||
|
Request *BaseRequest
|
||||||
|
Response *WebInitResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
type HotReloadStorage interface {
|
||||||
|
GetCookie() []*http.Cookie
|
||||||
|
GetBaseRequest() *BaseRequest
|
||||||
|
GetLoginInfo() *LoginInfo
|
||||||
|
Dump(cookies []*http.Cookie, req *BaseRequest, info *LoginInfo) error
|
||||||
|
Load() error
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileHotReloadStorage struct {
|
||||||
|
Cookie []*http.Cookie
|
||||||
|
Req *BaseRequest
|
||||||
|
Info *LoginInfo
|
||||||
|
filename string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileHotReloadStorage) Dump(cookies []*http.Cookie, req *BaseRequest, info *LoginInfo) error {
|
||||||
|
f.Cookie = cookies
|
||||||
|
f.Req = req
|
||||||
|
f.Info = info
|
||||||
|
var (
|
||||||
|
file *os.File
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
_, err = os.Stat(f.filename)
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
file, err = os.Create(f.filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if file == nil {
|
||||||
|
file, err = os.Open(f.filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
data, err := json.Marshal(f)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = file.Write(data)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileHotReloadStorage) Load() error {
|
||||||
|
file, err := os.Open(f.filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
if _, err := buffer.ReadFrom(file); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return json.Unmarshal(buffer.Bytes(), f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f FileHotReloadStorage) GetCookie() []*http.Cookie {
|
||||||
|
return f.Cookie
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f FileHotReloadStorage) GetBaseRequest() *BaseRequest {
|
||||||
|
return f.Req
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f FileHotReloadStorage) GetLoginInfo() *LoginInfo {
|
||||||
|
return f.Info
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileHotReloadStorage(filename string) *FileHotReloadStorage {
|
||||||
|
return &FileHotReloadStorage{filename: filename}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user