支持网页版和uos版切换

This commit is contained in:
eatMoreApple 2021-04-24 17:13:37 +08:00
parent 793bb95095
commit 9cfa517518
6 changed files with 355 additions and 214 deletions

319
bot.go
View File

@ -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))
}

View File

@ -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)
}

View File

@ -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

View File

@ -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")

View File

@ -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"
)

92
url.go Normal file
View File

@ -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")
}
}