更新底层逻辑代码

This commit is contained in:
eatMoreApple 2021-04-28 11:07:14 +08:00
parent cd802c3a8d
commit 57c397810d
3 changed files with 89 additions and 52 deletions

57
bot.go
View File

@ -2,7 +2,6 @@ package openwechat
import (
"errors"
"fmt"
"log"
"net/url"
)
@ -42,13 +41,37 @@ func (b *Bot) GetCurrentUser() (*Self, error) {
return b.self, nil
}
func (b *Bot) HotLogin(storage HotReloadStorage) error {
func (b *Bot) HotLogin(storage HotReloadStorage, retry ...bool) error {
b.isHot = true
b.hotReloadStorage = storage
if err := storage.Load(); err != nil {
var err error
// 如果load出错了,就执行正常登陆逻辑
// 第一次没有数据load都会出错的
if err = storage.Load(); err != nil {
return b.Login()
}
cookies := storage.GetCookie()
if err = b.hotLoginInit(); err != nil {
return err
}
// 如果webInit出错,则说明可能身份信息已经失效
// 如果retry为True的话,则进行正常登陆
if err = b.webInit(); err != nil {
if len(retry) > 0 {
if retry[0] {
return b.Login()
}
}
}
return err
}
// 热登陆初始化
func (b *Bot) hotLoginInit() error {
cookies := b.hotReloadStorage.GetCookie()
for u, ck := range cookies {
path, err := url.Parse(u)
if err != nil {
@ -56,9 +79,9 @@ func (b *Bot) HotLogin(storage HotReloadStorage) error {
}
b.Caller.Client.Jar.SetCookies(path, ck)
}
b.storage.LoginInfo = storage.GetLoginInfo()
b.storage.Request = storage.GetBaseRequest()
return b.webInit()
b.storage.LoginInfo = b.hotReloadStorage.GetLoginInfo()
b.storage.Request = b.hotReloadStorage.GetBaseRequest()
return nil
}
// 用户登录
@ -78,7 +101,7 @@ func (b *Bot) Login() error {
}
switch resp.Code {
case statusSuccess:
return b.login(resp.Raw)
return b.handleLogin(resp.Raw)
case statusScanned:
if b.ScanCallBack != nil {
b.ScanCallBack(resp.Raw)
@ -104,7 +127,7 @@ func (b *Bot) Logout() error {
}
// 登录逻辑
func (b *Bot) login(data []byte) error {
func (b *Bot) handleLogin(data []byte) error {
// 判断是否有登录回调,如果有执行它
if b.LoginCallBack != nil {
b.LoginCallBack(data)
@ -171,19 +194,18 @@ func (b *Bot) asyncCall() error {
resp *SyncCheckResponse
)
for b.Alive() {
info := b.storage.LoginInfo
response := b.storage.Response
resp, err = b.Caller.SyncCheck(info, response)
// 长轮训检查是否有消息返回
resp, err = b.Caller.SyncCheck(b.storage.LoginInfo, b.storage.Response)
if err != nil {
return err
}
// 如果不是正常的状态码返回,发生了错误,直接退出
if !resp.Success() {
return fmt.Errorf("unknow code got %s", resp.RetCode)
return resp
}
// 如果Selector不为0则获取消息
if !resp.NorMal() {
if err = b.getMessage(); err != nil {
if err = b.getNewWechatMessage(); err != nil {
return err
}
}
@ -199,7 +221,7 @@ func (b *Bot) stopAsyncCALL(err error) {
}
// 获取新的消息
func (b *Bot) getMessage() error {
func (b *Bot) getNewWechatMessage() error {
resp, err := b.Caller.WebWxSync(b.storage.Request, b.storage.Response, b.storage.LoginInfo)
if err != nil {
return err
@ -230,6 +252,11 @@ func (b *Bot) Block() error {
return nil
}
// 获取当前Bot崩溃的原因
func (b *Bot) CrashReason() error {
return b.err
}
func NewBot(caller *Caller) *Bot {
return &Bot{Caller: caller, storage: &Storage{}, exit: make(chan bool)}
}

View File

@ -1,6 +1,9 @@
package openwechat
import "fmt"
import (
"errors"
"fmt"
)
/*
一些网络返回信息的封装
@ -43,25 +46,32 @@ func (b BaseResponse) Ok() bool {
}
func (b BaseResponse) Error() string {
switch b.Ret {
if err := getResponseErrorWithRetCode(b.Ret); err != nil {
return err.Error()
}
return ""
}
func getResponseErrorWithRetCode(code int) error {
switch code {
case 0:
return ""
return nil
case 1:
return "param error"
return errors.New("param error")
case -14:
return "ticket error"
return errors.New("ticket error")
case 1100:
return "not login warn"
return errors.New("not login warn")
case 1101:
return "not login check"
return errors.New("not login check")
case 1102:
return "cookie invalid error"
return errors.New("cookie invalid error")
case 1203:
return "login env error"
return errors.New("login env error")
case 1205:
return "opt too often"
return errors.New("opt too often")
default:
return fmt.Sprintf("base response ret code %d", b.Ret)
return fmt.Errorf("base response ret code %d", code)
}
}

View File

@ -1,54 +1,54 @@
package openwechat
import (
"bytes"
"encoding/json"
"encoding/xml"
"net/http"
"bytes"
"encoding/json"
"encoding/xml"
"net/http"
)
// Http请求的响应结构体封装
type ReturnResponse struct {
*http.Response
err error
*http.Response
err error
}
// Constructor for ReturnResponse
func NewReturnResponse(response *http.Response, err error) *ReturnResponse {
return &ReturnResponse{Response: response, err: err}
return &ReturnResponse{Response: response, err: err}
}
// 获取当前请求的错误
func (r *ReturnResponse) Err() error {
return r.err
return r.err
}
// json序列化
func (r *ReturnResponse) ScanJSON(v interface{}) error {
if data, err := r.ReadAll(); err != nil {
return err
} else {
return json.Unmarshal(data, v)
}
if data, err := r.ReadAll(); err != nil {
return err
} else {
return json.Unmarshal(data, v)
}
}
// xml序列化
func (r *ReturnResponse) ScanXML(v interface{}) error {
if data, err := r.ReadAll(); err != nil {
return err
} else {
return xml.Unmarshal(data, v)
}
if data, err := r.ReadAll(); err != nil {
return err
} else {
return xml.Unmarshal(data, v)
}
}
// 读取请求体
func (r *ReturnResponse) ReadAll() ([]byte, error) {
if r.Err() != nil {
return nil, r.Err()
}
buffer := bytes.Buffer{}
if _, err := buffer.ReadFrom(r.Body); err != nil {
return nil, err
}
return buffer.Bytes(), nil
if r.Err() != nil {
return nil, r.Err()
}
buffer := bytes.Buffer{}
if _, err := buffer.ReadFrom(r.Body); err != nil {
return nil, err
}
return buffer.Bytes(), nil
}