优化内部host切换逻辑

This commit is contained in:
eatMoreApple 2021-05-11 18:00:54 +08:00
parent 5d8dea264c
commit 0c6fa63391
5 changed files with 125 additions and 192 deletions

7
bot.go
View File

@ -308,13 +308,14 @@ func DefaultBot(modes ...mode) *Bot {
} else { } else {
m = modes[0] m = modes[0]
} }
urlManager := GetUrlManagerByMode(m) caller := DefaultCaller()
return NewBot(DefaultCaller(urlManager)) caller.Client.mode = m
return NewBot(caller)
} }
// 通过uuid获取登录二维码的url // 通过uuid获取登录二维码的url
func GetQrcodeUrl(uuid string) string { func GetQrcodeUrl(uuid string) string {
return qrcodeUrl + uuid return qrcode + uuid
} }
// 打印登录二维码 // 打印登录二维码

View File

@ -3,8 +3,8 @@ package openwechat
import ( import (
"errors" "errors"
"net/http" "net/http"
"net/url"
"os" "os"
"strings"
) )
// 调用请求和解析请求 // 调用请求和解析请求
@ -19,8 +19,8 @@ func NewCaller(client *Client) *Caller {
} }
// Default Constructor for Caller // Default Constructor for Caller
func DefaultCaller(urlManager UrlManager) *Caller { func DefaultCaller() *Caller {
return NewCaller(DefaultClient(urlManager)) return NewCaller(DefaultClient())
} }
// 获取登录的uuid // 获取登录的uuid
@ -71,13 +71,17 @@ func (c *Caller) GetLoginInfo(body []byte) (*LoginInfo, error) {
if len(results) != 2 { if len(results) != 2 {
return nil, errors.New("redirect url does not match") return nil, errors.New("redirect url does not match")
} }
path := string(results[1]) path, err := url.Parse(string(results[1]))
if strings.Contains(path, "wx2") { if err != nil {
c.Client.UrlManager = normal return nil, err
} else {
c.Client.UrlManager = desktop
} }
resp := NewReturnResponse(c.Client.GetLoginInfo(path)) host := path.Host
domain, err := getDomainByHost(host)
if err != nil {
return nil, err
}
c.Client.domain = domain
resp := NewReturnResponse(c.Client.GetLoginInfo(path.String()))
if resp.Err() != nil { if resp.Err() != nil {
return nil, resp.Err() return nil, resp.Err()
} }

View File

@ -40,18 +40,19 @@ func (u UserAgentHook) AfterRequest(response *http.Response, err error) {}
type Client struct { type Client struct {
HttpHooks HttpHooks HttpHooks HttpHooks
*http.Client *http.Client
UrlManager domain *domain
mode mode
mu sync.Mutex mu sync.Mutex
cookies map[string][]*http.Cookie cookies map[string][]*http.Cookie
} }
func NewClient(client *http.Client, urlManager UrlManager) *Client { func NewClient(client *http.Client) *Client {
return &Client{Client: client, UrlManager: urlManager} return &Client{Client: client}
} }
// 自动存储cookie // 自动存储cookie
// 设置客户端不自动跳转 // 设置客户端不自动跳转
func DefaultClient(urlManager UrlManager) *Client { func DefaultClient() *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 {
@ -59,7 +60,7 @@ func DefaultClient(urlManager UrlManager) *Client {
}, },
Jar: jar, Jar: jar,
} }
c := NewClient(client, urlManager) c := NewClient(client)
c.AddHttpHook(UserAgentHook{}) c.AddHttpHook(UserAgentHook{})
return c return c
} }
@ -106,13 +107,19 @@ func (c *Client) GetCookieMap() map[string][]*http.Cookie {
// 获取登录的uuid // 获取登录的uuid
func (c *Client) GetLoginUUID() (*http.Response, error) { func (c *Client) GetLoginUUID() (*http.Response, error) {
path, _ := url.Parse(jsLoginUrl) path, _ := url.Parse(jslogin)
params := url.Values{} params := url.Values{}
redirectUrl, _ := url.Parse(webwxnewloginpage)
if c.mode == Desktop {
p := url.Values{"mod": {"desktop"}}
redirectUrl.RawQuery = p.Encode()
}
params.Add("redirect_uri", redirectUrl.String())
params.Add("appid", appId) params.Add("appid", appId)
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()
req, _ := http.NewRequest(http.MethodGet, path.String(), nil) req, _ := http.NewRequest(http.MethodGet, path.String(), nil)
return c.Do(req) return c.Do(req)
@ -120,13 +127,13 @@ func (c *Client) GetLoginUUID() (*http.Response, error) {
// 获取登录的二维吗 // 获取登录的二维吗
func (c *Client) GetLoginQrcode(uuid string) (*http.Response, error) { func (c *Client) GetLoginQrcode(uuid string) (*http.Response, error) {
path := qrcodeUrl + uuid path := qrcode + 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(login)
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))
@ -142,14 +149,16 @@ func (c *Client) CheckLogin(uuid string) (*http.Response, error) {
// 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)
if c.mode == Desktop {
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.domain.BaseHost + webwxinit)
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()
@ -165,7 +174,7 @@ func (c *Client) WebInit(request *BaseRequest) (*http.Response, error) {
// 通知手机已登录 // 通知手机已登录
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.domain.BaseHost + webwxstatusnotify)
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)
@ -186,7 +195,7 @@ func (c *Client) WebWxStatusNotify(request *BaseRequest, response *WebInitRespon
// 异步检查是否有新的消息返回 // 异步检查是否有新的消息返回
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.domain.SyncHost + synccheck)
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)
@ -209,7 +218,7 @@ func (c *Client) SyncCheck(info *LoginInfo, response *WebInitResponse) (*http.Re
// 获取联系人信息 // 获取联系人信息
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.domain.BaseHost + webwxgetcontact)
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)
@ -221,7 +230,7 @@ func (c *Client) WebWxGetContact(info *LoginInfo) (*http.Response, error) {
// 获取联系人详情 // 获取联系人详情
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.domain.BaseHost + webwxbatchgetcontact)
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))
@ -240,7 +249,7 @@ func (c *Client) WebWxBatchGetContact(members Members, request *BaseRequest) (*h
// 获取消息接口 // 获取消息接口
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.domain.BaseHost + webwxsync)
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)
@ -274,7 +283,7 @@ func (c *Client) sendMessage(request *BaseRequest, url string, msg *SendMessage)
// 发送文本消息 // 发送文本消息
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.domain.BaseHost + webwxsendmsg)
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)
@ -284,7 +293,7 @@ func (c *Client) WebWxSendMsg(msg *SendMessage, info *LoginInfo, request *BaseRe
// 获取用户的头像 // 获取用户的头像
func (c *Client) WebWxGetHeadImg(headImageUrl string) (*http.Response, error) { func (c *Client) WebWxGetHeadImg(headImageUrl string) (*http.Response, error) {
path := c.baseUrl + headImageUrl path := c.domain.BaseHost + headImageUrl
req, _ := http.NewRequest(http.MethodGet, path, nil) req, _ := http.NewRequest(http.MethodGet, path, nil)
return c.Do(req) return c.Do(req)
} }
@ -319,7 +328,7 @@ func (c *Client) WebWxUploadMediaByChunk(file *os.File, request *BaseRequest, in
// 获取文件的类型 // 获取文件的类型
mediaType := getMessageType(sate.Name()) mediaType := getMessageType(sate.Name())
path, _ := url.Parse(c.webWxUpLoadMediaUrl) path, _ := url.Parse(c.domain.FileHost + webwxuploadmedia)
params := url.Values{} params := url.Values{}
params.Add("f", "json") params.Add("f", "json")
@ -435,7 +444,7 @@ func (c *Client) WebWxUploadMediaByChunk(file *os.File, request *BaseRequest, in
// 发送的图片必须是已经成功上传的图片 // 发送的图片必须是已经成功上传的图片
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.domain.BaseHost + webwxsendmsgimg)
params := url.Values{} params := url.Values{}
params.Add("fun", "async") params.Add("fun", "async")
params.Add("f", "json") params.Add("f", "json")
@ -448,7 +457,7 @@ func (c *Client) WebWxSendMsgImg(msg *SendMessage, request *BaseRequest, info *L
// 发送文件信息 // 发送文件信息
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.domain.BaseHost + webwxsendappmsg)
params := url.Values{} params := url.Values{}
params.Add("fun", "async") params.Add("fun", "async")
params.Add("f", "json") params.Add("f", "json")
@ -458,7 +467,7 @@ func (c *Client) WebWxSendAppMsg(msg *SendMessage, request *BaseRequest) (*http.
// 用户重命名接口 // 用户重命名接口
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.domain.BaseHost + webwxoplog)
params := url.Values{} params := url.Values{}
params.Add("lang", "zh_CN") params.Add("lang", "zh_CN")
path.RawQuery = params.Encode() path.RawQuery = params.Encode()
@ -477,7 +486,7 @@ func (c *Client) WebWxOplog(request *BaseRequest, remarkName, userName string) (
// 添加用户为好友接口 // 添加用户为好友接口
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.domain.BaseHost + webwxverifyuser)
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")
@ -504,7 +513,7 @@ func (c *Client) WebWxVerifyUser(storage *Storage, info RecommendInfo, verifyCon
// 获取图片消息的图片响应 // 获取图片消息的图片响应
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.domain.BaseHost + webwxgetmsgimg)
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)
@ -516,7 +525,7 @@ func (c *Client) WebWxGetMsgImg(msg *Message, info *LoginInfo) (*http.Response,
// 获取语音消息的语音响应 // 获取语音消息的语音响应
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.domain.BaseHost + webwxgetvoice)
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)
@ -527,7 +536,7 @@ func (c *Client) WebWxGetVoice(msg *Message, info *LoginInfo) (*http.Response, e
// 获取视频消息的视频响应 // 获取视频消息的视频响应
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.domain.BaseHost + webwxgetvideo)
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)
@ -538,7 +547,7 @@ func (c *Client) WebWxGetVideo(msg *Message, info *LoginInfo) (*http.Response, e
// 获取文件消息的文件响应 // 获取文件消息的文件响应
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.domain.FileHost + webwxgetmedia)
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)
@ -553,7 +562,7 @@ func (c *Client) WebWxGetMedia(msg *Message, info *LoginInfo) (*http.Response, e
// 用户退出 // 用户退出
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.domain.BaseHost + webwxlogout)
params := url.Values{} params := url.Values{}
params.Add("redirect", "1") params.Add("redirect", "1")
params.Add("type", "1") params.Add("type", "1")
@ -565,7 +574,7 @@ func (c *Client) Logout(info *LoginInfo) (*http.Response, error) {
// 添加用户进群聊 // 添加用户进群聊
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.domain.BaseHost + webwxupdatechatroom)
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)
@ -588,7 +597,7 @@ func (c *Client) AddMemberIntoChatRoom(req *BaseRequest, info *LoginInfo, group
// 从群聊中移除用户 // 从群聊中移除用户
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.domain.BaseHost + webwxupdatechatroom)
params := url.Values{} params := url.Values{}
params.Add("fun", "delmember") params.Add("fun", "delmember")
params.Add("lang", "zh_CN") params.Add("lang", "zh_CN")
@ -617,14 +626,14 @@ func (c *Client) WebWxRevokeMsg(msg *SentMessage, request *BaseRequest) (*http.R
"ToUserName": msg.ToUserName, "ToUserName": msg.ToUserName,
} }
buffer, _ := ToBuffer(content) buffer, _ := ToBuffer(content)
req, _ := http.NewRequest(http.MethodPost, c.webWxRevokeMsg, buffer) req, _ := http.NewRequest(http.MethodPost, c.domain.BaseHost+webwxrevokemsg, buffer)
req.Header.Set("Content-Type", jsonContentType) req.Header.Set("Content-Type", jsonContentType)
return c.Do(req) return c.Do(req)
} }
// 校验上传文件 // 校验上传文件
func (c *Client) webWxCheckUpload(stat os.FileInfo, request *BaseRequest, fileMd5, fromUserName, toUserName string) (*http.Response, error) { func (c *Client) webWxCheckUpload(stat os.FileInfo, request *BaseRequest, fileMd5, fromUserName, toUserName string) (*http.Response, error) {
path, _ := url.Parse(c.webWxCheckUploadUrl) path, _ := url.Parse(c.domain.BaseHost + webwxcheckupload)
content := map[string]interface{}{ content := map[string]interface{}{
"BaseRequest": request, "BaseRequest": request,
"FileMd5": fileMd5, "FileMd5": fileMd5,

View File

@ -14,63 +14,23 @@ var (
const ( const (
appId = "wx782c26e4c19acffb" appId = "wx782c26e4c19acffb"
jsLoginUrl = "https://login.wx.qq.com/jslogin" appMessageAppId = "wxeb7ec651dd0aefa9"
qrcodeUrl = "https://login.weixin.qq.com/qrcode/"
loginUrl = "https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login"
// 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"
webWxCheckUploadNormalUrl = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxcheckupload"
// 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"
webWxCheckUploadDesktopUrl = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxcheckupload"
jsonContentType = "application/json; charset=utf-8" jsonContentType = "application/json; charset=utf-8"
uosPatchClientVersion = "2.0.0" 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=" uosPatchExtspam = "Gp8ICJkIEpkICggwMDAwMDAwMRAGGoAI1GiJSIpeO1RZTq9QBKsRbPJdi84ropi16EYI10WB6g74sGmRwSNXjPQnYU" +
"KYotKkvLGpshucCaeWZMOylnc6o2AgDX9grhQQx7fm2DJRTyuNhUlwmEoWhjoG3F0ySAWUsEbH3bJMsEBwoB//0qmFJob74ffdaslqL+IrSy7L" +
"J76/G5TkvNC+J0VQkpH1u3iJJs0uUYyLDzdBIQ6Ogd8LDQ3VKnJLm4g/uDLe+G7zzzkOPzCjXL+70naaQ9medzqmh+/SmaQ6uFWLDQLcRln++w" +
"BwoEibNpG4uOJvqXy+ql50DjlNchSuqLmeadFoo9/mDT0q3G7o/80P15ostktjb7h9bfNc+nZVSnUEJXbCjTeqS5UYuxn+HTS5nZsPVxJA2O5G" +
"dKCYK4x8lTTKShRstqPfbQpplfllx2fwXcSljuYi3YipPyS3GCAqf5A7aYYwJ7AvGqUiR2SsVQ9Nbp8MGHET1GxhifC692APj6SJxZD3i1drSY" +
"ZPMMsS9rKAJTGz2FEupohtpf2tgXm6c16nDk/cw+C7K7me5j5PLHv55DFCS84b06AytZPdkFZLj7FHOkcFGJXitHkX5cgww7vuf6F3p0yM/W73" +
"SoXTx6GX4G6Hg2rYx3O/9VU2Uq8lvURB4qIbD9XQpzmyiFMaytMnqxcZJcoXCtfkTJ6pI7a92JpRUvdSitg967VUDUAQnCXCM/m0snRkR9LtoX" +
"AO1FUGpwlp1EfIdCZFPKNnXMeqev0j9W9ZrkEs9ZWcUEexSj5z+dKYQBhIICviYUQHVqBTZSNy22PlUIeDeIs11j7q4t8rD8LPvzAKWVqXE+5l" +
"S1JPZkjg4y5hfX1Dod3t96clFfwsvDP6xBSe1NBcoKbkyGxYK0UvPGtKQEE0Se2zAymYDv41klYE9s+rxp8e94/H8XhrL9oGm8KWb2RmYnAE7r" +
"y9gd6e8ZuBRIsISlJAE/e8y8xFmP031S6Lnaet6YXPsFpuFsdQs535IjcFd75hh6DNMBYhSfjv456cvhsb99+fRw/KVZLC3yzNSCbLSyo9d9BI" +
"45Plma6V8akURQA/qsaAzU0VyTIqZJkPDTzhuCl92vD2AD/QOhx6iwRSVPAxcRFZcWjgc2wCKh+uCYkTVbNQpB9B90YlNmI3fWTuUOUjwOzQRx" +
"JZj11NsimjOJ50qQwTTFj6qQvQ1a/I+MkTx5UO+yNHl718JWcR3AXGmv/aa9rD1eNP8ioTGlOZwPgmr2sor2iBpKTOrB83QgZXP+xRYkb4zVC+" +
"LoAXEoIa1+zArywlgREer7DLePukkU6wHTkuSaF+ge5Of1bXuU4i938WJHj0t3D8uQxkJvoFi/EYN/7u2P1zGRLV4dHVUsZMGCCtnO6BBigFMAA="
) )
// 消息类型 // 消息类型
@ -124,5 +84,3 @@ var imageType = map[string]bool{
} }
var videoType = "mp4" var videoType = "mp4"
const appMessageAppId = "wxeb7ec651dd0aefa9"

139
url.go
View File

@ -1,84 +1,6 @@
package openwechat package openwechat
// url信息存储 import "errors"
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
webWxCheckUploadUrl 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,
webWxCheckUploadUrl: webWxCheckUploadDesktopUrl,
}
// 网页版
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,
webWxCheckUploadUrl: webWxCheckUploadNormalUrl,
}
)
// mode 类型限制 // mode 类型限制
type mode string type mode string
@ -89,15 +11,54 @@ const (
Desktop mode = "desktop" // 突破网页版登录限制 Desktop mode = "desktop" // 突破网页版登录限制
) )
// 通过mode获取完善的UrlManager, const (
// mode有且仅有两种模式: Normal && Desktop webwxinit = "/cgi-bin/mmwebwx-bin/webwxinit"
func GetUrlManagerByMode(m mode) UrlManager { webwxstatusnotify = "/cgi-bin/mmwebwx-bin/webwxstatusnotify"
switch m { webwxsync = "/cgi-bin/mmwebwx-bin/webwxsync"
case Desktop: webwxsendmsg = "/cgi-bin/mmwebwx-bin/webwxsendmsg"
return desktop webwxgetcontact = "/cgi-bin/mmwebwx-bin/webwxgetcontact"
case Normal: webwxsendmsgimg = "/cgi-bin/mmwebwx-bin/webwxsendmsgimg"
return normal webwxsendappmsg = "/cgi-bin/mmwebwx-bin/webwxsendappmsg"
default: webwxbatchgetcontact = "/cgi-bin/mmwebwx-bin/webwxbatchgetcontact"
panic("unsupport mode got") webwxoplog = "/cgi-bin/mmwebwx-bin/webwxoplog"
webwxverifyuser = "/cgi-bin/mmwebwx-bin/webwxverifyuser"
synccheck = "/cgi-bin/mmwebwx-bin/synccheck"
webwxuploadmedia = "/cgi-bin/mmwebwx-bin/webwxuploadmedia"
webwxgetmsgimg = "/cgi-bin/mmwebwx-bin/webwxgetmsgimg"
webwxgetvoice = "/cgi-bin/mmwebwx-bin/webwxgetvoice"
webwxgetvideo = "/cgi-bin/mmwebwx-bin/webwxgetvideo"
webwxlogout = "/cgi-bin/mmwebwx-bin/webwxlogout"
webwxgetmedia = "/cgi-bin/mmwebwx-bin/webwxgetmedia"
webwxupdatechatroom = "/cgi-bin/mmwebwx-bin/webwxupdatechatroom"
webwxrevokemsg = "/cgi-bin/mmwebwx-bin/webwxrevokemsg"
webwxcheckupload = "/cgi-bin/mmwebwx-bin/webwxcheckupload"
webwxnewloginpage = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage"
jslogin = "https://login.wx.qq.com/jslogin"
login = "https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login"
qrcode = "https://login.weixin.qq.com/qrcode/"
)
var domainMap = map[string][]string{
"wx.qq.com": {"https://wx.qq.com", "https://file.wx.qq.com", "https://webpush.wx.qq.com"},
"wx2.qq.com": {"https://wx2.qq.com", "https://file.wx2.qq.com", "https://webpush.wx2.qq.com"},
"wx8.qq.com": {"https://wx8.qq.com", "https://file.wx8.qq.com", "https://webpush.wx8.qq.com"},
"web2.wechat.com": {"https://web2.wechat.com", "https://file.web2.wechat.com", "https://webpush.web2.wechat.com"},
"wechat.com": {"https://wechat.com", "https://file.web.wechat.com", "https://webpush.web.wechat.com"},
} }
func getDomainByHost(host string) (*domain, error) {
value, exist := domainMap[host]
if !exist {
return nil, errors.New("invalid host")
}
return &domain{
BaseHost: value[0],
FileHost: value[1],
SyncHost: value[2],
}, nil
}
type domain struct {
BaseHost, FileHost, SyncHost string
} }