From c20044dbb1b42fac4387f4e2a188b67cc5e5a87b Mon Sep 17 00:00:00 2001 From: eatMoreApple <15055461510@163.com> Date: Wed, 28 Apr 2021 23:30:52 +0800 Subject: [PATCH] --- README.md | 2 + bot.go | 440 ++++++++++++++++++++++++++++-------------------------- global.go | 138 ++++++++--------- url.go | 160 ++++++++++---------- 4 files changed, 381 insertions(+), 359 deletions(-) diff --git a/README.md b/README.md index 1db6fcc..c379a62 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # openwechat +[![Go Doc](https://pkg.go.dev/badge/github.com/eatMoreApple/openwechat)](https://godoc.org/github.com/eatMoreApple/openwechat) + > golang版个人微信号API, 类似开发公众号一样,开发个人微信号 diff --git a/bot.go b/bot.go index f57c88b..7698029 100644 --- a/bot.go +++ b/bot.go @@ -1,300 +1,316 @@ package openwechat import ( - "errors" - "log" - "net/url" + "errors" + "log" + "net/url" ) type Bot struct { - ScanCallBack func(body []byte) // 扫码回调,可获取扫码用户的头像 - LoginCallBack func(body []byte) // 登陆回调 - UUIDCallback func(uuid string) // 获取UUID的回调函数 - MessageHandler func(msg *Message) // 获取消息成功的handle - GetMessageErrorHandler func(err error) // 获取消息发生错误的handle - isHot bool - err error - exit chan bool - Caller *Caller - self *Self - storage *Storage - hotReloadStorage HotReloadStorage + ScanCallBack func(body []byte) // 扫码回调,可获取扫码用户的头像 + LoginCallBack func(body []byte) // 登陆回调 + UUIDCallback func(uuid string) // 获取UUID的回调函数 + MessageHandler func(msg *Message) // 获取消息成功的handle + GetMessageErrorHandler func(err error) // 获取消息发生错误的handle + isHot bool + err error + exit chan bool + Caller *Caller + self *Self + storage *Storage + hotReloadStorage HotReloadStorage } // 判断当前用户是否正常在线 func (b *Bot) Alive() bool { - if b.self == nil { - return false - } - select { - case <-b.exit: - return false - default: - return true - } + if b.self == nil { + return false + } + select { + case <-b.exit: + return false + default: + return true + } } // 获取当前的用户 +// self, err := bot.GetCurrentUser() +// if err != nil { +// return +// } +// fmt.Println(self.NickName) func (b *Bot) GetCurrentUser() (*Self, error) { - if b.self == nil { - return nil, errors.New("user not login") - } - return b.self, nil + if b.self == nil { + return nil, errors.New("user not login") + } + return b.self, nil } +// 热登录,可实现重复登录, +// retry设置为true可在热登录失效后进行普通登录行为 +// storage := NewJsonFileHotReloadStorage("storage.json") +// err := bot.HotLogin(storage, true) +// fmt.Println(err) func (b *Bot) HotLogin(storage HotReloadStorage, retry ...bool) error { - b.isHot = true - b.hotReloadStorage = storage + b.isHot = true + b.hotReloadStorage = storage - var err error + var err error - // 如果load出错了,就执行正常登陆逻辑 - // 第一次没有数据load都会出错的 - if err = storage.Load(); err != nil { - return b.Login() - } + // 如果load出错了,就执行正常登陆逻辑 + // 第一次没有数据load都会出错的 + if err = storage.Load(); err != nil { + return b.Login() + } - if err = b.hotLoginInit(); err != nil { - return err - } + 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 + // 如果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 { - return err - } - b.Caller.Client.Jar.SetCookies(path, ck) - } - b.storage.LoginInfo = b.hotReloadStorage.GetLoginInfo() - b.storage.Request = b.hotReloadStorage.GetBaseRequest() - return nil + cookies := b.hotReloadStorage.GetCookie() + for u, ck := range cookies { + path, err := url.Parse(u) + if err != nil { + return err + } + b.Caller.Client.Jar.SetCookies(path, ck) + } + b.storage.LoginInfo = b.hotReloadStorage.GetLoginInfo() + b.storage.Request = b.hotReloadStorage.GetBaseRequest() + return nil } // 用户登录 // 该方法会一直阻塞,直到用户扫码登录,或者二维码过期 func (b *Bot) Login() error { - uuid, err := b.Caller.GetLoginUUID() - if err != nil { - return err - } - if b.UUIDCallback != nil { - b.UUIDCallback(uuid) - } - for { - resp, err := b.Caller.CheckLogin(uuid) - if err != nil { - return err - } - switch resp.Code { - case statusSuccess: - return b.handleLogin(resp.Raw) - case statusScanned: - if b.ScanCallBack != nil { - b.ScanCallBack(resp.Raw) - } - case statusTimeout: - return errors.New("login time out") - case statusWait: - continue - } - } + uuid, err := b.Caller.GetLoginUUID() + if err != nil { + return err + } + if b.UUIDCallback != nil { + b.UUIDCallback(uuid) + } + for { + resp, err := b.Caller.CheckLogin(uuid) + if err != nil { + return err + } + switch resp.Code { + case statusSuccess: + return b.handleLogin(resp.Raw) + case statusScanned: + if b.ScanCallBack != nil { + b.ScanCallBack(resp.Raw) + } + case statusTimeout: + return errors.New("login time out") + case statusWait: + continue + } + } } // 用户退出 func (b *Bot) Logout() error { - if b.Alive() { - info := b.storage.LoginInfo - if err := b.Caller.Logout(info); err != nil { - return err - } - b.stopAsyncCALL(errors.New("logout")) - return nil - } - return errors.New("user not login") + if b.Alive() { + info := b.storage.LoginInfo + if err := b.Caller.Logout(info); err != nil { + return err + } + b.stopAsyncCALL(errors.New("logout")) + return nil + } + return errors.New("user not login") } // 登录逻辑 func (b *Bot) handleLogin(data []byte) error { - // 判断是否有登录回调,如果有执行它 - if b.LoginCallBack != nil { - b.LoginCallBack(data) - } - // 获取登录的一些基本的信息 - info, err := b.Caller.GetLoginInfo(data) - if err != nil { - return err - } - // 将LoginInfo存到storage里面 - b.storage.LoginInfo = info + // 判断是否有登录回调,如果有执行它 + if b.LoginCallBack != nil { + b.LoginCallBack(data) + } + // 获取登录的一些基本的信息 + info, err := b.Caller.GetLoginInfo(data) + if err != nil { + return err + } + // 将LoginInfo存到storage里面 + b.storage.LoginInfo = info - // 构建BaseRequest - request := &BaseRequest{ - Uin: info.WxUin, - Sid: info.WxSid, - Skey: info.SKey, - DeviceID: GetRandomDeviceId(), - } + // 构建BaseRequest + request := &BaseRequest{ + Uin: info.WxUin, + Sid: info.WxSid, + Skey: info.SKey, + DeviceID: GetRandomDeviceId(), + } - // 将BaseRequest存到storage里面方便后续调用 - b.storage.Request = request + // 将BaseRequest存到storage里面方便后续调用 + b.storage.Request = request - // 如果是热登陆,则将当前的重要信息写入hotReloadStorage - if b.isHot { - cookies := b.Caller.Client.GetCookieMap() - if err := b.hotReloadStorage.Dump(cookies, request, info); err != nil { - return err - } - } + // 如果是热登陆,则将当前的重要信息写入hotReloadStorage + if b.isHot { + cookies := b.Caller.Client.GetCookieMap() + if err := b.hotReloadStorage.Dump(cookies, request, info); err != nil { + return err + } + } - return b.webInit() + return b.webInit() } func (b *Bot) webInit() error { - req := b.storage.Request - info := b.storage.LoginInfo - // 获取初始化的用户信息和一些必要的参数 - resp, err := b.Caller.WebInit(req) - if err != nil { - return err - } - // 设置当前的用户 - b.self = &Self{Bot: b, User: &resp.User} - b.self.Self = b.self - b.storage.Response = resp + req := b.storage.Request + info := b.storage.LoginInfo + // 获取初始化的用户信息和一些必要的参数 + resp, err := b.Caller.WebInit(req) + if err != nil { + return err + } + // 设置当前的用户 + b.self = &Self{Bot: b, User: &resp.User} + b.self.Self = b.self + b.storage.Response = resp - // 通知手机客户端已经登录 - if err = b.Caller.WebWxStatusNotify(req, resp, info); err != nil { - return err - } - // 开启协程,轮训获取是否有新的消息返回 - go func() { - if b.GetMessageErrorHandler == nil { - b.GetMessageErrorHandler = b.stopAsyncCALL - } - if err := b.asyncCall(); err != nil { - b.GetMessageErrorHandler(err) - } - }() - return nil + // 通知手机客户端已经登录 + if err = b.Caller.WebWxStatusNotify(req, resp, info); err != nil { + return err + } + // 开启协程,轮训获取是否有新的消息返回 + go func() { + if b.GetMessageErrorHandler == nil { + b.GetMessageErrorHandler = b.stopAsyncCALL + } + if err := b.asyncCall(); err != nil { + b.GetMessageErrorHandler(err) + } + }() + return nil } // 轮训请求 // 根据状态码判断是否有新的请求 func (b *Bot) asyncCall() error { - var ( - err error - resp *SyncCheckResponse - ) - for b.Alive() { - // 长轮训检查是否有消息返回 - resp, err = b.Caller.SyncCheck(b.storage.LoginInfo, b.storage.Response) - if err != nil { - return err - } - // 如果不是正常的状态码返回,发生了错误,直接退出 - if !resp.Success() { - return resp - } - // 如果Selector不为0,则获取消息 - if !resp.NorMal() { - if err = b.getNewWechatMessage(); err != nil { - return err - } - } - } - return err + var ( + err error + resp *SyncCheckResponse + ) + for b.Alive() { + // 长轮训检查是否有消息返回 + resp, err = b.Caller.SyncCheck(b.storage.LoginInfo, b.storage.Response) + if err != nil { + return err + } + // 如果不是正常的状态码返回,发生了错误,直接退出 + if !resp.Success() { + return resp + } + // 如果Selector不为0,则获取消息 + if !resp.NorMal() { + if err = b.getNewWechatMessage(); err != nil { + return err + } + } + } + return err } // 当获取消息发生错误时, 默认的错误处理行为 func (b *Bot) stopAsyncCALL(err error) { - b.exit <- true - b.err = err - b.self = nil - log.Printf("exit with : %s", err.Error()) + b.exit <- true + b.err = err + b.self = nil + log.Printf("exit with : %s", err.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 - } - // 更新SyncKey并且重新存入storage - b.storage.Response.SyncKey = resp.SyncKey - // 遍历所有的新的消息,依次处理 - for _, message := range resp.AddMsgList { - // 根据不同的消息类型来进行处理,方便后续统一调用 - message.init(b) - // 调用自定义的处理方法 - if handler := b.MessageHandler; handler != nil { - handler(message) - } - } - return nil + resp, err := b.Caller.WebWxSync(b.storage.Request, b.storage.Response, b.storage.LoginInfo) + if err != nil { + return err + } + // 更新SyncKey并且重新存入storage + b.storage.Response.SyncKey = resp.SyncKey + // 遍历所有的新的消息,依次处理 + for _, message := range resp.AddMsgList { + // 根据不同的消息类型来进行处理,方便后续统一调用 + message.init(b) + // 调用自定义的处理方法 + if handler := b.MessageHandler; handler != nil { + handler(message) + } + } + return nil } // 当消息同步发生了错误或者用户主动在手机上退出,该方法会立即返回,否则会一直阻塞 func (b *Bot) Block() error { - if b.self == nil { - return errors.New("`Block` must be called after user login") - } - if _, closed := <-b.exit; !closed { - return errors.New("can not call `Block` after user logout") - } - close(b.exit) - return nil + if b.self == nil { + return errors.New("`Block` must be called after user login") + } + if _, closed := <-b.exit; !closed { + return errors.New("can not call `Block` after user logout") + } + close(b.exit) + return nil } // 获取当前Bot崩溃的原因 func (b *Bot) CrashReason() error { - return b.err + return b.err } // setter for Bot.MessageHandler func (b *Bot) MessageOnSuccess(h func(msg *Message)) { - b.MessageHandler = h + b.MessageHandler = h } // setter for Bot.GetMessageErrorHandler func (b *Bot) MessageOnError(h func(err error)) { - b.GetMessageErrorHandler = h + b.GetMessageErrorHandler = h } +// Bot的构造方法,需要自己传入Caller func NewBot(caller *Caller) *Bot { - return &Bot{Caller: caller, storage: &Storage{}, exit: make(chan bool)} + return &Bot{Caller: caller, storage: &Storage{}, exit: make(chan bool)} } +// 默认的Bot的构造方法, +// mode不传入默认为openwechat.Normal,详情见mode +// bot := openwechat.DefaultBot(openwechat.Desktop) func DefaultBot(modes ...mode) *Bot { - var m mode - if len(modes) == 0 { - m = Normal - } else { - m = modes[0] - } - urlManager := GetUrlManagerByMode(m) - return NewBot(DefaultCaller(urlManager)) + var m mode + if len(modes) == 0 { + m = Normal + } else { + m = modes[0] + } + urlManager := GetUrlManagerByMode(m) + return NewBot(DefaultCaller(urlManager)) } +// 通过uuid获取登录二维码的url func GetQrcodeUrl(uuid string) string { - return qrcodeUrl + uuid + return qrcodeUrl + uuid } +// 打印登录二维码 func PrintlnQrcodeUrl(uuid string) { - println("访问下面网址扫描二维码登录") - println(GetQrcodeUrl(uuid)) + println("访问下面网址扫描二维码登录") + println(GetQrcodeUrl(uuid)) } diff --git a/global.go b/global.go index 08a2cfd..7f99878 100644 --- a/global.go +++ b/global.go @@ -1,100 +1,102 @@ package openwechat import ( - "errors" - "regexp" + "errors" + "regexp" ) var ( - uuidRegexp = regexp.MustCompile(`uuid = "(.*?)";`) - statusCodeRegexp = regexp.MustCompile(`window.code=(\d+);`) - syncCheckRegexp = regexp.MustCompile(`window.synccheck=\{retcode:"(\d+)",selector:"(\d+)"\}`) - redirectUriRegexp = regexp.MustCompile(`window.redirect_uri="(.*?)"`) + uuidRegexp = regexp.MustCompile(`uuid = "(.*?)";`) + statusCodeRegexp = regexp.MustCompile(`window.code=(\d+);`) + syncCheckRegexp = regexp.MustCompile(`window.synccheck=\{retcode:"(\d+)",selector:"(\d+)"\}`) + redirectUriRegexp = regexp.MustCompile(`window.redirect_uri="(.*?)"`) ) const ( - appId = "wx782c26e4c19acffb" - jsLoginUrl = "https://login.wx.qq.com/jslogin" - qrcodeUrl = "https://login.weixin.qq.com/qrcode/" - loginUrl = "https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login" + appId = "wx782c26e4c19acffb" + jsLoginUrl = "https://login.wx.qq.com/jslogin" + qrcodeUrl = "https://login.weixin.qq.com/qrcode/" + loginUrl = "https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login" - // Normal urls + // Normal urls - baseNormalUrl = "https://wx2.qq.com" - webWxNewLoginPageNormalUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage" - webWxInitNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit" - webWxStatusNotifyNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify" - webWxSyncNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsync" - webWxSendMsgNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg" - webWxGetContactNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact" - webWxSendMsgImgNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg" - webWxSendAppMsgNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendappmsg" - webWxBatchGetContactNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact" - webWxOplogNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxoplog" - webWxVerifyUserNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxverifyuser" - syncCheckNormalUrl = "https://webpush.wx2.qq.com/cgi-bin/mmwebwx-bin/synccheck" - webWxUpLoadMediaNormalUrl = "https://file.wx2.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia" - webWxGetMsgImgNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetmsgimg" - webWxGetVoiceNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetvoice" - webWxGetVideoNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetvideo" - webWxLogoutNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxlogout" - webWxGetMediaNormalUrl = "https://file.wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetmedia" - webWxUpdateChatRoomNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxupdatechatroom" - webWxRevokeMsgNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxrevokemsg" + baseNormalUrl = "https://wx2.qq.com" + webWxNewLoginPageNormalUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage" + webWxInitNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit" + webWxStatusNotifyNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify" + webWxSyncNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsync" + webWxSendMsgNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg" + webWxGetContactNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact" + webWxSendMsgImgNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg" + webWxSendAppMsgNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendappmsg" + webWxBatchGetContactNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact" + webWxOplogNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxoplog" + webWxVerifyUserNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxverifyuser" + syncCheckNormalUrl = "https://webpush.wx2.qq.com/cgi-bin/mmwebwx-bin/synccheck" + webWxUpLoadMediaNormalUrl = "https://file.wx2.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia" + webWxGetMsgImgNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetmsgimg" + webWxGetVoiceNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetvoice" + webWxGetVideoNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetvideo" + webWxLogoutNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxlogout" + webWxGetMediaNormalUrl = "https://file.wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetmedia" + webWxUpdateChatRoomNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxupdatechatroom" + webWxRevokeMsgNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxrevokemsg" - // Desktop urls + // Desktop urls - baseDesktopUrl = "https://wx.qq.com" - webWxNewLoginPageDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?mod=desktop" - webWxInitDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit" - webWxStatusNotifyDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify" - webWxSyncDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync" - webWxSendMsgDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg" - webWxGetContactDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact" - webWxSendMsgImgDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg" - webWxSendAppMsgDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendappmsg" - webWxBatchGetContactDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact" - webWxOplogDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxoplog" - webWxVerifyUserDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxverifyuser" - syncCheckDesktopUrl = "https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck" - webWxUpLoadMediaDesktopUrl = "https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia" - webWxGetMsgImgDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetmsgimg" - webWxGetVoiceDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetvoice" - webWxGetVideoDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetvideo" - webWxLogoutDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout" - webWxGetMediaDesktopUrl = "https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetmedia" - webWxUpdateChatRoomDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxupdatechatroom" - webWxRevokeMsgDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxrevokemsg" + baseDesktopUrl = "https://wx.qq.com" + webWxNewLoginPageDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?mod=desktop" + webWxInitDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit" + webWxStatusNotifyDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify" + webWxSyncDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync" + webWxSendMsgDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg" + webWxGetContactDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact" + webWxSendMsgImgDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg" + webWxSendAppMsgDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendappmsg" + webWxBatchGetContactDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact" + webWxOplogDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxoplog" + webWxVerifyUserDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxverifyuser" + syncCheckDesktopUrl = "https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck" + webWxUpLoadMediaDesktopUrl = "https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia" + webWxGetMsgImgDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetmsgimg" + webWxGetVoiceDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetvoice" + webWxGetVideoDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetvideo" + webWxLogoutDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout" + webWxGetMediaDesktopUrl = "https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetmedia" + webWxUpdateChatRoomDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxupdatechatroom" + webWxRevokeMsgDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxrevokemsg" - jsonContentType = "application/json; charset=utf-8" - uosPatchClientVersion = "2.0.0" - uosPatchExtspam = "Gp8ICJkIEpkICggwMDAwMDAwMRAGGoAI1GiJSIpeO1RZTq9QBKsRbPJdi84ropi16EYI10WB6g74sGmRwSNXjPQnYUKYotKkvLGpshucCaeWZMOylnc6o2AgDX9grhQQx7fm2DJRTyuNhUlwmEoWhjoG3F0ySAWUsEbH3bJMsEBwoB//0qmFJob74ffdaslqL+IrSy7LJ76/G5TkvNC+J0VQkpH1u3iJJs0uUYyLDzdBIQ6Ogd8LDQ3VKnJLm4g/uDLe+G7zzzkOPzCjXL+70naaQ9medzqmh+/SmaQ6uFWLDQLcRln++wBwoEibNpG4uOJvqXy+ql50DjlNchSuqLmeadFoo9/mDT0q3G7o/80P15ostktjb7h9bfNc+nZVSnUEJXbCjTeqS5UYuxn+HTS5nZsPVxJA2O5GdKCYK4x8lTTKShRstqPfbQpplfllx2fwXcSljuYi3YipPyS3GCAqf5A7aYYwJ7AvGqUiR2SsVQ9Nbp8MGHET1GxhifC692APj6SJxZD3i1drSYZPMMsS9rKAJTGz2FEupohtpf2tgXm6c16nDk/cw+C7K7me5j5PLHv55DFCS84b06AytZPdkFZLj7FHOkcFGJXitHkX5cgww7vuf6F3p0yM/W73SoXTx6GX4G6Hg2rYx3O/9VU2Uq8lvURB4qIbD9XQpzmyiFMaytMnqxcZJcoXCtfkTJ6pI7a92JpRUvdSitg967VUDUAQnCXCM/m0snRkR9LtoXAO1FUGpwlp1EfIdCZFPKNnXMeqev0j9W9ZrkEs9ZWcUEexSj5z+dKYQBhIICviYUQHVqBTZSNy22PlUIeDeIs11j7q4t8rD8LPvzAKWVqXE+5lS1JPZkjg4y5hfX1Dod3t96clFfwsvDP6xBSe1NBcoKbkyGxYK0UvPGtKQEE0Se2zAymYDv41klYE9s+rxp8e94/H8XhrL9oGm8KWb2RmYnAE7ry9gd6e8ZuBRIsISlJAE/e8y8xFmP031S6Lnaet6YXPsFpuFsdQs535IjcFd75hh6DNMBYhSfjv456cvhsb99+fRw/KVZLC3yzNSCbLSyo9d9BI45Plma6V8akURQA/qsaAzU0VyTIqZJkPDTzhuCl92vD2AD/QOhx6iwRSVPAxcRFZcWjgc2wCKh+uCYkTVbNQpB9B90YlNmI3fWTuUOUjwOzQRxJZj11NsimjOJ50qQwTTFj6qQvQ1a/I+MkTx5UO+yNHl718JWcR3AXGmv/aa9rD1eNP8ioTGlOZwPgmr2sor2iBpKTOrB83QgZXP+xRYkb4zVC+LoAXEoIa1+zArywlgREer7DLePukkU6wHTkuSaF+ge5Of1bXuU4i938WJHj0t3D8uQxkJvoFi/EYN/7u2P1zGRLV4dHVUsZMGCCtnO6BBigFMAA=" + jsonContentType = "application/json; charset=utf-8" + uosPatchClientVersion = "2.0.0" + uosPatchExtspam = "Gp8ICJkIEpkICggwMDAwMDAwMRAGGoAI1GiJSIpeO1RZTq9QBKsRbPJdi84ropi16EYI10WB6g74sGmRwSNXjPQnYUKYotKkvLGpshucCaeWZMOylnc6o2AgDX9grhQQx7fm2DJRTyuNhUlwmEoWhjoG3F0ySAWUsEbH3bJMsEBwoB//0qmFJob74ffdaslqL+IrSy7LJ76/G5TkvNC+J0VQkpH1u3iJJs0uUYyLDzdBIQ6Ogd8LDQ3VKnJLm4g/uDLe+G7zzzkOPzCjXL+70naaQ9medzqmh+/SmaQ6uFWLDQLcRln++wBwoEibNpG4uOJvqXy+ql50DjlNchSuqLmeadFoo9/mDT0q3G7o/80P15ostktjb7h9bfNc+nZVSnUEJXbCjTeqS5UYuxn+HTS5nZsPVxJA2O5GdKCYK4x8lTTKShRstqPfbQpplfllx2fwXcSljuYi3YipPyS3GCAqf5A7aYYwJ7AvGqUiR2SsVQ9Nbp8MGHET1GxhifC692APj6SJxZD3i1drSYZPMMsS9rKAJTGz2FEupohtpf2tgXm6c16nDk/cw+C7K7me5j5PLHv55DFCS84b06AytZPdkFZLj7FHOkcFGJXitHkX5cgww7vuf6F3p0yM/W73SoXTx6GX4G6Hg2rYx3O/9VU2Uq8lvURB4qIbD9XQpzmyiFMaytMnqxcZJcoXCtfkTJ6pI7a92JpRUvdSitg967VUDUAQnCXCM/m0snRkR9LtoXAO1FUGpwlp1EfIdCZFPKNnXMeqev0j9W9ZrkEs9ZWcUEexSj5z+dKYQBhIICviYUQHVqBTZSNy22PlUIeDeIs11j7q4t8rD8LPvzAKWVqXE+5lS1JPZkjg4y5hfX1Dod3t96clFfwsvDP6xBSe1NBcoKbkyGxYK0UvPGtKQEE0Se2zAymYDv41klYE9s+rxp8e94/H8XhrL9oGm8KWb2RmYnAE7ry9gd6e8ZuBRIsISlJAE/e8y8xFmP031S6Lnaet6YXPsFpuFsdQs535IjcFd75hh6DNMBYhSfjv456cvhsb99+fRw/KVZLC3yzNSCbLSyo9d9BI45Plma6V8akURQA/qsaAzU0VyTIqZJkPDTzhuCl92vD2AD/QOhx6iwRSVPAxcRFZcWjgc2wCKh+uCYkTVbNQpB9B90YlNmI3fWTuUOUjwOzQRxJZj11NsimjOJ50qQwTTFj6qQvQ1a/I+MkTx5UO+yNHl718JWcR3AXGmv/aa9rD1eNP8ioTGlOZwPgmr2sor2iBpKTOrB83QgZXP+xRYkb4zVC+LoAXEoIa1+zArywlgREer7DLePukkU6wHTkuSaF+ge5Of1bXuU4i938WJHj0t3D8uQxkJvoFi/EYN/7u2P1zGRLV4dHVUsZMGCCtnO6BBigFMAA=" ) // 消息类型 const ( - TextMessage = 1 - ImageMessage = 3 - AppMessage = 6 + TextMessage = 1 + ImageMessage = 3 + AppMessage = 6 ) // 登录状态 const ( - statusSuccess = "200" - statusScanned = "201" - statusTimeout = "400" - statusWait = "408" + statusSuccess = "200" + statusScanned = "201" + statusTimeout = "400" + statusWait = "408" ) // errors var ( - noSuchUserFoundError = errors.New("no such user found") + noSuchUserFoundError = errors.New("no such user found") ) +// ALL跟search函数搭配 +// friends.Search(openwechat.ALL, ) const ALL = 0 -// sex +// 性别 const ( - MALE = 1 - FEMALE = 2 + MALE = 1 + FEMALE = 2 ) diff --git a/url.go b/url.go index 519670e..8f11727 100644 --- a/url.go +++ b/url.go @@ -2,79 +2,79 @@ package openwechat // url信息存储 type UrlManager struct { - baseUrl string - webWxNewLoginPageUrl string - webWxInitUrl string - webWxStatusNotifyUrl string - webWxSyncUrl string - webWxSendMsgUrl string - webWxGetContactUrl string - webWxSendMsgImgUrl string - webWxSendAppMsgUrl string - webWxBatchGetContactUrl string - webWxOplogUrl string - webWxVerifyUserUrl string - syncCheckUrl string - webWxUpLoadMediaUrl string - webWxGetMsgImgUrl string - webWxGetVoiceUrl string - webWxGetVideoUrl string - webWxLogoutUrl string - webWxGetMediaUrl string - webWxUpdateChatRoomUrl string - webWxRevokeMsg string + baseUrl string + webWxNewLoginPageUrl string + webWxInitUrl string + webWxStatusNotifyUrl string + webWxSyncUrl string + webWxSendMsgUrl string + webWxGetContactUrl string + webWxSendMsgImgUrl string + webWxSendAppMsgUrl string + webWxBatchGetContactUrl string + webWxOplogUrl string + webWxVerifyUserUrl string + syncCheckUrl string + webWxUpLoadMediaUrl string + webWxGetMsgImgUrl string + webWxGetVoiceUrl string + webWxGetVideoUrl string + webWxLogoutUrl string + webWxGetMediaUrl string + webWxUpdateChatRoomUrl string + webWxRevokeMsg string } var ( - // uos版 - desktop = UrlManager{ - baseUrl: baseDesktopUrl, - webWxNewLoginPageUrl: webWxNewLoginPageDesktopUrl, - webWxInitUrl: webWxInitDesktopUrl, - webWxStatusNotifyUrl: webWxStatusNotifyDesktopUrl, - webWxSyncUrl: webWxSyncDesktopUrl, - webWxSendMsgUrl: webWxSendMsgDesktopUrl, - webWxGetContactUrl: webWxGetContactDesktopUrl, - webWxSendMsgImgUrl: webWxSendMsgImgDesktopUrl, - webWxSendAppMsgUrl: webWxSendAppMsgDesktopUrl, - webWxBatchGetContactUrl: webWxBatchGetContactDesktopUrl, - webWxOplogUrl: webWxOplogDesktopUrl, - webWxVerifyUserUrl: webWxVerifyUserDesktopUrl, - syncCheckUrl: syncCheckDesktopUrl, - webWxUpLoadMediaUrl: webWxUpLoadMediaDesktopUrl, - webWxGetMsgImgUrl: webWxGetMsgImgDesktopUrl, - webWxGetVoiceUrl: webWxGetVoiceDesktopUrl, - webWxGetVideoUrl: webWxGetVideoDesktopUrl, - webWxLogoutUrl: webWxLogoutDesktopUrl, - webWxGetMediaUrl: webWxGetMediaDesktopUrl, - webWxUpdateChatRoomUrl: webWxUpdateChatRoomDesktopUrl, - webWxRevokeMsg: webWxRevokeMsgDesktopUrl, - } + // uos版 + desktop = UrlManager{ + baseUrl: baseDesktopUrl, + webWxNewLoginPageUrl: webWxNewLoginPageDesktopUrl, + webWxInitUrl: webWxInitDesktopUrl, + webWxStatusNotifyUrl: webWxStatusNotifyDesktopUrl, + webWxSyncUrl: webWxSyncDesktopUrl, + webWxSendMsgUrl: webWxSendMsgDesktopUrl, + webWxGetContactUrl: webWxGetContactDesktopUrl, + webWxSendMsgImgUrl: webWxSendMsgImgDesktopUrl, + webWxSendAppMsgUrl: webWxSendAppMsgDesktopUrl, + webWxBatchGetContactUrl: webWxBatchGetContactDesktopUrl, + webWxOplogUrl: webWxOplogDesktopUrl, + webWxVerifyUserUrl: webWxVerifyUserDesktopUrl, + syncCheckUrl: syncCheckDesktopUrl, + webWxUpLoadMediaUrl: webWxUpLoadMediaDesktopUrl, + webWxGetMsgImgUrl: webWxGetMsgImgDesktopUrl, + webWxGetVoiceUrl: webWxGetVoiceDesktopUrl, + webWxGetVideoUrl: webWxGetVideoDesktopUrl, + webWxLogoutUrl: webWxLogoutDesktopUrl, + webWxGetMediaUrl: webWxGetMediaDesktopUrl, + webWxUpdateChatRoomUrl: webWxUpdateChatRoomDesktopUrl, + webWxRevokeMsg: webWxRevokeMsgDesktopUrl, + } - // 网页版 - normal = UrlManager{ - baseUrl: baseNormalUrl, - webWxNewLoginPageUrl: webWxNewLoginPageNormalUrl, - webWxInitUrl: webWxInitNormalUrl, - webWxStatusNotifyUrl: webWxStatusNotifyNormalUrl, - webWxSyncUrl: webWxSyncNormalUrl, - webWxSendMsgUrl: webWxSendMsgNormalUrl, - webWxGetContactUrl: webWxGetContactNormalUrl, - webWxSendMsgImgUrl: webWxSendMsgImgNormalUrl, - webWxSendAppMsgUrl: webWxSendAppMsgNormalUrl, - webWxBatchGetContactUrl: webWxBatchGetContactNormalUrl, - webWxOplogUrl: webWxOplogNormalUrl, - webWxVerifyUserUrl: webWxVerifyUserNormalUrl, - syncCheckUrl: syncCheckNormalUrl, - webWxUpLoadMediaUrl: webWxUpLoadMediaNormalUrl, - webWxGetMsgImgUrl: webWxGetMsgImgNormalUrl, - webWxGetVoiceUrl: webWxGetVoiceNormalUrl, - webWxGetVideoUrl: webWxGetVideoNormalUrl, - webWxLogoutUrl: webWxLogoutNormalUrl, - webWxGetMediaUrl: webWxGetMediaNormalUrl, - webWxUpdateChatRoomUrl: webWxUpdateChatRoomNormalUrl, - webWxRevokeMsg: webWxRevokeMsgNormalUrl, - } + // 网页版 + normal = UrlManager{ + baseUrl: baseNormalUrl, + webWxNewLoginPageUrl: webWxNewLoginPageNormalUrl, + webWxInitUrl: webWxInitNormalUrl, + webWxStatusNotifyUrl: webWxStatusNotifyNormalUrl, + webWxSyncUrl: webWxSyncNormalUrl, + webWxSendMsgUrl: webWxSendMsgNormalUrl, + webWxGetContactUrl: webWxGetContactNormalUrl, + webWxSendMsgImgUrl: webWxSendMsgImgNormalUrl, + webWxSendAppMsgUrl: webWxSendAppMsgNormalUrl, + webWxBatchGetContactUrl: webWxBatchGetContactNormalUrl, + webWxOplogUrl: webWxOplogNormalUrl, + webWxVerifyUserUrl: webWxVerifyUserNormalUrl, + syncCheckUrl: syncCheckNormalUrl, + webWxUpLoadMediaUrl: webWxUpLoadMediaNormalUrl, + webWxGetMsgImgUrl: webWxGetMsgImgNormalUrl, + webWxGetVoiceUrl: webWxGetVoiceNormalUrl, + webWxGetVideoUrl: webWxGetVideoNormalUrl, + webWxLogoutUrl: webWxLogoutNormalUrl, + webWxGetMediaUrl: webWxGetMediaNormalUrl, + webWxUpdateChatRoomUrl: webWxUpdateChatRoomNormalUrl, + webWxRevokeMsg: webWxRevokeMsgNormalUrl, + } ) // mode 类型限制 @@ -82,17 +82,19 @@ type mode string // 向外暴露2种模式 const ( - Normal mode = "normal" - Desktop mode = "desktop" + Normal mode = "normal" + Desktop mode = "desktop" // 突破网页版登录限制 ) +// 通过mode获取完善的UrlManager, +// mode有且仅有两种模式: Normal && Desktop func GetUrlManagerByMode(m mode) UrlManager { - switch m { - case Desktop: - return desktop - case Normal: - return normal - default: - panic("unsupport mode got") - } + switch m { + case Desktop: + return desktop + case Normal: + return normal + default: + panic("unsupport mode got") + } }