From 9cfa5175186c4b1285ee7fdabd2025bf0dba8760 Mon Sep 17 00:00:00 2001 From: eatMoreApple <15055461510@163.com> Date: Sat, 24 Apr 2021 17:13:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=BD=91=E9=A1=B5=E7=89=88?= =?UTF-8?q?=E5=92=8Cuos=E7=89=88=E5=88=87=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot.go | 319 +++++++++++++++++++++++++++------------------------- bot_test.go | 26 ++++- caller.go | 4 +- client.go | 51 +++++---- global.go | 77 ++++++++----- url.go | 92 +++++++++++++++ 6 files changed, 355 insertions(+), 214 deletions(-) create mode 100644 url.go diff --git a/bot.go b/bot.go index 3918f03..377dd82 100644 --- a/bot.go +++ b/bot.go @@ -1,216 +1,223 @@ package openwechat import ( - "errors" - "fmt" + "errors" + "fmt" ) type Bot struct { - Caller *Caller - self *Self - storage *Storage - ScanCallBack func(body []byte) - LoginCallBack func(body []byte) - UUIDCallback func(uuid string) - MessageHandler func(msg *Message) - err error - exit chan bool + Caller *Caller + self *Self + storage *Storage + ScanCallBack func(body []byte) + LoginCallBack func(body []byte) + UUIDCallback func(uuid string) + MessageHandler func(msg *Message) + err error + exit chan bool } -// 判断当前用户是否正常在线MessageHandler +// 判断当前用户是否正常在线 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 + } } // 获取当前的用户 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 } // 用户登录 // 该方法会一直阻塞,直到用户扫码登录,或者二维码过期 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.login(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.login(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) login(data []byte) error { - // 判断是否有登录回调,如果有执行它 - if b.LoginCallBack != nil { - b.LoginCallBack(data) - } - // 获取登录的一些基本的信息 - info, err := b.Caller.GetLoginInfo(data) - if err != nil { - return err - } + // 判断是否有登录回调,如果有执行它 + if b.LoginCallBack != nil { + b.LoginCallBack(data) + } + // 获取登录的一些基本的信息 + info, err := b.Caller.GetLoginInfo(data) + if err != nil { + return err + } - // 将LoginInfo存到storage里面 - b.storage.LoginInfo = info + // 将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 - // 获取初始化的用户信息和一些必要的参数 - resp, err := b.Caller.WebInit(request) - if err != nil { - return err - } - // 设置当前的用户 - b.self = &Self{Bot: b, User: &resp.User} - b.self.Self = b.self - b.storage.Response = resp + // 将BaseRequest存到storage里面方便后续调用 + b.storage.Request = request + // 获取初始化的用户信息和一些必要的参数 + resp, err := b.Caller.WebInit(request) + 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(request, resp, info); err != nil { - return err - } - // 开启协程,轮训获取是否有新的消息返回 - go func() { - b.stopAsyncCALL(b.asyncCall()) - }() - return nil + // 通知手机客户端已经登录 + if err = b.Caller.WebWxStatusNotify(request, resp, info); err != nil { + return err + } + // 开启协程,轮训获取是否有新的消息返回 + go func() { + b.stopAsyncCALL(b.asyncCall()) + }() + return nil } // 轮训请求 // 根据状态码判断是否有新的请求 func (b *Bot) asyncCall() error { - var ( - err error - resp *SyncCheckResponse - ) - for b.Alive() { - info := b.storage.LoginInfo - response := b.storage.Response - resp, err = b.Caller.SyncCheck(info, response) - if err != nil { - return err - } - // 如果不是正常的状态码返回,发生了错误,直接退出 - if !resp.Success() { - return fmt.Errorf("unknow code got %s", resp.RetCode) - } - // 如果Selector不为0,则获取消息 - if !resp.NorMal() { - if err = b.getMessage(); err != nil { - return err - } - } - } - return err + var ( + err error + resp *SyncCheckResponse + ) + for b.Alive() { + info := b.storage.LoginInfo + response := b.storage.Response + resp, err = b.Caller.SyncCheck(info, response) + if err != nil { + return err + } + // 如果不是正常的状态码返回,发生了错误,直接退出 + if !resp.Success() { + return fmt.Errorf("unknow code got %s", resp.RetCode) + } + // 如果Selector不为0,则获取消息 + if !resp.NorMal() { + if err = b.getMessage(); err != nil { + return err + } + } + } + return err } func (b *Bot) stopAsyncCALL(err error) { - b.exit <- true - b.err = err - b.self = nil + b.exit <- true + b.err = err + b.self = nil } // 获取新的消息 func (b *Bot) getMessage() 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 } 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)} } -func DefaultBot() *Bot { - return NewBot(DefaultCaller()) +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)) } type Storage struct { - LoginInfo *LoginInfo - Request *BaseRequest - Response *WebInitResponse + LoginInfo *LoginInfo + Request *BaseRequest + Response *WebInitResponse } 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/bot_test.go b/bot_test.go index cce3f3f..df3fa91 100644 --- a/bot_test.go +++ b/bot_test.go @@ -2,12 +2,20 @@ package openwechat import "testing" -func defaultBot() *Bot { - bot := DefaultBot() +func defaultBot(modes ...mode) *Bot { + bot := DefaultBot(modes...) bot.UUIDCallback = PrintlnQrcodeUrl return bot } +func getSelf(modes ...mode) (*Self, error) { + bot := defaultBot(modes...) + if err := bot.Login(); err != nil { + return nil, err + } + return bot.GetCurrentUser() +} + func TestBotLogin(t *testing.T) { bot := defaultBot() if err := bot.Login(); err != nil { @@ -21,3 +29,17 @@ func TestBotLogin(t *testing.T) { } t.Log(self.NickName) } + +func TestFriend(t *testing.T) { + self, err := getSelf() + if err != nil { + t.Error(err) + return + } + friends, err := self.Friends() + if err != nil { + t.Error(err) + return + } + t.Log(friends) +} diff --git a/caller.go b/caller.go index 3c99034..f5705b5 100644 --- a/caller.go +++ b/caller.go @@ -17,8 +17,8 @@ func NewCaller(client *Client) *Caller { } // Default Constructor for Caller -func DefaultCaller() *Caller { - return NewCaller(DefaultClient()) +func DefaultCaller(urlManager UrlManager) *Caller { + return NewCaller(DefaultClient(urlManager)) } // 获取登录的uuid diff --git a/client.go b/client.go index 3c7b941..d312cb6 100644 --- a/client.go +++ b/client.go @@ -18,15 +18,18 @@ import ( // http请求客户端 // 客户端需要维持Session会话 // 并且客户端不允许跳转 -type Client struct{ *http.Client } +type Client struct { + *http.Client + UrlManager +} -func NewClient(client *http.Client) *Client { - return &Client{Client: client} +func NewClient(client *http.Client, urlManager UrlManager) *Client { + return &Client{Client: client, UrlManager: urlManager} } // 自动存储cookie // 设置客户端不自动跳转 -func DefaultClient() *Client { +func DefaultClient(urlManager UrlManager) *Client { jar, _ := cookiejar.New(nil) client := &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { @@ -34,7 +37,7 @@ func DefaultClient() *Client { }, Jar: jar, } - return NewClient(client) + return NewClient(client, urlManager) } // 获取登录的uuid @@ -42,7 +45,7 @@ func (c *Client) GetLoginUUID() (*http.Response, error) { path, _ := url.Parse(jsLoginUrl) params := url.Values{} params.Add("appid", appId) - params.Add("redirect_uri", webWxNewLoginPage) + params.Add("redirect_uri", c.webWxNewLoginPageUrl) params.Add("fun", "new") params.Add("lang", "zh_CN") params.Add("_", strconv.FormatInt(time.Now().Unix(), 10)) @@ -80,7 +83,7 @@ func (c *Client) GetLoginInfo(path string) (*http.Response, error) { // 请求获取初始化信息 func (c *Client) WebInit(request *BaseRequest) (*http.Response, error) { - path, _ := url.Parse(webWxInitUrl) + path, _ := url.Parse(c.webWxInitUrl) params := url.Values{} params.Add("_", fmt.Sprintf("%d", time.Now().Unix())) path.RawQuery = params.Encode() @@ -94,7 +97,7 @@ func (c *Client) WebInit(request *BaseRequest) (*http.Response, error) { // 通知手机已登录 func (c *Client) WebWxStatusNotify(request *BaseRequest, response *WebInitResponse, info *LoginInfo) (*http.Response, error) { - path, _ := url.Parse(webWxStatusNotifyUrl) + path, _ := url.Parse(c.webWxStatusNotifyUrl) params := url.Values{} params.Add("lang", "zh_CN") params.Add("pass_ticket", info.PassTicket) @@ -115,7 +118,7 @@ func (c *Client) WebWxStatusNotify(request *BaseRequest, response *WebInitRespon // 异步检查是否有新的消息返回 func (c *Client) SyncCheck(info *LoginInfo, response *WebInitResponse) (*http.Response, error) { - path, _ := url.Parse(syncCheckUrl) + path, _ := url.Parse(c.syncCheckUrl) params := url.Values{} params.Add("r", strconv.FormatInt(time.Now().Unix(), 10)) params.Add("skey", info.SKey) @@ -138,7 +141,7 @@ func (c *Client) SyncCheck(info *LoginInfo, response *WebInitResponse) (*http.Re // 获取联系人信息 func (c *Client) WebWxGetContact(info *LoginInfo) (*http.Response, error) { - path, _ := url.Parse(webWxGetContactUrl) + path, _ := url.Parse(c.webWxGetContactUrl) params := url.Values{} params.Add("r", strconv.FormatInt(time.Now().Unix(), 10)) params.Add("skey", info.SKey) @@ -149,7 +152,7 @@ func (c *Client) WebWxGetContact(info *LoginInfo) (*http.Response, error) { // 获取联系人详情 func (c *Client) WebWxBatchGetContact(members Members, request *BaseRequest) (*http.Response, error) { - path, _ := url.Parse(webWxBatchGetContactUrl) + path, _ := url.Parse(c.webWxBatchGetContactUrl) params := url.Values{} params.Add("type", "ex") params.Add("r", strconv.FormatInt(time.Now().Unix(), 10)) @@ -168,7 +171,7 @@ func (c *Client) WebWxBatchGetContact(members Members, request *BaseRequest) (*h // 获取消息接口 func (c *Client) WebWxSync(request *BaseRequest, response *WebInitResponse, info *LoginInfo) (*http.Response, error) { - path, _ := url.Parse(webWxSyncUrl) + path, _ := url.Parse(c.webWxSyncUrl) params := url.Values{} params.Add("sid", info.WxSid) params.Add("skey", info.SKey) @@ -202,7 +205,7 @@ func (c *Client) sendMessage(request *BaseRequest, url string, msg *SendMessage) // 发送文本消息 func (c *Client) WebWxSendMsg(msg *SendMessage, info *LoginInfo, request *BaseRequest) (*http.Response, error) { msg.Type = TextMessage - path, _ := url.Parse(webWxSendMsgUrl) + path, _ := url.Parse(c.webWxSendMsgUrl) params := url.Values{} params.Add("lang", "zh_CN") params.Add("pass_ticket", info.PassTicket) @@ -212,13 +215,13 @@ func (c *Client) WebWxSendMsg(msg *SendMessage, info *LoginInfo, request *BaseRe // 获取用户的头像 func (c *Client) WebWxGetHeadImg(headImageUrl string) (*http.Response, error) { - path := baseUrl + headImageUrl + path := c.baseUrl + headImageUrl return c.Get(path) } // 上传文件 func (c *Client) WebWxUploadMedia(file *os.File, request *BaseRequest, info *LoginInfo, forUserName, toUserName, contentType, mediaType string) (*http.Response, error) { - path, _ := url.Parse(webWxUpLoadMediaUrl) + path, _ := url.Parse(c.webWxUpLoadMediaUrl) params := url.Values{} params.Add("f", "json") path.RawQuery = params.Encode() @@ -286,7 +289,7 @@ func (c *Client) WebWxUploadMedia(file *os.File, request *BaseRequest, info *Log // 发送的图片必须是已经成功上传的图片 func (c *Client) WebWxSendMsgImg(msg *SendMessage, request *BaseRequest, info *LoginInfo) (*http.Response, error) { msg.Type = ImageMessage - path, _ := url.Parse(webWxSendMsgImgUrl) + path, _ := url.Parse(c.webWxSendMsgImgUrl) params := url.Values{} params.Add("fun", "async") params.Add("f", "json") @@ -299,7 +302,7 @@ func (c *Client) WebWxSendMsgImg(msg *SendMessage, request *BaseRequest, info *L // 发送文件信息 func (c *Client) WebWxSendAppMsg(msg *SendMessage, request *BaseRequest) (*http.Response, error) { msg.Type = AppMessage - path, _ := url.Parse(webWxSendAppMsgUrl) + path, _ := url.Parse(c.webWxSendAppMsgUrl) params := url.Values{} params.Add("fun", "async") params.Add("f", "json") @@ -309,7 +312,7 @@ func (c *Client) WebWxSendAppMsg(msg *SendMessage, request *BaseRequest) (*http. // 用户重命名接口 func (c *Client) WebWxOplog(request *BaseRequest, remarkName, userName string) (*http.Response, error) { - path, _ := url.Parse(webWxOplogUrl) + path, _ := url.Parse(c.webWxOplogUrl) params := url.Values{} params.Add("lang", "zh_CN") path.RawQuery = params.Encode() @@ -328,7 +331,7 @@ func (c *Client) WebWxOplog(request *BaseRequest, remarkName, userName string) ( // 添加用户为好友接口 func (c *Client) WebWxVerifyUser(storage *Storage, info RecommendInfo, verifyContent string) (*http.Response, error) { loginInfo := storage.LoginInfo - path, _ := url.Parse(webWxVerifyUserUrl) + path, _ := url.Parse(c.webWxVerifyUserUrl) params := url.Values{} params.Add("r", strconv.FormatInt(time.Now().Unix(), 10)) params.Add("lang", "zh_CN") @@ -355,7 +358,7 @@ func (c *Client) WebWxVerifyUser(storage *Storage, info RecommendInfo, verifyCon // 获取图片消息的图片响应 func (c *Client) WebWxGetMsgImg(msg *Message, info *LoginInfo) (*http.Response, error) { - path, _ := url.Parse(webWxGetMsgImgUrl) + path, _ := url.Parse(c.webWxGetMsgImgUrl) params := url.Values{} params.Add("MsgID", msg.MsgId) params.Add("skey", info.SKey) @@ -366,7 +369,7 @@ func (c *Client) WebWxGetMsgImg(msg *Message, info *LoginInfo) (*http.Response, // 获取语音消息的语音响应 func (c *Client) WebWxGetVoice(msg *Message, info *LoginInfo) (*http.Response, error) { - path, _ := url.Parse(webWxGetVoiceUrl) + path, _ := url.Parse(c.webWxGetVoiceUrl) params := url.Values{} params.Add("msgid", msg.MsgId) params.Add("skey", info.SKey) @@ -376,7 +379,7 @@ func (c *Client) WebWxGetVoice(msg *Message, info *LoginInfo) (*http.Response, e // 获取视频消息的视频响应 func (c *Client) WebWxGetVideo(msg *Message, info *LoginInfo) (*http.Response, error) { - path, _ := url.Parse(webWxGetVideoUrl) + path, _ := url.Parse(c.webWxGetVideoUrl) params := url.Values{} params.Add("msgid", msg.MsgId) params.Add("skey", info.SKey) @@ -386,7 +389,7 @@ func (c *Client) WebWxGetVideo(msg *Message, info *LoginInfo) (*http.Response, e // 获取文件消息的文件响应 func (c *Client) WebWxGetMedia(msg *Message, info *LoginInfo) (*http.Response, error) { - path, _ := url.Parse(webWxGetMediaUrl) + path, _ := url.Parse(c.webWxGetMediaUrl) params := url.Values{} params.Add("sender", msg.FromUserName) params.Add("mediaid", msg.MediaId) @@ -400,7 +403,7 @@ func (c *Client) WebWxGetMedia(msg *Message, info *LoginInfo) (*http.Response, e // 用户退出 func (c *Client) Logout(info *LoginInfo) (*http.Response, error) { - path, _ := url.Parse(webWxLogoutUrl) + path, _ := url.Parse(c.webWxLogoutUrl) params := url.Values{} params.Add("redirect", "1") params.Add("type", "1") diff --git a/global.go b/global.go index 9b74fd7..ce834a9 100644 --- a/global.go +++ b/global.go @@ -13,30 +13,54 @@ var ( ) const ( - appId = "wx782c26e4c19acffb" + 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" - baseUrl = "https://wx.qq.com" - jsLoginUrl = "https://login.wx.qq.com/jslogin" - webWxNewLoginPage = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?mod=desktop" - qrcodeUrl = "https://login.weixin.qq.com/qrcode/" - loginUrl = "https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login" - webWxInitUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit" - webWxStatusNotifyUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify" - webWxSyncUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync" - webWxSendMsgUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg" - webWxGetContactUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact" - webWxSendMsgImgUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg" - webWxSendAppMsgUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendappmsg" - webWxBatchGetContactUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact" - webWxOplogUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxoplog" - webWxVerifyUserUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxverifyuser" - syncCheckUrl = "https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck" - webWxUpLoadMediaUrl = "https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia" - webWxGetMsgImgUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetmsgimg" - webWxGetVoiceUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetvoice" - webWxGetVideoUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetvideo" - webWxLogoutUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout" - webWxGetMediaUrl = "https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetmedia" + // 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" + + // 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" jsonContentType = "application/json; charset=utf-8" uosPatchClientVersion = "2.0.0" @@ -70,10 +94,3 @@ const ( MALE = 1 FEMALE = 2 ) - -type mode string - -const ( - normal mode = "normal" - desk mode = "desk" -) diff --git a/url.go b/url.go new file mode 100644 index 0000000..42cf035 --- /dev/null +++ b/url.go @@ -0,0 +1,92 @@ +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 +} + +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, + } + + // 网页版 + 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, + } +) + +// mode 类型限制 +type mode string + +// 向外暴露2种模式 +const ( + Normal mode = "normal" + Desktop mode = "desktop" +) + +func GetUrlManagerByMode(m mode) UrlManager { + switch m { + case Desktop: + return desktop + case Normal: + return normal + default: + panic("unsupport mode got") + } +}