支持热登陆 ✨
This commit is contained in:
parent
2761e43c49
commit
a8c646b33d
41
bot.go
41
bot.go
@ -11,11 +11,14 @@ type Bot struct {
|
||||
LoginCallBack func(body []byte)
|
||||
UUIDCallback func(uuid string)
|
||||
MessageHandler func(msg *Message)
|
||||
isHot bool
|
||||
err error
|
||||
exit chan bool
|
||||
Caller *Caller
|
||||
self *Self
|
||||
storage *Storage
|
||||
hotReloadStorage HotReloadStorage
|
||||
mode mode
|
||||
}
|
||||
|
||||
// 判断当前用户是否正常在线
|
||||
@ -39,6 +42,20 @@ func (b *Bot) GetCurrentUser() (*Self, error) {
|
||||
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 {
|
||||
@ -105,8 +122,22 @@ func (b *Bot) login(data []byte) error {
|
||||
|
||||
// 将BaseRequest存到storage里面方便后续调用
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@ -116,7 +147,7 @@ func (b *Bot) login(data []byte) error {
|
||||
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
|
||||
}
|
||||
// 开启协程,轮训获取是否有新的消息返回
|
||||
@ -208,12 +239,6 @@ func DefaultBot(modes ...mode) *Bot {
|
||||
return NewBot(DefaultCaller(urlManager))
|
||||
}
|
||||
|
||||
type Storage struct {
|
||||
LoginInfo *LoginInfo
|
||||
Request *BaseRequest
|
||||
Response *WebInitResponse
|
||||
}
|
||||
|
||||
func GetQrcodeUrl(uuid string) string {
|
||||
return qrcodeUrl + uuid
|
||||
}
|
||||
|
15
bot_test.go
15
bot_test.go
@ -220,3 +220,18 @@ func TestAgreeFriendsAdd(t *testing.T) {
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
10
client.go
10
client.go
@ -40,6 +40,16 @@ func DefaultClient(urlManager UrlManager) *Client {
|
||||
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
|
||||
func (c *Client) GetLoginUUID() (*http.Response, error) {
|
||||
path, _ := url.Parse(jsLoginUrl)
|
||||
|
90
stroage.go
90
stroage.go
@ -1,3 +1,93 @@
|
||||
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