2026-02-17 13:06:23 +08:00
|
|
|
|
package clientsdk
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"bytes"
|
|
|
|
|
|
"compress/zlib"
|
|
|
|
|
|
"crypto/md5"
|
|
|
|
|
|
"crypto/rand"
|
|
|
|
|
|
"encoding/base64"
|
|
|
|
|
|
"encoding/hex"
|
|
|
|
|
|
"encoding/xml"
|
|
|
|
|
|
"errors"
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"html/template"
|
|
|
|
|
|
"io"
|
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
|
"net/http"
|
|
|
|
|
|
"net/url"
|
|
|
|
|
|
"regexp"
|
|
|
|
|
|
"strconv"
|
|
|
|
|
|
"strings"
|
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
"xiawan/wx/api/req"
|
|
|
|
|
|
"xiawan/wx/api/utils"
|
|
|
|
|
|
"xiawan/wx/api/vo"
|
|
|
|
|
|
"xiawan/wx/lib"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/gogo/protobuf/proto"
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
|
|
"github.com/lunny/log"
|
|
|
|
|
|
|
|
|
|
|
|
"xiawan/wx/clientsdk/android"
|
|
|
|
|
|
"xiawan/wx/clientsdk/baseinfo"
|
|
|
|
|
|
"xiawan/wx/clientsdk/baseutils"
|
|
|
|
|
|
"xiawan/wx/clientsdk/cecdh"
|
|
|
|
|
|
"xiawan/wx/clientsdk/extinfo"
|
|
|
|
|
|
clientsdk "xiawan/wx/clientsdk/hybrid"
|
|
|
|
|
|
"xiawan/wx/clientsdk/mmtls"
|
|
|
|
|
|
"xiawan/wx/protobuf/wechat"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 获取登录二维码 直登
|
|
|
|
|
|
func SendLoginQRCodeRequestDirect(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
// 重新生成AesKey
|
|
|
|
|
|
userInfo.SessionKey = baseutils.RandomBytes(16)
|
|
|
|
|
|
|
|
|
|
|
|
var request wechat.LoginQRCodeRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// AESKey
|
|
|
|
|
|
var aesKey wechat.AESKey
|
|
|
|
|
|
var tmpAesKeyLen = uint32(16)
|
|
|
|
|
|
aesKey.Len = &tmpAesKeyLen
|
|
|
|
|
|
aesKey.Key = []byte(userInfo.SessionKey)
|
|
|
|
|
|
request.Aes = &aesKey
|
|
|
|
|
|
|
|
|
|
|
|
// OpCode
|
|
|
|
|
|
var tmpOpcode = uint32(0)
|
|
|
|
|
|
request.Opcode = &tmpOpcode
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
src, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, src, baseinfo.MMRequestTypeGetLoginQRCode, 7)
|
|
|
|
|
|
// 初始化代理信息
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getloginqrcode", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
userInfo.ClientVersion = baseinfo.ClientVersion
|
|
|
|
|
|
userInfo.DeviceInfo.DeviceName = baseinfo.IPadDeviceName
|
|
|
|
|
|
userInfo.DeviceInfo.OsType = baseinfo.DeviceTypeIos
|
|
|
|
|
|
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendLoginQRCodeRequest 获取登陆二维码 正常
|
|
|
|
|
|
func SendLoginQRCodeRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
// 重新生成AesKey
|
|
|
|
|
|
userInfo.SessionKey = baseutils.RandomBytes(16)
|
|
|
|
|
|
|
|
|
|
|
|
var request wechat.LoginQRCodeRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// AESKey
|
|
|
|
|
|
var aesKey wechat.AESKey
|
|
|
|
|
|
var tmpAesKeyLen = uint32(16)
|
|
|
|
|
|
aesKey.Len = &tmpAesKeyLen
|
|
|
|
|
|
aesKey.Key = []byte(userInfo.SessionKey)
|
|
|
|
|
|
request.Aes = &aesKey
|
|
|
|
|
|
|
|
|
|
|
|
// OpCode
|
|
|
|
|
|
var tmpOpcode = uint32(0)
|
|
|
|
|
|
request.Opcode = &tmpOpcode
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
src, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, src, baseinfo.MMRequestTypeGetLoginQRCode, 7)
|
|
|
|
|
|
// 初始化代理信息
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getloginqrcode", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendLoginQRCodeRequest 获取登陆二维码(绕过验证码)
|
|
|
|
|
|
func SendLoginQRCodeRequestX(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
// 重新生成AesKey
|
|
|
|
|
|
userInfo.SessionKey = baseutils.RandomBytes(16)
|
|
|
|
|
|
|
|
|
|
|
|
// 构造请求
|
|
|
|
|
|
var request wechat.LoginQRCodeRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// AESKey
|
|
|
|
|
|
var aesKey wechat.AESKey
|
|
|
|
|
|
var tmpAesKeyLen = uint32(16)
|
|
|
|
|
|
aesKey.Len = &tmpAesKeyLen
|
|
|
|
|
|
aesKey.Key = []byte(userInfo.SessionKey)
|
|
|
|
|
|
request.Aes = &aesKey
|
|
|
|
|
|
|
|
|
|
|
|
// OpCode
|
|
|
|
|
|
var tmpOpcode = uint32(0)
|
|
|
|
|
|
request.Opcode = &tmpOpcode
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
src, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, src, baseinfo.MMRequestTypeGetLoginQRCode, 7)
|
|
|
|
|
|
// 初始化代理信息
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getloginqrcode", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendManualAuth 发送ManualAuth请求
|
|
|
|
|
|
func sendManualAuthByAccountData(userInfo *baseinfo.UserInfo, accountData []byte) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
// 打包加密数据
|
|
|
|
|
|
subHeader := make([]byte, 0)
|
|
|
|
|
|
tmpBytes := baseutils.Int32ToBytes(uint32(len(accountData)))
|
|
|
|
|
|
subHeader = append(subHeader, tmpBytes[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// 获取 deviceDataRequest
|
|
|
|
|
|
deviceData := GetManualAuthAesReqDataMarshal(userInfo)
|
|
|
|
|
|
tmpBytes = baseutils.Int32ToBytes(uint32(len(deviceData)))
|
|
|
|
|
|
subHeader = append(subHeader, tmpBytes[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// 加密压缩 accountData
|
|
|
|
|
|
newAccountData := baseutils.CompressAndRsaByVer(accountData, userInfo.GetLoginRsaVer())
|
|
|
|
|
|
tmpBytes = baseutils.Int32ToBytes(uint32(len(newAccountData)))
|
|
|
|
|
|
subHeader = append(subHeader, tmpBytes[0:]...)
|
|
|
|
|
|
subHeader = append(subHeader, newAccountData[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// 压缩加密 deviceData
|
|
|
|
|
|
newDeviceData := baseutils.CompressAes(userInfo.SessionKey, deviceData)
|
|
|
|
|
|
subHeader = append(subHeader, newDeviceData[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// 发送登陆请求
|
|
|
|
|
|
sendData := Pack(userInfo, subHeader, baseinfo.MMRequestTypeManualAuth, 17)
|
|
|
|
|
|
// 初始化代理信息
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/manualauth", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendManualAuthA16发送A16登录请求
|
|
|
|
|
|
func SendManualAuthA16(userInfo *baseinfo.UserInfo, accountData []byte) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
/*req := &wechat.ManualAuthRequest{
|
|
|
|
|
|
RsaReqData: GetManualAuthRsaReqDataProtobuf(userInfo,userInfo.LoginDataInfo.UserName,userInfo.LoginDataInfo.PassWord),
|
|
|
|
|
|
AesReqData: GetManualAuthAesReqDataA16Protobuf(userInfo),
|
|
|
|
|
|
}*/
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
// 打包加密数据
|
|
|
|
|
|
subHeader := make([]byte, 0)
|
|
|
|
|
|
tmpBytes := baseutils.Int32ToBytes(uint32(len(accountData)))
|
|
|
|
|
|
subHeader = append(subHeader, tmpBytes[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// 获取 deviceDataRequest
|
|
|
|
|
|
deviceData := GetManualAuthAesReqDataA16Protobuf(userInfo)
|
|
|
|
|
|
tmpBytes = baseutils.Int32ToBytes(uint32(len(deviceData)))
|
|
|
|
|
|
subHeader = append(subHeader, tmpBytes[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// 加密压缩 accountData
|
|
|
|
|
|
newAccountData := baseutils.CompressAndRsaByVer(accountData, userInfo.GetLoginRsaVer())
|
|
|
|
|
|
tmpBytes = baseutils.Int32ToBytes(uint32(len(newAccountData)))
|
|
|
|
|
|
subHeader = append(subHeader, tmpBytes[0:]...)
|
|
|
|
|
|
subHeader = append(subHeader, newAccountData[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// 压缩加密 deviceData
|
|
|
|
|
|
newDeviceData := baseutils.CompressAes(userInfo.SessionKey, deviceData)
|
|
|
|
|
|
subHeader = append(subHeader, newDeviceData[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// 发送登陆请求
|
|
|
|
|
|
sendData := Pack(userInfo, subHeader, baseinfo.MMRequestTypeManualAuth, 17)
|
|
|
|
|
|
// 初始化代理信息
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/manualauth", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendManualAuth 发送登陆请求
|
|
|
|
|
|
func SendManualAuth(userInfo *baseinfo.UserInfo, newpass string, wxid string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var tmpNid uint32 = 713
|
|
|
|
|
|
userInfo.EcPublicKey, userInfo.EcPrivateKey = cecdh.GenerateEccKey()
|
|
|
|
|
|
authRequest := &wechat.ManualAuthAccountRequest{}
|
|
|
|
|
|
// aes_key
|
|
|
|
|
|
var aesKey wechat.AESKey
|
|
|
|
|
|
var tmpAesKeyLen uint32 = 16
|
|
|
|
|
|
aesKey.Len = &tmpAesKeyLen
|
|
|
|
|
|
aesKey.Key = []byte(userInfo.SessionKey)
|
|
|
|
|
|
authRequest.Aes = &aesKey
|
|
|
|
|
|
|
|
|
|
|
|
// 其它参数
|
|
|
|
|
|
var ecdhKey wechat.ECDHKey
|
|
|
|
|
|
var key wechat.SKBuiltinString_
|
|
|
|
|
|
key.Buffer = userInfo.EcPublicKey
|
|
|
|
|
|
var tmpLen = (uint32)(len(userInfo.EcPublicKey))
|
|
|
|
|
|
key.Len = &tmpLen
|
|
|
|
|
|
ecdhKey.Nid = &tmpNid
|
|
|
|
|
|
ecdhKey.Key = &key
|
|
|
|
|
|
authRequest.EcdhKey = &ecdhKey
|
|
|
|
|
|
authRequest.UserName = &wxid
|
|
|
|
|
|
userInfo.WxId = wxid
|
|
|
|
|
|
//判断是否为iPad登录的伪密码
|
|
|
|
|
|
if !strings.HasPrefix(newpass, "extdevnewpwd_") {
|
|
|
|
|
|
newpass = baseutils.Md5Value(newpass)
|
|
|
|
|
|
}
|
|
|
|
|
|
authRequest.Password_1 = &newpass
|
|
|
|
|
|
|
|
|
|
|
|
// 序列化
|
|
|
|
|
|
accountData, err := proto.Marshal(authRequest)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if !strings.HasPrefix(userInfo.LoginDataInfo.LoginData, "A") && userInfo.DeviceInfo != nil {
|
|
|
|
|
|
return sendManualAuthByAccountData(userInfo, accountData)
|
|
|
|
|
|
}
|
|
|
|
|
|
return SendManualAuthA16(userInfo, accountData)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取DeviceToken IOS
|
|
|
|
|
|
func SendIosDeviceTokenRequest(userInfo *baseinfo.UserInfo) (*wechat.TrustResp, error) {
|
|
|
|
|
|
deviceIos := userInfo.DeviceInfo
|
|
|
|
|
|
fmt.Println("iphonever", deviceIos.IphoneVer, "osType", deviceIos.OsType, "deviceName", deviceIos.DeviceName, userInfo.ClientVersion, baseinfo.ClientVersion, 11111)
|
|
|
|
|
|
deviceId := Get62Key(userInfo.LoginDataInfo.LoginData)
|
|
|
|
|
|
if deviceId[:2] != "49" {
|
|
|
|
|
|
deviceId = "49" + deviceId[2:]
|
|
|
|
|
|
}
|
|
|
|
|
|
clientVersion := userInfo.ClientVersion
|
|
|
|
|
|
if !(int(clientVersion) > 0) {
|
|
|
|
|
|
clientVersion = baseinfo.ClientVersion
|
|
|
|
|
|
}
|
|
|
|
|
|
installTime := strconv.FormatInt(time.Now().Add(-2592234*time.Second).Unix(), 10) // 一个月前(偏移234秒)秒级时间戳
|
|
|
|
|
|
kernBootTime := strconv.FormatInt(time.Now().Add(-2592230*time.Second).Unix()*1000, 10) // 一个月前(偏移230秒)毫秒秒级时间戳
|
|
|
|
|
|
uuid1, uuid2 := baseinfo.IOSUuid(deviceId)
|
|
|
|
|
|
td := &wechat.TrustReq{
|
|
|
|
|
|
Td: &wechat.TrustData{
|
|
|
|
|
|
Tdi: []*wechat.TrustDeviceInfo{
|
|
|
|
|
|
{Key: proto.String("deviceid"), Val: proto.String(deviceId)},
|
|
|
|
|
|
{Key: proto.String("sdi"), Val: proto.String(extinfo.GetCidMd5(deviceId, extinfo.GetCid(0x0262626262626)))},
|
|
|
|
|
|
{Key: proto.String("idfv"), Val: proto.String(uuid1)},
|
|
|
|
|
|
{Key: proto.String("idfa"), Val: proto.String(uuid2)},
|
|
|
|
|
|
{Key: proto.String("device_model"), Val: proto.String(deviceIos.IphoneVer)},
|
|
|
|
|
|
{Key: proto.String("os_version"), Val: proto.String(deviceIos.OsType)},
|
|
|
|
|
|
{Key: proto.String("core_count"), Val: proto.String("6")},
|
|
|
|
|
|
{Key: proto.String("carrier_name"), Val: proto.String("")},
|
|
|
|
|
|
{Key: proto.String("is_jailbreak"), Val: proto.String("0")},
|
|
|
|
|
|
{Key: proto.String("device_name"), Val: proto.String(deviceIos.DeviceName)},
|
|
|
|
|
|
{Key: proto.String("client_version"), Val: proto.String(fmt.Sprintf("%v", clientVersion))},
|
|
|
|
|
|
{Key: proto.String("plist_version"), Val: proto.String(fmt.Sprintf("%v", clientVersion))},
|
|
|
|
|
|
{Key: proto.String("language"), Val: proto.String("zh")},
|
|
|
|
|
|
{Key: proto.String("locale_country"), Val: proto.String("CN")},
|
|
|
|
|
|
{Key: proto.String("screen_width"), Val: proto.String("834")},
|
|
|
|
|
|
{Key: proto.String("screen_height"), Val: proto.String("1112")},
|
|
|
|
|
|
{Key: proto.String("install_time"), Val: proto.String(installTime)},
|
|
|
|
|
|
{Key: proto.String("kern_boottime"), Val: proto.String(kernBootTime)},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
pb, _ := proto.Marshal(td)
|
|
|
|
|
|
var b bytes.Buffer
|
|
|
|
|
|
w := zlib.NewWriter(&b)
|
|
|
|
|
|
w.Write(pb)
|
|
|
|
|
|
w.Close()
|
|
|
|
|
|
|
|
|
|
|
|
zt := new(ZT)
|
|
|
|
|
|
zt.Init()
|
|
|
|
|
|
// encData := zt.Encrypt(b.Bytes())
|
|
|
|
|
|
encData := android.SaeEncrypt07(b.Bytes())
|
|
|
|
|
|
randKey := make([]byte, 16)
|
|
|
|
|
|
_, _ = io.ReadFull(rand.Reader, randKey)
|
|
|
|
|
|
fp := &wechat.FPFresh{
|
|
|
|
|
|
BaseRequest: &wechat.BaseRequest{
|
|
|
|
|
|
SessionKey: []byte{},
|
|
|
|
|
|
Uin: proto.Uint32(0),
|
|
|
|
|
|
DeviceId: append([]byte(deviceId), 0),
|
|
|
|
|
|
ClientVersion: proto.Uint32(clientVersion),
|
|
|
|
|
|
OsType: &userInfo.DeviceInfo.OsType,
|
|
|
|
|
|
Scene: proto.Uint32(0),
|
|
|
|
|
|
},
|
|
|
|
|
|
SessKey: randKey,
|
|
|
|
|
|
Ztdata: &wechat.ZTData{
|
|
|
|
|
|
Version: []byte("00000007"),
|
|
|
|
|
|
Encrypted: proto.Uint64(1),
|
|
|
|
|
|
Data: encData,
|
|
|
|
|
|
TimeStamp: proto.Int64(int64(time.Now().Unix())),
|
|
|
|
|
|
OpType: proto.Uint64(5),
|
|
|
|
|
|
Uin: proto.Uint64(0),
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
reqData, _ := proto.Marshal(fp)
|
|
|
|
|
|
|
|
|
|
|
|
hec := &android.Client{}
|
|
|
|
|
|
|
|
|
|
|
|
DeviceTypeIos := deviceIos.OsType
|
|
|
|
|
|
if DeviceTypeIos == "" {
|
|
|
|
|
|
DeviceTypeIos = baseinfo.DeviceTypeIos
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
hec.Init("IOS", int(clientVersion), DeviceTypeIos)
|
|
|
|
|
|
hecData := hec.HybridEcdhPackIosEn(3789, 0, nil, reqData)
|
|
|
|
|
|
// 初始化代理信息
|
|
|
|
|
|
MMInfo := userInfo.GetMMInfo()
|
|
|
|
|
|
MMInfo.Dialer = userInfo.GetDialer()
|
|
|
|
|
|
recvData, err := mmtls.MMHTTPPostData(MMInfo, "/cgi-bin/micromsg-bin/fpinitnl", hecData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return &wechat.TrustResp{}, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(recvData) <= 31 {
|
|
|
|
|
|
return &wechat.TrustResp{}, errors.New(hex.EncodeToString(recvData))
|
|
|
|
|
|
}
|
|
|
|
|
|
ph := hec.HybridEcdhPackIosUn(recvData)
|
|
|
|
|
|
DTResp := &wechat.TrustResp{}
|
|
|
|
|
|
_ = proto.Unmarshal(ph.Data, DTResp)
|
|
|
|
|
|
return DTResp, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取DeviceToken
|
|
|
|
|
|
func SendAndroIdDeviceTokenRequest(userInfo *baseinfo.UserInfo) (*wechat.TrustResp, error) {
|
|
|
|
|
|
Android16 := userInfo.DeviceInfoA16
|
|
|
|
|
|
td := &wechat.TrustReq{
|
|
|
|
|
|
Td: &wechat.TrustData{
|
|
|
|
|
|
Tdi: []*wechat.TrustDeviceInfo{
|
|
|
|
|
|
{Key: proto.String("IMEI"), Val: proto.String(Android16.AndriodImei(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("AndroidID"), Val: proto.String(Android16.AndriodID(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("PhoneSerial"), Val: proto.String(Android16.AndriodPhoneSerial(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("cid"), Val: proto.String("")},
|
|
|
|
|
|
{Key: proto.String("WidevineDeviceID"), Val: proto.String(Android16.AndriodWidevineDeviceID(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("WidevineProvisionID"), Val: proto.String(Android16.AndriodWidevineProvisionID(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("GSFID"), Val: proto.String("")},
|
|
|
|
|
|
{Key: proto.String("SoterID"), Val: proto.String("")},
|
|
|
|
|
|
{Key: proto.String("SoterUid"), Val: proto.String("")},
|
|
|
|
|
|
{Key: proto.String("FSID"), Val: proto.String(Android16.AndriodFSID(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("BootID"), Val: proto.String("")},
|
|
|
|
|
|
{Key: proto.String("IMSI"), Val: proto.String("")},
|
|
|
|
|
|
{Key: proto.String("PhoneNum"), Val: proto.String("")},
|
|
|
|
|
|
{Key: proto.String("WeChatInstallTime"), Val: proto.String("1556077144")},
|
|
|
|
|
|
{Key: proto.String("PhoneModel"), Val: proto.String(Android16.AndroidPhoneModel(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("BuildBoard"), Val: proto.String("bullhead")},
|
|
|
|
|
|
{Key: proto.String("BuildBootloader"), Val: proto.String(Android16.AndroidBuildBoard(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("SystemBuildDate"), Val: proto.String("Fri Sep 28 23:37:27 UTC 2019")},
|
|
|
|
|
|
{Key: proto.String("SystemBuildDateUTC"), Val: proto.String("1538177847")},
|
|
|
|
|
|
{Key: proto.String("BuildFP"), Val: proto.String(Android16.AndroidBuildFP(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("BuildID"), Val: proto.String(Android16.AndroidBuildID(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("BuildBrand"), Val: proto.String("google")},
|
|
|
|
|
|
{Key: proto.String("BuildDevice"), Val: proto.String("bullhead")},
|
|
|
|
|
|
{Key: proto.String("BuildProduct"), Val: proto.String("bullhead")},
|
|
|
|
|
|
{Key: proto.String("Manufacturer"), Val: proto.String(Android16.AndroidManufacturer(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("RadioVersion"), Val: proto.String(Android16.AndroidRadioVersion(Android16.DeviceIdStr[:15]))},
|
|
|
|
|
|
{Key: proto.String("AndroidVersion"), Val: proto.String(Android16.AndroidVersion())},
|
|
|
|
|
|
{Key: proto.String("SdkIntVersion"), Val: proto.String("27")},
|
|
|
|
|
|
{Key: proto.String("ScreenWidth"), Val: proto.String("1080")},
|
|
|
|
|
|
{Key: proto.String("ScreenHeight"), Val: proto.String("1794")},
|
|
|
|
|
|
{Key: proto.String("SensorList"), Val: proto.String("BMI160 accelerometer#Bosch#0.004788#1,BMI160 gyroscope#Bosch#0.000533#1,BMM150 magnetometer#Bosch#0.000000#1,BMP280 pressure#Bosch#0.005000#1,BMP280 temperature#Bosch#0.010000#1,RPR0521 Proximity Sensor#Rohm#1.000000#1,RPR0521 Light Sensor#Rohm#10.000000#1,Orientation#Google#1.000000#1,BMI160 Step detector#Bosch#1.000000#1,Significant motion#Google#1.000000#1,Gravity#Google#1.000000#1,Linear Acceleration#Google#1.000000#1,Rotation Vector#Google#1.000000#1,Geomagnetic Rotation Vector#Google#1.000000#1,Game Rotation Vector#Google#1.000000#1,Pickup Gesture#Google#1.000000#1,Tilt Detector#Google#1.000000#1,BMI160 Step counter#Bosch#1.000000#1,BMM150 magnetometer (uncalibrated)#Bosch#0.000000#1,BMI160 gyroscope (uncalibrated)#Bosch#0.000533#1,Sensors Sync#Google#1.000000#1,Double Twist#Google#1.000000#1,Double Tap#Google#1.000000#1,Device Orientation#Google#1.000000#1,BMI160 accelerometer (uncalibrated)#Bosch#0.004788#1")},
|
|
|
|
|
|
{Key: proto.String("DefaultInputMethod"), Val: proto.String("com.google.android.inputmethod.latin")},
|
|
|
|
|
|
{Key: proto.String("InputMethodList"), Val: proto.String("Google \345\215\260\345\272\246\350\257\255\351\224\256\347\233\230#com.google.android.apps.inputmethod.hindi,Google \350\257\255\351\237\263\350\276\223\345\205\245#com.google.android.googlequicksearchbox,Google \346\227\245\350\257\255\350\276\223\345\205\245\346\263\225#com.google.android.inputmethod.japanese,Google \351\237\251\350\257\255\350\276\223\345\205\245\346\263\225#com.google.android.inputmethod.korean,Gboard#com.google.android.inputmethod.latin,\350\260\267\346\255\214\346\213\274\351\237\263\350\276\223\345\205\245\346\263\225#com.google.android.inputmethod.pinyin")},
|
|
|
|
|
|
{Key: proto.String("DeviceID"), Val: proto.String(Android16.DeviceIdStr[:15])},
|
|
|
|
|
|
{Key: proto.String("OAID"), Val: proto.String("")},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
pb, _ := proto.Marshal(td)
|
|
|
|
|
|
var b bytes.Buffer
|
|
|
|
|
|
w := zlib.NewWriter(&b)
|
|
|
|
|
|
w.Write(pb)
|
|
|
|
|
|
w.Close()
|
|
|
|
|
|
zt := new(android.ZT)
|
|
|
|
|
|
zt.Init()
|
|
|
|
|
|
encData := zt.Encrypt(b.Bytes())
|
|
|
|
|
|
randKey := make([]byte, 16)
|
|
|
|
|
|
io.ReadFull(rand.Reader, randKey)
|
|
|
|
|
|
fp := &wechat.FPFresh{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
SessKey: randKey,
|
|
|
|
|
|
Ztdata: &wechat.ZTData{
|
|
|
|
|
|
Version: []byte("00000003"), // apad 此处为 "00000003\x00"
|
|
|
|
|
|
Encrypted: proto.Uint64(1),
|
|
|
|
|
|
Data: encData,
|
|
|
|
|
|
TimeStamp: proto.Int64(int64(time.Now().Unix())),
|
|
|
|
|
|
OpType: proto.Uint64(5),
|
|
|
|
|
|
Uin: proto.Uint64(0),
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
reqData, _ := proto.Marshal(fp)
|
|
|
|
|
|
hec := &android.Client{}
|
|
|
|
|
|
hec.Init("Android", int(baseinfo.AndroidClientVersion), baseinfo.AndroidDeviceType)
|
|
|
|
|
|
sendData := hec.HybridEcdhPackAndroidEn(3789, 10002, 0, nil, reqData)
|
|
|
|
|
|
MMInfo := userInfo.GetMMInfo()
|
|
|
|
|
|
MMInfo.Dialer = userInfo.GetDialer()
|
|
|
|
|
|
recvData, err := mmtls.MMHTTPPostData(MMInfo, "/cgi-bin/micromsg-bin/fpinitnl", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return &wechat.TrustResp{}, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(recvData) <= 31 {
|
|
|
|
|
|
return &wechat.TrustResp{}, errors.New(hex.EncodeToString(recvData))
|
|
|
|
|
|
}
|
|
|
|
|
|
ph := hec.HybridEcdhPackAndroidUn(recvData)
|
|
|
|
|
|
DTResp := &wechat.TrustResp{}
|
|
|
|
|
|
_ = proto.Unmarshal(ph.Data, DTResp)
|
|
|
|
|
|
return DTResp, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取DeviceToken
|
|
|
|
|
|
func SendDeviceTokenRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
deviceInfo := userInfo.DeviceInfo
|
|
|
|
|
|
deviceId := hex.EncodeToString(deviceInfo.DeviceID)
|
|
|
|
|
|
ServerVersion := userInfo.ClientVersion
|
|
|
|
|
|
if !(int(ServerVersion) > 0) {
|
|
|
|
|
|
ServerVersion = baseinfo.ServerVersion
|
|
|
|
|
|
}
|
|
|
|
|
|
data, err := extinfo.GetZTData(deviceId, deviceInfo.OsType, deviceInfo.OsTypeNumber, deviceInfo.DeviceName, uint64(ServerVersion))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
request := wechat.TrustRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
RandomKey: userInfo.SessionKey,
|
|
|
|
|
|
SpamBuff: data,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
src, _ := proto.Marshal(&request)
|
|
|
|
|
|
//sendData := Pack(userInfo, src, 3789, 12)
|
|
|
|
|
|
|
|
|
|
|
|
secKeyMgr := NewSecLoginKeyMgrByVer(146)
|
|
|
|
|
|
|
|
|
|
|
|
reqData := src
|
|
|
|
|
|
//加密
|
|
|
|
|
|
encrypt, epKey, token, ecdhpairkey, err := clientsdk.HybridEncrypt(reqData, secKeyMgr.WeChatPubKey)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
log.Error("加密 error", err.Error())
|
|
|
|
|
|
}
|
|
|
|
|
|
ecdhPacket := &wechat.EcdhPacket{
|
|
|
|
|
|
Type: proto.Uint32(1),
|
|
|
|
|
|
Key: &wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(415),
|
|
|
|
|
|
Buffer: ecdhpairkey.PubKey,
|
|
|
|
|
|
},
|
|
|
|
|
|
Token: token,
|
|
|
|
|
|
Url: proto.String(""),
|
|
|
|
|
|
ProtobufData: encrypt,
|
|
|
|
|
|
}
|
|
|
|
|
|
secKeyMgr.PubKey = ecdhpairkey.PubKey
|
|
|
|
|
|
secKeyMgr.PriKey = ecdhpairkey.PriKey
|
|
|
|
|
|
secKeyMgr.SourceData = reqData
|
|
|
|
|
|
secKeyMgr.FinalSha256 = append(secKeyMgr.FinalSha256, epKey[24:]...)
|
|
|
|
|
|
secKeyMgr.FinalSha256 = append(secKeyMgr.FinalSha256, reqData...)
|
|
|
|
|
|
ecdhDataPacket, err := proto.Marshal(ecdhPacket)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
log.Error("ecdhDataPacket error", err.Error())
|
|
|
|
|
|
}
|
|
|
|
|
|
packHeader := CreatePackHead(userInfo, baseinfo.MMPackDataTypeUnCompressed, 3789, ecdhDataPacket, ecdhDataPacket, uint32(len(ecdhDataPacket)), 12, uint32(0x4e))
|
|
|
|
|
|
//设置Hybrid 加密密钥版本
|
|
|
|
|
|
packHeader.HybridKeyVer = secKeyMgr.WeChatPubKeyVersion
|
|
|
|
|
|
//开始组头
|
|
|
|
|
|
//packHeader.ReqData= PackHeaderSerialize(packHeader, false)
|
|
|
|
|
|
|
|
|
|
|
|
sendData := PackHeaderSerialize(packHeader, true)
|
|
|
|
|
|
MMInfo := userInfo.GetMMInfo()
|
|
|
|
|
|
MMInfo.Dialer = userInfo.GetDialer()
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(MMInfo, "/cgi-bin/micromsg-bin/fpinitnl", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
packHeader, err = DecodePackHeader(resp, nil)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
packHeader.Data, err = clientsdk.HybridEcdhDecrypt(packHeader.Data, secKeyMgr.PriKey, secKeyMgr.PubKey, secKeyMgr.FinalSha256)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return packHeader, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 二次登录-new
|
|
|
|
|
|
func SendSecautouthRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
userInfo.EcPublicKey, userInfo.EcPrivateKey = cecdh.GenerateEccKey()
|
|
|
|
|
|
autoAuthKey := &wechat.AutoAuthKey{}
|
|
|
|
|
|
err := proto.Unmarshal(userInfo.AutoAuthKey, autoAuthKey)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
userInfo.SessionKey = autoAuthKey.EncryptKey.Buffer
|
|
|
|
|
|
var tmpNid uint32 = 713
|
|
|
|
|
|
var key wechat.SKBuiltinString_
|
|
|
|
|
|
key.Buffer = userInfo.EcPublicKey
|
|
|
|
|
|
var tmpLen = (uint32)(len(userInfo.EcPublicKey))
|
|
|
|
|
|
key.Len = &tmpLen
|
|
|
|
|
|
// ClientSeqId
|
|
|
|
|
|
tmpTime := int(time.Now().UnixNano() / 1000000000)
|
|
|
|
|
|
tmpTimeStr := strconv.Itoa(tmpTime)
|
|
|
|
|
|
var strClientSeqID = string(userInfo.DeviceInfo.Imei + "-" + tmpTimeStr)
|
|
|
|
|
|
// extSpamInfo
|
|
|
|
|
|
var extSpamInfo wechat.SKBuiltinString_
|
|
|
|
|
|
extSpamInfo.Buffer = GetExtPBSpamInfoDataLogin(userInfo)
|
|
|
|
|
|
extSpamInfoLen := uint32(len(extSpamInfo.Buffer))
|
|
|
|
|
|
extSpamInfo.Len = &extSpamInfoLen
|
|
|
|
|
|
req := &wechat.AutoAuthRequest{
|
|
|
|
|
|
RsaReqData: &wechat.AutoAuthRsaReqData{
|
|
|
|
|
|
AesEncryptKey: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(autoAuthKey.EncryptKey.Buffer))),
|
|
|
|
|
|
Buffer: autoAuthKey.EncryptKey.Buffer,
|
|
|
|
|
|
},
|
|
|
|
|
|
PubEcdhKey: &wechat.ECDHKey{
|
|
|
|
|
|
Nid: proto.Uint32(tmpNid),
|
|
|
|
|
|
Key: &key,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
AesReqData: &wechat.AutoAuthAesReqData{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
BaseReqInfo: &wechat.BaseAuthReqInfo{},
|
|
|
|
|
|
AutoAuthKey: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(userInfo.AutoAuthKey))),
|
|
|
|
|
|
Buffer: userInfo.AutoAuthKey,
|
|
|
|
|
|
},
|
|
|
|
|
|
Imei: &userInfo.DeviceInfo.Imei,
|
|
|
|
|
|
SoftType: &userInfo.DeviceInfo.SoftTypeXML,
|
|
|
|
|
|
BuiltinIpSeq: proto.Uint32(0),
|
|
|
|
|
|
ClientSeqId: &strClientSeqID,
|
|
|
|
|
|
DeviceName: proto.String(userInfo.DeviceInfo.DeviceName),
|
|
|
|
|
|
SoftInfoXml: proto.String("iPad Mini 4"),
|
|
|
|
|
|
Language: proto.String("zh_CN"),
|
|
|
|
|
|
TimeZone: proto.String("8.00"),
|
|
|
|
|
|
ExtSpamInfo: &extSpamInfo,
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
reqData, err := proto.Marshal(req)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
secKeyMgr := NewSecLoginKeyMgrByVer(146)
|
|
|
|
|
|
//加密
|
|
|
|
|
|
encrypt, epKey, token, ecdhpairkey, err := clientsdk.HybridEncrypt(reqData, secKeyMgr.WeChatPubKey)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
/*ecdhPacket := &wechat.EcdhPacket{
|
|
|
|
|
|
Type: proto.Uint32(1),
|
|
|
|
|
|
Key: &wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(415),
|
|
|
|
|
|
Buffer: ecdhpairkey.PubKey,
|
|
|
|
|
|
},
|
|
|
|
|
|
Token: token,
|
|
|
|
|
|
Url: proto.String(""),
|
|
|
|
|
|
ProtobufData: encrypt,
|
|
|
|
|
|
}*/
|
|
|
|
|
|
ecdhPacket := &wechat.HybridEcdhRequest{
|
|
|
|
|
|
Type: proto.Int32(1),
|
|
|
|
|
|
SecECDHKey: &wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(415),
|
|
|
|
|
|
Buffer: ecdhpairkey.PubKey,
|
|
|
|
|
|
},
|
|
|
|
|
|
Randomkeydata: token,
|
|
|
|
|
|
Randomkeyextenddata: epKey,
|
|
|
|
|
|
Encyptdata: encrypt,
|
|
|
|
|
|
}
|
|
|
|
|
|
secKeyMgr.PubKey = ecdhpairkey.PubKey
|
|
|
|
|
|
secKeyMgr.PriKey = ecdhpairkey.PriKey
|
|
|
|
|
|
secKeyMgr.SourceData = reqData
|
|
|
|
|
|
secKeyMgr.FinalSha256 = append(secKeyMgr.FinalSha256, epKey[24:]...)
|
|
|
|
|
|
secKeyMgr.FinalSha256 = append(secKeyMgr.FinalSha256, reqData...)
|
|
|
|
|
|
ecdhDataPacket, err := proto.Marshal(ecdhPacket)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
packHeader := CreatePackHead(userInfo, baseinfo.MMPackDataTypeUnCompressed, 763, ecdhDataPacket, ecdhDataPacket, uint32(len(ecdhDataPacket)), 12, uint32(0x4e))
|
|
|
|
|
|
//设置Hybrid 加密密钥版本
|
|
|
|
|
|
packHeader.HybridKeyVer = secKeyMgr.WeChatPubKeyVersion
|
|
|
|
|
|
//开始组头
|
|
|
|
|
|
retData := PackHeaderSerialize(packHeader, false)
|
|
|
|
|
|
//fmt.Println(hex.EncodeToString(retData))
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/secautoauth", retData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
packHeader, err = DecodePackHeader(resp, nil)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
packHeader.Data, err = clientsdk.HybridEcdhDecrypt(packHeader.Data, secKeyMgr.PriKey, secKeyMgr.PubKey, secKeyMgr.FinalSha256)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return packHeader, err
|
|
|
|
|
|
|
|
|
|
|
|
/*hec :=&Client{}
|
|
|
|
|
|
hec.Init("IOS")
|
|
|
|
|
|
hecData := hec.HybridEcdhPackIosEn(763,userInfo.Uin,userInfo.Session,reqData)
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/secautoauth", hecData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
packHeader := hec.HybridEcdhPackIosUn(resp)
|
|
|
|
|
|
packHeader, err = DecodePackHeader(resp, nil)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
packHeader.Data, err = clientsdk.HybridEcdhDecrypt(packHeader.Data, secKeyMgr.PriKey, secKeyMgr.PubKey, secKeyMgr.FinalSha256)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}*/
|
|
|
|
|
|
// return packHeader, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendAutoAuthRequest 发送token登陆请求
|
|
|
|
|
|
func SendAutoAuthRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
userInfo.EcPublicKey, userInfo.EcPrivateKey = cecdh.GenerateEccKey()
|
|
|
|
|
|
autoAuthKey := &wechat.AutoAuthKey{}
|
|
|
|
|
|
err := proto.Unmarshal(userInfo.AutoAuthKey, autoAuthKey)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
userInfo.SessionKey = autoAuthKey.EncryptKey.Buffer
|
|
|
|
|
|
// 获取AutoAuthRsaReqData
|
|
|
|
|
|
rsaReqData := GetAutoAuthRsaReqDataMarshal(userInfo)
|
|
|
|
|
|
aesReqData := GetAutoAuthAesReqDataMarshal(userInfo)
|
|
|
|
|
|
|
|
|
|
|
|
// 开始打包数据
|
|
|
|
|
|
// 加密压缩 rsaReqData
|
|
|
|
|
|
rsaEncodeData := baseutils.CompressAndRsaByVer(rsaReqData, userInfo.GetLoginRsaVer())
|
|
|
|
|
|
rsaAesEncodeData := baseutils.CompressAes(userInfo.SessionKey, rsaReqData)
|
|
|
|
|
|
|
|
|
|
|
|
// 加密压缩 aesReqData
|
|
|
|
|
|
aesEncodeData := baseutils.CompressAes(userInfo.SessionKey, aesReqData)
|
|
|
|
|
|
|
|
|
|
|
|
body := make([]byte, 0)
|
|
|
|
|
|
// rsaReqBuflen
|
|
|
|
|
|
tmpBuf := baseutils.Int32ToBytes(uint32(len(rsaReqData)))
|
|
|
|
|
|
body = append(body, tmpBuf[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// aesReqBuf len
|
|
|
|
|
|
tmpBuf = baseutils.Int32ToBytes(uint32(len(aesReqData)))
|
|
|
|
|
|
body = append(body, tmpBuf[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// rsaEncodeData len
|
|
|
|
|
|
tmpBuf = baseutils.Int32ToBytes(uint32(len(rsaEncodeData)))
|
|
|
|
|
|
body = append(body, tmpBuf[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// rsaAesEncodeData len
|
|
|
|
|
|
tmpBuf = baseutils.Int32ToBytes(uint32(len(rsaAesEncodeData)))
|
|
|
|
|
|
body = append(body, tmpBuf[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// rsaEncodeData
|
|
|
|
|
|
body = append(body, rsaEncodeData[0:]...)
|
|
|
|
|
|
body = append(body, rsaAesEncodeData[0:]...)
|
|
|
|
|
|
body = append(body, aesEncodeData[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
/*sendData,secKeyMgr:= Pack12(userInfo, body, baseinfo.MMRequestTypeAutoAuth, 12)
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/autoauth",sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
log.Error("mmtls error", err.Error())
|
|
|
|
|
|
}
|
|
|
|
|
|
packHeader, err:= DecodePackHeader(resp, nil)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
log.Error("ecdhDataPacket error", err.Error())
|
|
|
|
|
|
}
|
|
|
|
|
|
packHeader.Data, err = clientsdk.HybridEcdhDecrypt(packHeader.Data, secKeyMgr.PriKey, secKeyMgr.PubKey, secKeyMgr.FinalSha256)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
log.Error("HybridEcdhDecrypt error", err.Error())
|
|
|
|
|
|
}
|
|
|
|
|
|
return packHeader,nil*/
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
sendData := Pack(userInfo, body, baseinfo.MMRequestTypeAutoAuth, 9)
|
|
|
|
|
|
MMInfo := userInfo.GetMMInfo()
|
|
|
|
|
|
MMInfo.Dialer = userInfo.GetDialer()
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(MMInfo, "/cgi-bin/micromsg-bin/autoauth", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetCheckLoginQRCodeRequest 长链接:获取检测二维码状态-请求数据包
|
|
|
|
|
|
func GetCheckLoginQRCodeRequest(userInfo *baseinfo.UserInfo, qrcodeUUID string, qrcodeKey []byte) ([]byte, error) {
|
|
|
|
|
|
var request wechat.CheckLoginQRCodeRequest
|
|
|
|
|
|
// 重新生成AesKey
|
|
|
|
|
|
//userInfo.SessionKey = baseutils.RandomBytes(16)
|
|
|
|
|
|
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// AESKey
|
|
|
|
|
|
var aesKey wechat.AESKey
|
|
|
|
|
|
var tmpAesKeyLen = uint32(16)
|
|
|
|
|
|
aesKey.Len = &tmpAesKeyLen
|
|
|
|
|
|
aesKey.Key = []byte(userInfo.SessionKey)
|
|
|
|
|
|
request.Aes = &aesKey
|
|
|
|
|
|
|
|
|
|
|
|
// uuid
|
|
|
|
|
|
request.Uuid = &qrcodeUUID
|
|
|
|
|
|
|
|
|
|
|
|
// timeStamp 当前系统时间
|
|
|
|
|
|
timeStamp := (uint32)(time.Now().Unix())
|
|
|
|
|
|
request.TimeStamp = &timeStamp
|
|
|
|
|
|
|
|
|
|
|
|
// OpCode
|
|
|
|
|
|
var tmpOpcode = uint32(0)
|
|
|
|
|
|
request.Opcode = &tmpOpcode
|
|
|
|
|
|
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
src, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, src, baseinfo.MMRequestTypeCheckLoginQRCode, 7)
|
|
|
|
|
|
return sendData, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendPushQrLoginNotice 二维码二次登录
|
|
|
|
|
|
func SendPushQrLoginNotice(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.PushLoginURLRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
|
|
|
|
|
|
request = wechat.PushLoginURLRequest{
|
|
|
|
|
|
BaseRequest: baseReq,
|
|
|
|
|
|
UserName: proto.String(userInfo.GetUserName()),
|
|
|
|
|
|
AutoAuthTicket: proto.String(""),
|
|
|
|
|
|
ClientID: proto.String(fmt.Sprintf("iPad-Push-%s.110141", userInfo.DeviceInfo.DeviceID)),
|
|
|
|
|
|
RandomEnCryptKey: &wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(uint32(len(userInfo.SessionKey))),
|
|
|
|
|
|
Buffer: userInfo.SessionKey,
|
|
|
|
|
|
},
|
|
|
|
|
|
OPCode: proto.Uint32(3),
|
|
|
|
|
|
DeviceName: proto.String(userInfo.DeviceInfo.DeviceName),
|
|
|
|
|
|
AutoAuthKey: &wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(uint32(len(userInfo.AutoAuthKey))),
|
|
|
|
|
|
Buffer: userInfo.AutoAuthKey,
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
src, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, src, baseinfo.MMRequestTypePushQrLogin, 1)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/pushloginurl", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetHeartBeatShortRequest 短链接心跳
|
|
|
|
|
|
func GetHeartBeatShortRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
sendData, err := GetHeartBeatRequest(userInfo)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
MMInfo := userInfo.GetMMInfo()
|
|
|
|
|
|
MMInfo.Dialer = userInfo.GetDialer()
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(MMInfo, "/cgi-bin/micromsg-bin/heartbeat", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetHeartBeatRequest 长链接:获取心跳包-请求数据包
|
|
|
|
|
|
func GetHeartBeatRequest(userInfo *baseinfo.UserInfo) ([]byte, error) {
|
|
|
|
|
|
var request wechat.HeartBeatRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// timeStamp 当前系统时间
|
|
|
|
|
|
timeStamp := (uint32)(time.Now().UnixNano() / 1000000000)
|
|
|
|
|
|
request.TimeStamp = &timeStamp
|
|
|
|
|
|
|
|
|
|
|
|
// Scene
|
|
|
|
|
|
request.Scene = &tmpScene
|
|
|
|
|
|
|
|
|
|
|
|
// KeyBuf
|
|
|
|
|
|
request.KeyBuf = &wechat.SKBuiltinString_{}
|
|
|
|
|
|
request.KeyBuf.Buffer = userInfo.SessionKey
|
|
|
|
|
|
request.KeyBuf.Len = proto.Uint32(uint32(len(userInfo.SessionKey)))
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据
|
|
|
|
|
|
src, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, src, baseinfo.MMRequestTypeHeartBeat, 5)
|
|
|
|
|
|
return sendData, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendNewSyncRequest 发送同步信息请求
|
|
|
|
|
|
func SendNewSyncRequest(userInfo *baseinfo.UserInfo, scene uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.NewSyncRequest
|
|
|
|
|
|
zeroValue32 := uint32(0)
|
|
|
|
|
|
|
|
|
|
|
|
// Oplog
|
|
|
|
|
|
var opLog wechat.CmdList
|
|
|
|
|
|
opLog.Count = &zeroValue32
|
|
|
|
|
|
opLog.ItemList = make([]*wechat.CmdItem, 0)
|
|
|
|
|
|
request.Oplog = &opLog
|
|
|
|
|
|
|
|
|
|
|
|
// Selector
|
|
|
|
|
|
tmpSelector := uint32(262151)
|
|
|
|
|
|
request.Selector = &tmpSelector
|
|
|
|
|
|
|
|
|
|
|
|
// keyBuf
|
|
|
|
|
|
var keyBuf wechat.SKBuiltinString_
|
|
|
|
|
|
keyBuf.Buffer = userInfo.SyncKey
|
|
|
|
|
|
tmpLen := uint32(len(keyBuf.Buffer))
|
|
|
|
|
|
keyBuf.Len = &tmpLen
|
|
|
|
|
|
request.KeyBuf = &keyBuf
|
|
|
|
|
|
|
|
|
|
|
|
// Scene
|
|
|
|
|
|
request.Scene = &scene
|
|
|
|
|
|
// DeviceType
|
|
|
|
|
|
if userInfo.DeviceInfoA16 != nil {
|
|
|
|
|
|
request.DeviceType = &baseinfo.AndroidDeviceType
|
|
|
|
|
|
} else {
|
|
|
|
|
|
request.DeviceType = &userInfo.DeviceInfo.OsType
|
|
|
|
|
|
}
|
|
|
|
|
|
// syncMsgDigest : 短链接同步
|
|
|
|
|
|
syncMsgDigest := baseinfo.MMSyncMsgDigestTypeShortLink
|
|
|
|
|
|
request.SyncMsgDigest = &syncMsgDigest
|
|
|
|
|
|
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
src, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, src, baseinfo.MMRequestTypeNewSync, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/newsync", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 同步消息
|
|
|
|
|
|
func SendWxSyncMsg(userInfo *baseinfo.UserInfo, key string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
zeroValue32 := uint32(0)
|
|
|
|
|
|
// Oplog
|
|
|
|
|
|
var opLog wechat.CmdList
|
|
|
|
|
|
opLog.Count = &zeroValue32
|
|
|
|
|
|
opLog.ItemList = make([]*wechat.CmdItem, 0)
|
|
|
|
|
|
//
|
|
|
|
|
|
var keyBuf wechat.SKBuiltinString_
|
|
|
|
|
|
keyBuf.Buffer = userInfo.SyncKey
|
|
|
|
|
|
if key != "" {
|
|
|
|
|
|
keyBuf.Buffer = []byte(key)
|
|
|
|
|
|
}
|
|
|
|
|
|
tmpLen := uint32(len(keyBuf.Buffer))
|
|
|
|
|
|
keyBuf.Len = &tmpLen
|
|
|
|
|
|
request := wechat.NewSyncRequest{
|
|
|
|
|
|
Oplog: &opLog,
|
|
|
|
|
|
Selector: proto.Uint32(262151),
|
|
|
|
|
|
Scene: proto.Uint32(4),
|
|
|
|
|
|
DeviceType: proto.String(userInfo.DeviceInfo.OsType),
|
|
|
|
|
|
SyncMsgDigest: proto.Uint32(baseinfo.MMSyncMsgDigestTypeShortLink),
|
|
|
|
|
|
KeyBuf: &keyBuf,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
src, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, src, baseinfo.MMRequestTypeNewSync, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/newsync", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendGetProfileRequest 发送获取帐号所有信息请求
|
|
|
|
|
|
func SendGetProfileRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.GetProfileRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpZero = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpZero
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetProfile, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getprofile", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取设备
|
|
|
|
|
|
func SendGetSafetyInfoRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
baseRequest := GetBaseRequest(userInfo)
|
|
|
|
|
|
//baseRequest.Scene = proto.Uint32(1)
|
|
|
|
|
|
var req = wechat.GetSafetyInfoRequest{
|
|
|
|
|
|
BaseRequest: baseRequest,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 850, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getsafetyinfo", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 删除设备
|
|
|
|
|
|
func SendDelSafeDeviceRequest(userInfo *baseinfo.UserInfo, uuid string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
baseRequest := GetBaseRequest(userInfo)
|
|
|
|
|
|
//baseRequest.Scene = proto.Uint32(1)
|
|
|
|
|
|
var req = wechat.DelSafeDeviceRequest{
|
|
|
|
|
|
BaseRequest: baseRequest,
|
|
|
|
|
|
Uuid: proto.String(uuid),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 362, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/delsafedevice", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检测微信登录环境
|
|
|
|
|
|
func SendCheckCanSetAliasRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
baseRequest := GetBaseRequest(userInfo)
|
|
|
|
|
|
var req = wechat.CheckCanSetAliasReq{
|
|
|
|
|
|
BaseRequest: baseRequest,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 926, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/checkcansetalias", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendInitContactReq 初始化联系人列表
|
|
|
|
|
|
func SendInitContactReq(userInfo *baseinfo.UserInfo, contactSeq uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.InitContactReq
|
|
|
|
|
|
|
|
|
|
|
|
// Username
|
|
|
|
|
|
request.Username = &userInfo.WxId
|
|
|
|
|
|
// CurrentWxcontactSeq
|
|
|
|
|
|
request.CurrentWxcontactSeq = &contactSeq
|
|
|
|
|
|
// CurrentChatRoomContactSeq
|
|
|
|
|
|
roomContactSeq := uint32(0)
|
|
|
|
|
|
request.CurrentChatRoomContactSeq = &roomContactSeq
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeInitContact, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/initcontact", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func GetContactListPageReq(userInfo *baseinfo.UserInfo, CurrentWxcontactSeq uint32, CurrentChatRoomContactSeq uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.InitContactReq
|
|
|
|
|
|
|
|
|
|
|
|
// Username
|
|
|
|
|
|
request.Username = &userInfo.WxId
|
|
|
|
|
|
// CurrentWxcontactSeq
|
|
|
|
|
|
request.CurrentWxcontactSeq = &CurrentWxcontactSeq
|
|
|
|
|
|
request.CurrentChatRoomContactSeq = &CurrentChatRoomContactSeq
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeInitContact, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/initcontact", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendBatchGetContactBriefInfoReq 批量获取联系人信息
|
|
|
|
|
|
func SendBatchGetContactBriefInfoReq(userInfo *baseinfo.UserInfo, userNameList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.BatchGetContactBriefInfoReq
|
|
|
|
|
|
request.ContactUsernameList = userNameList
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeBatchGetContactBriefInfo, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/batchgetcontactbriefinfo", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func SendGetFriendRelationReq(userInfo *baseinfo.UserInfo, userName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.MMBizJsApiGetUserOpenIdRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(1)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
request.AppId = proto.String("wx7c8d593b2c3a7703")
|
|
|
|
|
|
request.UserName = proto.String(userName)
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
//获取好友关系状态
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 1177, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmbiz-bin/usrmsg/mmbizjsapi_getuseropenid", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendGetContactRequest 获取指定微信号信息请求, userWxID:联系人ID roomWxID:群ID
|
|
|
|
|
|
func SendGetContactRequest(userInfo *baseinfo.UserInfo, userWxIDList []string, antisPanTicketList []string, roomWxIDList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.GetContactRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// userCount
|
|
|
|
|
|
var userCount = uint32(len(userWxIDList))
|
|
|
|
|
|
request.UserCount = &userCount
|
|
|
|
|
|
// UserNameList
|
|
|
|
|
|
userNameList := make([]*wechat.SKBuiltinString, userCount)
|
|
|
|
|
|
// 遍历
|
|
|
|
|
|
for index := uint32(0); index < userCount; index++ {
|
|
|
|
|
|
userNameItem := new(wechat.SKBuiltinString)
|
|
|
|
|
|
userNameItem.Str = &userWxIDList[index]
|
|
|
|
|
|
userNameList[index] = userNameItem
|
|
|
|
|
|
}
|
|
|
|
|
|
request.UserNameList = userNameList
|
|
|
|
|
|
|
|
|
|
|
|
// AntispamTicketCount
|
|
|
|
|
|
antispamTicketCount := uint32(len(antisPanTicketList))
|
|
|
|
|
|
request.AntispamTicketCount = &antispamTicketCount
|
|
|
|
|
|
// AntispamTicket
|
|
|
|
|
|
tmpAntispamTicketList := make([]*wechat.SKBuiltinString, antispamTicketCount)
|
|
|
|
|
|
for index := uint32(0); index < antispamTicketCount; index++ {
|
|
|
|
|
|
antispamTicket := new(wechat.SKBuiltinString)
|
|
|
|
|
|
antispamTicket.Str = &antisPanTicketList[index]
|
|
|
|
|
|
tmpAntispamTicketList[index] = antispamTicket
|
|
|
|
|
|
}
|
|
|
|
|
|
request.AntispamTicket = tmpAntispamTicketList
|
|
|
|
|
|
|
|
|
|
|
|
// FromChatRoomCount
|
|
|
|
|
|
fromChatRoomCount := uint32(len(roomWxIDList))
|
|
|
|
|
|
request.FromChatRoomCount = &fromChatRoomCount
|
|
|
|
|
|
// FromChatRoom
|
|
|
|
|
|
fromChatRoomList := make([]*wechat.SKBuiltinString, fromChatRoomCount)
|
|
|
|
|
|
for index := uint32(0); index < fromChatRoomCount; index++ {
|
|
|
|
|
|
fromChatRoom := new(wechat.SKBuiltinString)
|
|
|
|
|
|
fromChatRoom.Str = &roomWxIDList[index]
|
|
|
|
|
|
fromChatRoomList[index] = fromChatRoom
|
|
|
|
|
|
}
|
|
|
|
|
|
request.FromChatRoom = fromChatRoomList
|
|
|
|
|
|
|
|
|
|
|
|
// GetContactScene
|
|
|
|
|
|
var getContactScene = uint32(0)
|
|
|
|
|
|
request.GetContactScene = &getContactScene
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetContact, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getcontact", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建红包
|
|
|
|
|
|
func SendWXCreateRedPacket(userInfo *baseinfo.UserInfo, hbItem *baseinfo.RedPacket) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.HongBaoReq
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
// CgiCmd
|
|
|
|
|
|
request.CgiCmd = proto.Uint32(0)
|
|
|
|
|
|
// OutPutType
|
|
|
|
|
|
request.OutPutType = proto.Uint32(0)
|
|
|
|
|
|
// ReqText
|
|
|
|
|
|
strReqText := string("")
|
|
|
|
|
|
strReqText = strReqText + "city=Guangzhou&"
|
|
|
|
|
|
strReqText = strReqText + "hbType=" + strconv.Itoa(int(hbItem.RedType)) + "&"
|
|
|
|
|
|
strReqText = strReqText + "headImg=" + "&"
|
|
|
|
|
|
strReqText = strReqText + "inWay=" + strconv.Itoa(int(hbItem.From)) + "&"
|
|
|
|
|
|
strReqText = strReqText + "needSendToMySelf=0" + "&"
|
|
|
|
|
|
strReqText = strReqText + "nickName=" + url.QueryEscape(userInfo.NickName) + "&"
|
|
|
|
|
|
strReqText = strReqText + "perValue=" + strconv.Itoa(int(hbItem.Amount)) + "&"
|
|
|
|
|
|
strReqText = strReqText + "province=Guangdong" + "&"
|
|
|
|
|
|
strReqText = strReqText + "sendUserName=" + userInfo.WxId + "&"
|
|
|
|
|
|
strReqText = strReqText + "totalAmount=" + strconv.Itoa(int(hbItem.Amount*hbItem.Count)) + "&"
|
|
|
|
|
|
strReqText = strReqText + "totalNum=" + strconv.Itoa(int(hbItem.Count)) + "&"
|
|
|
|
|
|
strReqText = strReqText + "username=" + hbItem.Username + "&"
|
|
|
|
|
|
strReqText = strReqText + "wishing=" + url.QueryEscape(hbItem.Content)
|
|
|
|
|
|
var reqText wechat.SKBuiltinString_
|
|
|
|
|
|
reqText.Buffer = []byte(strReqText)
|
|
|
|
|
|
tmpLen := uint32(len(reqText.Buffer))
|
|
|
|
|
|
reqText.Len = &tmpLen
|
|
|
|
|
|
request.ReqText = &reqText
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 1575, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmpay-bin/requestwxhb", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendReceiveWxHB 发送接收红包请求
|
|
|
|
|
|
func SendReceiveWxHB(userInfo *baseinfo.UserInfo, hongBaoReceiverItem *baseinfo.HongBaoReceiverItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.HongBaoReq
|
|
|
|
|
|
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// CgiCmd
|
|
|
|
|
|
request.CgiCmd = &hongBaoReceiverItem.CgiCmd
|
|
|
|
|
|
|
|
|
|
|
|
// OutPutType
|
|
|
|
|
|
outputType := baseinfo.MMTenPayReqOutputTypeJSON
|
|
|
|
|
|
request.OutPutType = &outputType
|
|
|
|
|
|
/**agreeDuty=0
|
|
|
|
|
|
&channelId=1
|
|
|
|
|
|
&encrypt_key=T1LVNmOtXtStQDQwgZP81guupLsaO6meiWltwBFoSNL+WSIFmhqa1msSZ1J0HsRjE0V0u0k2qp2Yrqihjr8WXyV/okS+/4mJEl6whzupyQKYil69t/2kZ87agWyblo0A2SiozLrZSvs2HjFy9SH3IgXVECDSGKWVXcwJ3QqBmvY=&
|
|
|
|
|
|
encrypt_userinfo=RU3cO5jg3eSTw+Kiwh14q3GhRM3Vk6ZNA5FD4BwmUxo+Bkr/JMItKC10pnNKUgsPfIpZ1/G1tk2MBtCwtQwo8A==&group_name=48593899189@chatroom
|
|
|
|
|
|
&inWay=0
|
|
|
|
|
|
&msgType=1&
|
|
|
|
|
|
nativeUrl=wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1800008896202411036324429265017&ver=2&sign=AARxHbYBAAABAAAAAAC07b6S00apLZ%2F7lz0nZyAAAAD5K3H1P3TTsgLxNwDzPyfEp2uvjYg0WGAGRbvB%2BrLW1PF0gCgzTvftYOhOXdBog8moWaYrvz7UoWuTijySa63rd0mAoTd3caJvpcvBzjUQcHvGUsYShwUN28KEUV6S6MOdl8QhdoPeRYZXwZC8kGaJCoLJ5t8zfDGgmdotHQ%3D%3D&
|
|
|
|
|
|
sendId=1800008896202411036324429265017&union_source=0
|
|
|
|
|
|
*/
|
|
|
|
|
|
// ReqText
|
|
|
|
|
|
strReqText := string("")
|
|
|
|
|
|
strReqText = strReqText + "agreeDuty=0&"
|
|
|
|
|
|
strReqText = strReqText + "channelId=" + hongBaoReceiverItem.HongBaoURLItem.ChannelID + "&"
|
|
|
|
|
|
// strReqText = strReqText + "city=" + hongBaoReceiverItem.City + "&"
|
|
|
|
|
|
strReqText = strReqText + "encrypt_key=" + baseutils.EscapeURL(userInfo.HBAesKeyEncrypted) + "&"
|
|
|
|
|
|
strReqText = strReqText + "encrypt_userinfo=" + baseutils.EscapeURL(GetEncryptUserInfo(userInfo)) + "&"
|
|
|
|
|
|
strReqText = strReqText + "inWay=" + strconv.Itoa(int(hongBaoReceiverItem.InWay)) + "&"
|
|
|
|
|
|
strReqText = strReqText + "msgType=" + hongBaoReceiverItem.HongBaoURLItem.MsgType + "&"
|
|
|
|
|
|
strReqText = strReqText + "nativeUrl=" + baseutils.EscapeURL(hongBaoReceiverItem.NativeURL) + "&"
|
|
|
|
|
|
// strReqText = strReqText + "province=" + hongBaoReceiverItem.Province + "&"
|
|
|
|
|
|
strReqText = strReqText + "sendId=" + hongBaoReceiverItem.HongBaoURLItem.SendID
|
|
|
|
|
|
// strReqText = strReqText + "union_source=0"
|
|
|
|
|
|
var reqText wechat.SKBuiltinString_
|
|
|
|
|
|
reqText.Buffer = []byte(strReqText)
|
|
|
|
|
|
tmpLen := uint32(len(reqText.Buffer))
|
|
|
|
|
|
reqText.Len = &tmpLen
|
|
|
|
|
|
request.ReqText = &reqText
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
RequestType := baseinfo.MMRequestTypeReceiveWxHB
|
|
|
|
|
|
urlPath := "/cgi-bin/mmpay-bin/receivewxhb"
|
|
|
|
|
|
if hongBaoReceiverItem.SceneID == uint32(1005) {
|
|
|
|
|
|
// 企业外部群红包 timingIdentifier
|
|
|
|
|
|
//RequestType = uint32(4536)
|
|
|
|
|
|
strReqText = strReqText + "&union_source=0"
|
|
|
|
|
|
strReqText = strReqText + "&group_name=" + baseutils.EscapeURL(hongBaoReceiverItem.HongBaoURLItem.SendUserName)
|
|
|
|
|
|
|
|
|
|
|
|
//"encrypt_key"
|
|
|
|
|
|
//"group_name"
|
|
|
|
|
|
urlPath = "/cgi-bin/mmpay-bin/unionhb/receiveunionhb"
|
|
|
|
|
|
CgiCmd := uint32(4536)
|
|
|
|
|
|
request.CgiCmd = &CgiCmd
|
|
|
|
|
|
|
|
|
|
|
|
reqText.Buffer = []byte(strReqText)
|
|
|
|
|
|
tmpLen := uint32(len(reqText.Buffer))
|
|
|
|
|
|
reqText.Len = &tmpLen
|
|
|
|
|
|
request.ReqText = &reqText
|
|
|
|
|
|
// fmt.Print("企业外部群红包 timingIdentifier")
|
|
|
|
|
|
}
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
// userInfo.ClientVersion = ClientVersion
|
|
|
|
|
|
// fmt.Print("\nRequestType:", RequestType)
|
|
|
|
|
|
// fmt.Print("\nurlPath:", urlPath)
|
|
|
|
|
|
// fmt.Print("\n")
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, RequestType, 5)
|
|
|
|
|
|
// byte[] 转 string
|
|
|
|
|
|
// sendEncodeDataStr := string(srcData)
|
|
|
|
|
|
// fmt.Println("srcData: ", sendEncodeDataStr)
|
|
|
|
|
|
///cgi-bin/mmpay-bin/unionhb 企业群红包
|
|
|
|
|
|
/// 打开红包
|
|
|
|
|
|
// 长链接发送
|
|
|
|
|
|
// fmt.Print("\n发送长连接接收红包请求\n")
|
|
|
|
|
|
// err := mmtls.MMTCPSendReq(userInfo.MMInfo, mmtls.MMLongOperationRequest, sendEncodeData)
|
|
|
|
|
|
// if err != nil {
|
|
|
|
|
|
// return nil, err
|
|
|
|
|
|
// }
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, urlPath, sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fmt.Println("err:", err)
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendOpenWxHB 发送领取红包请求
|
|
|
|
|
|
func SendOpenWxHB(userInfo *baseinfo.UserInfo, hongBaoOpenItem *baseinfo.HongBaoOpenItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.HongBaoReq
|
|
|
|
|
|
|
|
|
|
|
|
// "channelId": "1",
|
|
|
|
|
|
// "encrypt_key": "T1LVNmOtXtStQDQwgZP81guupLsaO6meiWltwBFoSNL+WSIFmhqa1msSZ1J0HsRjE0V0u0k2qp2Yrqihjr8WXyV/okS+/4mJEl6whzupyQKYil69t/2kZ87agWyblo0A2SiozLrZSvs2HjFy9SH3IgXVECDSGKWVXcwJ3QqBmvY=",
|
|
|
|
|
|
// "encrypt_userinfo": "RU3cO5jg3eSTw+Kiwh14q3GhRM3Vk6ZNA5FD4BwmUxo+Bkr/JMItKC10pnNKUgsPfIpZ1/G1tk2MBtCwtQwo8A==",
|
|
|
|
|
|
// "headImg": "https://wx.qlogo.cn/mmhead/ver_1/iaGwFC19C856VC76SkWmjlib40vgX6xtIQkbUM32rF45VDstSpH6KOdGoKaFCceXT04ia3NayIYspXPTpKcuw33UDcwasgaVkVgLttHCIUnMI0GjV8qd5es6lSUeWZwZry2/132",
|
|
|
|
|
|
// "msgType": "1",
|
|
|
|
|
|
// "nativeUrl": "wxpay://c2cbizmessagehandler/hongbao/receivehongbao?msgtype=1&channelid=1&sendid=1800008896202411036324429265017&ver=2&sign=AARxHbYBAAABAAAAAAC07b6S00apLZ%2F7lz0nZyAAAAD5K3H1P3TTsgLxNwDzPyfEp2uvjYg0WGAGRbvB%2BrLW1PF0gCgzTvftYOhOXdBog8moWaYrvz7UoWuTijySa63rd0mAoTd3caJvpcvBzjUQcHvGUsYShwUN28KEUV6S6MOdl8QhdoPeRYZXwZC8kGaJCoLJ5t8zfDGgmdotHQ%3D%3D",
|
|
|
|
|
|
// "nickName": "琳琳",
|
|
|
|
|
|
// "sendId": "1800008896202411036324429265017",
|
|
|
|
|
|
// "sessionUserName": "48593899189@chatroom",
|
|
|
|
|
|
// "timingIdentifier": "87a72ff1f1700e4dc289b712ff9bdfae",
|
|
|
|
|
|
// "union_source": "0"
|
|
|
|
|
|
///402665260
|
|
|
|
|
|
// baserequest402665506
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// CgiCmd
|
|
|
|
|
|
request.CgiCmd = &hongBaoOpenItem.CgiCmd
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
// OutPutType
|
|
|
|
|
|
outputType := baseinfo.MMTenPayReqOutputTypeJSON
|
|
|
|
|
|
request.OutPutType = &outputType
|
|
|
|
|
|
|
|
|
|
|
|
// ReqText
|
|
|
|
|
|
strReqText := string("")
|
|
|
|
|
|
strReqText = strReqText + "channelId=" + hongBaoOpenItem.HongBaoURLItem.ChannelID + "&"
|
|
|
|
|
|
strReqText = strReqText + "city=" + hongBaoOpenItem.City + "&"
|
|
|
|
|
|
strReqText = strReqText + "encrypt_key=" + baseutils.EscapeURL(userInfo.HBAesKeyEncrypted) + "&"
|
|
|
|
|
|
strReqText = strReqText + "encrypt_userinfo=" + baseutils.EscapeURL(GetEncryptUserInfo(userInfo)) + "&"
|
|
|
|
|
|
strReqText = strReqText + "headImg=" + baseutils.EscapeURL(hongBaoOpenItem.HeadImg) + "&"
|
|
|
|
|
|
strReqText = strReqText + "msgType=" + hongBaoOpenItem.HongBaoURLItem.MsgType + "&"
|
|
|
|
|
|
strReqText = strReqText + "nativeUrl=" + baseutils.EscapeURL(hongBaoOpenItem.NativeURL) + "&"
|
|
|
|
|
|
strReqText = strReqText + "nickName=" + baseutils.HongBaoStringToBytes(hongBaoOpenItem.NickName) + "&"
|
|
|
|
|
|
strReqText = strReqText + "province=" + hongBaoOpenItem.Province + "&"
|
|
|
|
|
|
strReqText = strReqText + "sendId=" + hongBaoOpenItem.HongBaoURLItem.SendID + "&"
|
|
|
|
|
|
strReqText = strReqText + "sessionUserName=" + hongBaoOpenItem.HongBaoURLItem.SendUserName + "&"
|
|
|
|
|
|
strReqText = strReqText + "timingIdentifier=" + hongBaoOpenItem.TimingIdentifier
|
|
|
|
|
|
// strReqText = strReqText + "&union_source=0"
|
|
|
|
|
|
// fmt.Println("strReqText: ")
|
|
|
|
|
|
// fmt.Println(strReqText)
|
|
|
|
|
|
var reqText wechat.SKBuiltinString_
|
|
|
|
|
|
reqText.Buffer = []byte(strReqText)
|
|
|
|
|
|
tmpLen := uint32(len(reqText.Buffer))
|
|
|
|
|
|
reqText.Len = &tmpLen
|
|
|
|
|
|
request.ReqText = &reqText
|
|
|
|
|
|
|
|
|
|
|
|
urlPath := "/cgi-bin/mmpay-bin/openwxhb"
|
|
|
|
|
|
RequestType := baseinfo.MMRequestTypeReceiveWxHB
|
|
|
|
|
|
// if hongBaoOpenItem.SceneID == uint32(1005) {
|
|
|
|
|
|
// // 企业外部群红包
|
|
|
|
|
|
// RequestType = uint32(5148)
|
|
|
|
|
|
// CgiCmd := uint32(0x141c)
|
|
|
|
|
|
// request.CgiCmd = &CgiCmd
|
|
|
|
|
|
// urlPath = "/cgi-bin/mmpay-bin/unionhb"
|
|
|
|
|
|
// //打开 "4536",
|
|
|
|
|
|
// //拆开 "5148",
|
|
|
|
|
|
//
|
|
|
|
|
|
// }
|
|
|
|
|
|
// fmt.Println("\nurlPath: ")
|
|
|
|
|
|
// fmt.Println(urlPath)
|
|
|
|
|
|
// 打包发送数据
|
2026-02-26 10:44:13 +08:00
|
|
|
|
marshalStartMs := time.Now().UnixMilli()
|
2026-02-17 13:06:23 +08:00
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
2026-02-26 10:44:13 +08:00
|
|
|
|
marshalEndMs := time.Now().UnixMilli()
|
|
|
|
|
|
packStartMs := time.Now().UnixMilli()
|
2026-02-17 13:06:23 +08:00
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, RequestType, 5)
|
2026-02-26 10:44:13 +08:00
|
|
|
|
packEndMs := time.Now().UnixMilli()
|
2026-02-17 13:06:23 +08:00
|
|
|
|
|
2026-02-26 10:44:13 +08:00
|
|
|
|
httpStartMs := time.Now().UnixMilli()
|
2026-02-17 13:06:23 +08:00
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, urlPath, sendEncodeData)
|
2026-02-26 10:44:13 +08:00
|
|
|
|
httpEndMs := time.Now().UnixMilli()
|
2026-02-17 13:06:23 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-26 10:44:13 +08:00
|
|
|
|
decodeStartMs := time.Now().UnixMilli()
|
|
|
|
|
|
ph, err := DecodePackHeader(resp, nil)
|
|
|
|
|
|
decodeEndMs := time.Now().UnixMilli()
|
|
|
|
|
|
fmt.Printf("OpenWxHB细分 marshal=%dms pack=%dms http=%dms decodePackHeader=%dms\n",
|
|
|
|
|
|
marshalEndMs-marshalStartMs, packEndMs-packStartMs, httpEndMs-httpStartMs, decodeEndMs-decodeStartMs)
|
|
|
|
|
|
return ph, err
|
2026-02-17 13:06:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func SendOpenUninoHB(userInfo *baseinfo.UserInfo, hongBaoOpenItem *baseinfo.HongBaoOpenItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.HongBaoReq
|
|
|
|
|
|
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// CgiCmd
|
|
|
|
|
|
request.CgiCmd = &hongBaoOpenItem.CgiCmd
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
// OutPutType
|
|
|
|
|
|
outputType := baseinfo.MMTenPayReqOutputTypeJSON
|
|
|
|
|
|
request.OutPutType = &outputType
|
|
|
|
|
|
|
|
|
|
|
|
// ReqText
|
|
|
|
|
|
strReqText := string("")
|
|
|
|
|
|
strReqText = strReqText + "channelId=" + hongBaoOpenItem.HongBaoURLItem.ChannelID + "&"
|
|
|
|
|
|
//strReqText = strReqText + "city=" + hongBaoOpenItem.City + "&"
|
|
|
|
|
|
strReqText = strReqText + "encrypt_key=" + baseutils.EscapeURL(userInfo.HBAesKeyEncrypted) + "&"
|
|
|
|
|
|
strReqText = strReqText + "encrypt_userinfo=" + baseutils.EscapeURL(GetEncryptUserInfo(userInfo)) + "&"
|
|
|
|
|
|
strReqText = strReqText + "headImg=" + baseutils.EscapeURL(hongBaoOpenItem.HeadImg) + "&"
|
|
|
|
|
|
strReqText = strReqText + "msgType=" + hongBaoOpenItem.HongBaoURLItem.MsgType + "&"
|
|
|
|
|
|
strReqText = strReqText + "nativeUrl=" + baseutils.EscapeURL(hongBaoOpenItem.NativeURL) + "&"
|
|
|
|
|
|
strReqText = strReqText + "nickName=" + baseutils.HongBaoStringToBytes(hongBaoOpenItem.NickName) + "&"
|
|
|
|
|
|
//strReqText = strReqText + "province=" + hongBaoOpenItem.Province + "&"
|
|
|
|
|
|
strReqText = strReqText + "sendId=" + hongBaoOpenItem.HongBaoURLItem.SendID + "&"
|
|
|
|
|
|
strReqText = strReqText + "sessionUserName=" + hongBaoOpenItem.HongBaoURLItem.SendUserName + "&"
|
|
|
|
|
|
strReqText = strReqText + "timingIdentifier=" + hongBaoOpenItem.TimingIdentifier + "&"
|
|
|
|
|
|
strReqText = strReqText + "union_source=0"
|
|
|
|
|
|
// fmt.Println("strReqText: ")
|
|
|
|
|
|
// fmt.Println(strReqText)
|
|
|
|
|
|
var reqText wechat.SKBuiltinString_
|
|
|
|
|
|
reqText.Buffer = []byte(strReqText)
|
|
|
|
|
|
tmpLen := uint32(len(reqText.Buffer))
|
|
|
|
|
|
reqText.Len = &tmpLen
|
|
|
|
|
|
request.ReqText = &reqText
|
|
|
|
|
|
|
|
|
|
|
|
urlPath := "/cgi-bin/mmpay-bin/unionhb/openunionhb"
|
|
|
|
|
|
RequestType := baseinfo.MMRequestTypeReceiveWxHB
|
|
|
|
|
|
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, RequestType, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, urlPath, sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendRedEnvelopeWxHB 发送查看红包详情请求
|
|
|
|
|
|
func SendRedEnvelopeWxHB(userInfo *baseinfo.UserInfo, hongBaoOpenItem *baseinfo.HongBaoOpenItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.HongBaoReq
|
|
|
|
|
|
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// CgiCmd
|
|
|
|
|
|
request.CgiCmd = &hongBaoOpenItem.CgiCmd
|
|
|
|
|
|
|
|
|
|
|
|
// OutPutType
|
|
|
|
|
|
outputType := baseinfo.MMTenPayReqOutputTypeJSON
|
|
|
|
|
|
request.OutPutType = &outputType
|
|
|
|
|
|
|
|
|
|
|
|
// ReqText
|
|
|
|
|
|
strReqText := string("")
|
|
|
|
|
|
strReqText = strReqText + "agreeDuty=1" + "&"
|
|
|
|
|
|
strReqText = strReqText + "inWay=1" + "&"
|
|
|
|
|
|
strReqText = strReqText + "channelId=" + hongBaoOpenItem.HongBaoURLItem.ChannelID + "&"
|
|
|
|
|
|
strReqText = strReqText + "msgType=" + hongBaoOpenItem.HongBaoURLItem.MsgType + "&"
|
|
|
|
|
|
strReqText = strReqText + "nativeUrl=" + baseutils.EscapeURL(hongBaoOpenItem.NativeURL) + "&"
|
|
|
|
|
|
strReqText = strReqText + "sendId=" + hongBaoOpenItem.HongBaoURLItem.SendID + "&"
|
|
|
|
|
|
strReqText = strReqText + "sessionUserName=" + hongBaoOpenItem.HongBaoURLItem.SendUserName + "&"
|
|
|
|
|
|
var reqText wechat.SKBuiltinString_
|
|
|
|
|
|
reqText.Buffer = []byte(strReqText)
|
|
|
|
|
|
tmpLen := uint32(len(reqText.Buffer))
|
|
|
|
|
|
reqText.Len = &tmpLen
|
|
|
|
|
|
request.ReqText = &reqText
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeQryDetailWxHB, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmpay-bin/qrydetailwxhb", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 查看红包领取列表
|
|
|
|
|
|
func SendGetRedPacketListRequest(userInfo *baseinfo.UserInfo, hongBaoOpenItem *baseinfo.GetRedPacketList) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.HongBaoReq
|
|
|
|
|
|
if hongBaoOpenItem.Limit == 0 {
|
|
|
|
|
|
hongBaoOpenItem.Limit = 11
|
|
|
|
|
|
}
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
// CgiCmd
|
|
|
|
|
|
request.CgiCmd = proto.Uint32(5)
|
|
|
|
|
|
// OutPutType
|
|
|
|
|
|
outputType := baseinfo.MMTenPayReqOutputTypeJSON
|
|
|
|
|
|
request.OutPutType = &outputType
|
|
|
|
|
|
// ReqText
|
|
|
|
|
|
strReqText := string("")
|
|
|
|
|
|
strReqText = strReqText + "channelId=" + hongBaoOpenItem.HongBaoItem.ChannelID + "&"
|
|
|
|
|
|
strReqText = strReqText + "msgType=" + hongBaoOpenItem.HongBaoItem.MsgType + "&"
|
|
|
|
|
|
strReqText = strReqText + "nativeUrl=" + baseutils.EscapeURL(hongBaoOpenItem.NativeURL) + "&province=&"
|
|
|
|
|
|
strReqText = strReqText + "sendId=" + hongBaoOpenItem.HongBaoItem.SendID + "&"
|
|
|
|
|
|
strReqText = strReqText + "limit=" + strconv.FormatInt(hongBaoOpenItem.Limit, 10) + "&"
|
|
|
|
|
|
strReqText = strReqText + "offset=" + strconv.FormatInt(hongBaoOpenItem.Offset, 10)
|
|
|
|
|
|
var reqText wechat.SKBuiltinString_
|
|
|
|
|
|
reqText.Buffer = []byte(strReqText)
|
|
|
|
|
|
tmpLen := uint32(len(reqText.Buffer))
|
|
|
|
|
|
reqText.Len = &tmpLen
|
|
|
|
|
|
request.ReqText = &reqText
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeQryDetailWxHB, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmpay-bin/qrydetailwxhb", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendCreatePreTransferRequest 创建转账
|
|
|
|
|
|
func SendCreatePreTransferRequest(userInfo *baseinfo.UserInfo, transferItem *req.CreatePreTransfer) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
description, fee, toUserName := transferItem.Description, transferItem.Fee, transferItem.ToUserName
|
|
|
|
|
|
var req_text = "delay_confirm_flag=0&desc=" + description + "&fee=" + strconv.Itoa(int(fee)) + "&fee_type=CNY&pay_scene=31&receiver_name=" + toUserName + "&scene=31&transfer_scene=2"
|
|
|
|
|
|
wcPaySign, err := TenPaySignDes3(req_text, "%^&*Tenpay!@#$")
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
req_text += "&WCPaySign=" + wcPaySign
|
|
|
|
|
|
tmpReqItem := &baseinfo.TenPayReqItem{}
|
|
|
|
|
|
tmpReqItem.CgiCMD = 0x53
|
|
|
|
|
|
tmpReqItem.ReqText = req_text
|
|
|
|
|
|
return SendWxPayTransferReq(userInfo, tmpReqItem)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendConfirmPreTransferRequest 确认转账
|
|
|
|
|
|
func SendConfirmPreTransferRequest(userInfo *baseinfo.UserInfo, transferItem *req.ConfirmPreTransfer) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
bankType, bankSerial := transferItem.BankType, transferItem.BankSerial
|
|
|
|
|
|
payPassword, reqKey := transferItem.PayPassword, transferItem.ReqKey
|
|
|
|
|
|
var req_text = "auto_deduct_flag=0&bank_type=" + bankType + "&bind_serial=" + bankSerial + "&busi_sms_flag=0&flag=3&passwd=" + payPassword + "&pay_scene=37&req_key=" + reqKey + "&use_touch=0"
|
|
|
|
|
|
wcPaySign, err := TenPaySignDes3(req_text, "%^&*Tenpay!@#$")
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
req_text += "&WCPaySign=" + wcPaySign
|
|
|
|
|
|
tmpReqItem := &baseinfo.TenPayReqItem{}
|
|
|
|
|
|
tmpReqItem.CgiCMD = 0
|
|
|
|
|
|
tmpReqItem.ReqText = req_text
|
|
|
|
|
|
return SendWxPayTransferReq(userInfo, tmpReqItem)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendWxPayTransferReq 发送微信支付之转账请求
|
|
|
|
|
|
func SendWxPayTransferReq(userInfo *baseinfo.UserInfo, reqItem *baseinfo.TenPayReqItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.TenPayRequest
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// CgiCmd
|
|
|
|
|
|
request.CgiCmd = &reqItem.CgiCMD
|
|
|
|
|
|
|
|
|
|
|
|
// OutPutType
|
|
|
|
|
|
outputType := baseinfo.MMTenPayReqOutputTypeJSON
|
|
|
|
|
|
request.OutPutType = &outputType
|
|
|
|
|
|
|
|
|
|
|
|
// ReqText
|
|
|
|
|
|
var reqTextSKBuf wechat.SKBuiltinString_
|
|
|
|
|
|
tmpLen := uint32(len(reqItem.ReqText))
|
|
|
|
|
|
reqTextSKBuf.Len = &tmpLen
|
|
|
|
|
|
reqTextSKBuf.Buffer = []byte(reqItem.ReqText)
|
|
|
|
|
|
request.ReqText = &reqTextSKBuf
|
|
|
|
|
|
|
|
|
|
|
|
// ReqTextWx
|
|
|
|
|
|
var wxReqTextSKBuf wechat.SKBuiltinString_
|
|
|
|
|
|
wxReqTextSKBuf.Buffer = []byte(reqItem.ReqText)
|
|
|
|
|
|
wxReqTextSKBuf.Len = &tmpLen
|
|
|
|
|
|
|
|
|
|
|
|
request.ReqTextWx = &wxReqTextSKBuf
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 385, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/tenpay", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendTextMsg 发送文本消息请求 toWxid:接受人微信id,content:消息内容,atWxIDList:@用户微信id列表(toWxid只能是群的wxid,content应为:@用户昵称 @用户昵称 消息内容)
|
|
|
|
|
|
func SendTextMsg(userInfo *baseinfo.UserInfo, toWxid string, content string, atWxIDList []string, ContentType int) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
// 构造请求
|
|
|
|
|
|
var request wechat.NewSendMsgRequest
|
|
|
|
|
|
var count uint32 = 1
|
|
|
|
|
|
request.MsgCount = &count
|
|
|
|
|
|
var msgRequestNewList []*wechat.MicroMsgRequestNew = make([]*wechat.MicroMsgRequestNew, count)
|
|
|
|
|
|
var msgRequestNew wechat.MicroMsgRequestNew
|
|
|
|
|
|
var recvierString wechat.SKBuiltinString
|
|
|
|
|
|
recvierString.Str = &toWxid
|
|
|
|
|
|
msgRequestNew.ToUserName = &recvierString // 设置接收人wxid
|
|
|
|
|
|
msgRequestNew.Content = &content // 设置发送内容
|
|
|
|
|
|
if ContentType == 0 {
|
|
|
|
|
|
ContentType = 1
|
|
|
|
|
|
}
|
|
|
|
|
|
var tmpType uint32 = uint32(ContentType)
|
|
|
|
|
|
msgRequestNew.Type = &tmpType // 发送的类型
|
|
|
|
|
|
currentTime := time.Now()
|
|
|
|
|
|
misSecond := currentTime.UnixNano() / 1000000
|
|
|
|
|
|
var seconds = uint32(misSecond / 1000)
|
|
|
|
|
|
msgRequestNew.CreateTime = &seconds // 设置时间 秒为单位
|
|
|
|
|
|
seqID := time.Now().UnixNano() / int64(time.Millisecond)
|
|
|
|
|
|
var tmpCheckCode = WithSeqidCalcCheckCode(toWxid, seqID)
|
|
|
|
|
|
msgRequestNew.ClientMsgId = &tmpCheckCode // 设置校验码
|
|
|
|
|
|
|
|
|
|
|
|
// atUserList
|
|
|
|
|
|
var atUserStr = string("")
|
|
|
|
|
|
size := len(atWxIDList)
|
|
|
|
|
|
if size > 0 {
|
|
|
|
|
|
atUserStr = atUserStr + "<msgsource><atuserlist>"
|
|
|
|
|
|
for index := 0; index < size; index++ {
|
|
|
|
|
|
atUserStr = atUserStr + atWxIDList[index]
|
|
|
|
|
|
if index < size-1 {
|
|
|
|
|
|
atUserStr = atUserStr + ","
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
atUserStr = atUserStr + "</atuserlist></msgsource>"
|
|
|
|
|
|
msgRequestNew.MsgSource = &atUserStr
|
|
|
|
|
|
}
|
|
|
|
|
|
msgRequestNewList[0] = &msgRequestNew
|
|
|
|
|
|
request.ChatSendList = msgRequestNewList
|
|
|
|
|
|
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, srcData, baseinfo.MMRequestTypeNewSendMsg, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/newsendmsg", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 发送图片v1.1
|
|
|
|
|
|
func SendUploadImageNewRequest(userInfo *baseinfo.UserInfo, imgData []byte, toUserName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
// 构造请求
|
|
|
|
|
|
var protobufdata []byte
|
|
|
|
|
|
imgStream := bytes.NewBuffer(imgData)
|
|
|
|
|
|
Startpos := 0
|
|
|
|
|
|
datalen := 50000
|
|
|
|
|
|
datatotalength := imgStream.Len()
|
|
|
|
|
|
ClientImgId := fmt.Sprintf("%v_%v", userInfo.WxId, time.Now().Unix())
|
|
|
|
|
|
I := 0
|
|
|
|
|
|
for {
|
|
|
|
|
|
Startpos = I * datalen
|
|
|
|
|
|
count := 0
|
|
|
|
|
|
if datatotalength-Startpos > datalen {
|
|
|
|
|
|
count = datalen
|
|
|
|
|
|
} else {
|
|
|
|
|
|
count = datatotalength - Startpos
|
|
|
|
|
|
}
|
|
|
|
|
|
if count < 0 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
Databuff := make([]byte, count)
|
|
|
|
|
|
_, _ = imgStream.Read(Databuff)
|
|
|
|
|
|
request := &wechat.UploadMsgImgRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
ClientImgId: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(ClientImgId),
|
|
|
|
|
|
},
|
|
|
|
|
|
SenderWxid: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(userInfo.WxId),
|
|
|
|
|
|
},
|
|
|
|
|
|
RecvWxid: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(toUserName),
|
|
|
|
|
|
},
|
|
|
|
|
|
TotalLen: proto.Uint32(uint32(datatotalength)),
|
|
|
|
|
|
StartPos: proto.Uint32(uint32(Startpos)),
|
|
|
|
|
|
DataLen: proto.Uint32(uint32(len(Databuff))),
|
|
|
|
|
|
Data: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(Databuff))),
|
|
|
|
|
|
Buffer: Databuff,
|
|
|
|
|
|
},
|
|
|
|
|
|
MsgType: proto.Uint32(3),
|
|
|
|
|
|
EncryVer: proto.Uint32(0),
|
|
|
|
|
|
ReqTime: proto.Uint32(uint32(time.Now().Unix())),
|
|
|
|
|
|
MessageExt: proto.String("png"),
|
|
|
|
|
|
}
|
|
|
|
|
|
//序列化
|
|
|
|
|
|
srcData, _ := proto.Marshal(request)
|
|
|
|
|
|
sendData := Pack(userInfo, srcData, baseinfo.MMRequestTypeForwardCdnImage, 5)
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
|
|
|
|
|
|
rsp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/uploadmsgimg", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
protobufdata = rsp
|
|
|
|
|
|
I++
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(protobufdata, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 发送企业oplog
|
|
|
|
|
|
func SendQWOpLogRequest(userInfo *baseinfo.UserInfo, cmdId int64, value []byte) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.QYOpLogRequest
|
|
|
|
|
|
request.Type = proto.Int64(cmdId)
|
|
|
|
|
|
request.V = value
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, srcData, 806, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/openimoplog", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendOplogRequest 发送修改帐号信息请求
|
|
|
|
|
|
func SendOplogRequest(userInfo *baseinfo.UserInfo, modifyItems []*baseinfo.ModifyItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.OplogRequest
|
|
|
|
|
|
// CmdList
|
|
|
|
|
|
var oplog wechat.CmdList
|
|
|
|
|
|
count := uint32(len(modifyItems))
|
|
|
|
|
|
oplog.Count = &count
|
|
|
|
|
|
|
|
|
|
|
|
// ItemList
|
|
|
|
|
|
cmdItemList := make([]*wechat.CmdItem, count)
|
|
|
|
|
|
var index = uint32(0)
|
|
|
|
|
|
for ; index < count; index++ {
|
|
|
|
|
|
//Item
|
|
|
|
|
|
cmdItem := &wechat.CmdItem{}
|
|
|
|
|
|
cmdItem.CmdId = &modifyItems[index].CmdID
|
|
|
|
|
|
|
|
|
|
|
|
cmdBuf := &wechat.DATA{}
|
|
|
|
|
|
cmdBuf.Len = &modifyItems[index].Len
|
|
|
|
|
|
cmdBuf.Data = modifyItems[index].Data
|
|
|
|
|
|
cmdItem.CmdBuf = cmdBuf
|
|
|
|
|
|
cmdItemList[index] = cmdItem
|
|
|
|
|
|
}
|
|
|
|
|
|
oplog.ItemList = cmdItemList
|
|
|
|
|
|
request.Oplog = &oplog
|
|
|
|
|
|
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, srcData, baseinfo.MMRequestTypeOplog, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/oplog", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendGetQRCodeRequest 获取二维码
|
|
|
|
|
|
func SendGetQRCodeRequest(userInfo *baseinfo.UserInfo, userName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.GetQRCodeRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// opCode
|
|
|
|
|
|
opcode := uint32(0)
|
|
|
|
|
|
request.Opcode = &opcode
|
|
|
|
|
|
|
|
|
|
|
|
// style
|
|
|
|
|
|
style := uint32(0)
|
|
|
|
|
|
request.Style = &style
|
|
|
|
|
|
|
|
|
|
|
|
// UserName
|
|
|
|
|
|
var userNameSKBuffer wechat.SKBuiltinString
|
|
|
|
|
|
userNameSKBuffer.Str = &userName
|
|
|
|
|
|
request.UserName = &userNameSKBuffer
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetQrCode, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getqrcode", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, []byte(userName))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendLogOutRequest 发送登出请求
|
|
|
|
|
|
func SendLogOutRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.LogOutRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
// 打包数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, srcData, 282, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/logout", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSnsPostRequest 发送朋友圈
|
|
|
|
|
|
func SendSnsPostRequest(userInfo *baseinfo.UserInfo, postItem *baseinfo.SnsPostItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.SnsPostRequest
|
|
|
|
|
|
zeroValue32 := uint32(0)
|
|
|
|
|
|
zeroValue64 := uint64(0)
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// ObjectDesc
|
|
|
|
|
|
objectDescData := CreateSnsPostItemXML(userInfo.WxId, postItem)
|
|
|
|
|
|
if postItem.Xml {
|
|
|
|
|
|
objectDescData = []byte(postItem.Content)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
length := uint32(len(objectDescData))
|
|
|
|
|
|
var objectDesc wechat.SKBuiltinString_
|
|
|
|
|
|
objectDesc.Len = &length
|
|
|
|
|
|
objectDesc.Buffer = objectDescData
|
|
|
|
|
|
request.ObjectDesc = &objectDesc
|
|
|
|
|
|
|
|
|
|
|
|
// WithUserListCount
|
|
|
|
|
|
withUserListCount := uint32(len(postItem.WithUserList))
|
|
|
|
|
|
request.WithUserListCount = &withUserListCount
|
|
|
|
|
|
// WithUserList
|
|
|
|
|
|
request.WithUserList = make([]*wechat.SKBuiltinString, withUserListCount)
|
|
|
|
|
|
index := uint32(0)
|
|
|
|
|
|
for ; index < withUserListCount; index++ {
|
|
|
|
|
|
withUser := &wechat.SKBuiltinString{}
|
|
|
|
|
|
withUser.Str = &postItem.WithUserList[index]
|
|
|
|
|
|
request.WithUserList[index] = withUser
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// BlackListCount
|
|
|
|
|
|
blackListCount := uint32(len(postItem.BlackList))
|
|
|
|
|
|
request.BlackListCount = &blackListCount
|
|
|
|
|
|
// BlackList
|
|
|
|
|
|
request.BlackList = make([]*wechat.SKBuiltinString, blackListCount)
|
|
|
|
|
|
index = uint32(0)
|
|
|
|
|
|
for ; index < blackListCount; index++ {
|
|
|
|
|
|
blackUser := &wechat.SKBuiltinString{}
|
|
|
|
|
|
blackUser.Str = &postItem.BlackList[index]
|
|
|
|
|
|
request.BlackList[index] = blackUser
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GroupUserCount
|
|
|
|
|
|
groupUserCount := uint32(len(postItem.GroupUserList))
|
|
|
|
|
|
request.GroupUserCount = &groupUserCount
|
|
|
|
|
|
// GroupUser
|
|
|
|
|
|
request.GroupUser = make([]*wechat.SKBuiltinString, groupUserCount)
|
|
|
|
|
|
index = uint32(0)
|
|
|
|
|
|
for ; index < groupUserCount; index++ {
|
|
|
|
|
|
groupUser := &wechat.SKBuiltinString{}
|
|
|
|
|
|
groupUser.Str = &postItem.GroupUserList[index]
|
|
|
|
|
|
request.GroupUser[index] = groupUser
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// otherFields
|
|
|
|
|
|
bgImageType := uint32(1)
|
|
|
|
|
|
request.PostBgimgType = &bgImageType
|
|
|
|
|
|
request.ObjectSource = &zeroValue32
|
|
|
|
|
|
request.ReferId = &zeroValue64
|
|
|
|
|
|
request.Privacy = &postItem.Privacy
|
|
|
|
|
|
request.SyncFlag = &zeroValue32
|
|
|
|
|
|
|
|
|
|
|
|
// ClientId
|
|
|
|
|
|
tmpTime := int(time.Now().UnixNano() / 1000000000)
|
|
|
|
|
|
tmpTimeStr := strconv.Itoa(tmpTime)
|
|
|
|
|
|
clientID := string("sns_post_")
|
|
|
|
|
|
clientID = clientID + userInfo.WxId + "_" + tmpTimeStr + "_0"
|
|
|
|
|
|
request.ClientId = &clientID
|
|
|
|
|
|
|
|
|
|
|
|
// groupCount
|
|
|
|
|
|
request.GroupCount = &zeroValue32
|
|
|
|
|
|
request.GroupIds = make([]*wechat.SnsGroup, zeroValue32)
|
|
|
|
|
|
|
|
|
|
|
|
// mediaInfoCount MediaInfo
|
|
|
|
|
|
mediaInfoCount := uint32(len(postItem.MediaList))
|
|
|
|
|
|
request.MediaInfoCount = &mediaInfoCount
|
|
|
|
|
|
request.MediaInfo = make([]*wechat.MediaInfo, mediaInfoCount)
|
|
|
|
|
|
for index := uint32(0); index < mediaInfoCount; index++ {
|
|
|
|
|
|
mediaInfo := &wechat.MediaInfo{}
|
|
|
|
|
|
source := uint32(2)
|
|
|
|
|
|
mediaInfo.Source = &source
|
|
|
|
|
|
|
|
|
|
|
|
// MediaType
|
|
|
|
|
|
mediaType := uint32(1)
|
|
|
|
|
|
if postItem.MediaList[index].Type == baseinfo.MMSNSMediaTypeImage {
|
|
|
|
|
|
mediaType = 1
|
|
|
|
|
|
}
|
|
|
|
|
|
mediaInfo.MediaType = &mediaType
|
|
|
|
|
|
|
|
|
|
|
|
// VideoPlayLength
|
|
|
|
|
|
mediaInfo.VideoPlayLength = &zeroValue32
|
|
|
|
|
|
|
|
|
|
|
|
// SessionId
|
|
|
|
|
|
currentTime := int(time.Now().UnixNano() / 1000000)
|
|
|
|
|
|
sessionID := "memonts-" + strconv.Itoa(currentTime)
|
|
|
|
|
|
mediaInfo.SessionId = &sessionID
|
|
|
|
|
|
|
|
|
|
|
|
// startTime
|
|
|
|
|
|
startTime := uint32(time.Now().UnixNano() / 1000000000)
|
|
|
|
|
|
mediaInfo.StartTime = &startTime
|
|
|
|
|
|
|
|
|
|
|
|
request.MediaInfo[index] = mediaInfo
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SnsPostOperationFields
|
|
|
|
|
|
var postOperationFields wechat.SnsPostOperationFields
|
|
|
|
|
|
postOperationFields.ContactTagCount = &zeroValue32
|
|
|
|
|
|
postOperationFields.TempUserCount = &zeroValue32
|
|
|
|
|
|
request.SnsPostOperationFields = &postOperationFields
|
|
|
|
|
|
|
|
|
|
|
|
// clientcheckdata
|
|
|
|
|
|
var extSpamInfo wechat.SKBuiltinString_
|
|
|
|
|
|
if userInfo.DeviceInfo != nil {
|
|
|
|
|
|
extSpamInfo.Buffer = GetExtPBSpamInfoDataIpad(userInfo)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
extSpamInfo.Buffer = GetExtPBSpamInfoDataA16(userInfo)
|
|
|
|
|
|
}
|
|
|
|
|
|
extSpamInfoLen := uint32(len(extSpamInfo.Buffer))
|
|
|
|
|
|
extSpamInfo.Len = &extSpamInfoLen
|
|
|
|
|
|
request.ExtSpamInfo = &extSpamInfo
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeMMSnsPost, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/mmsnspost", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSnsPostRequestByXML 通过XML的信息来发送朋友圈
|
|
|
|
|
|
func SendSnsPostRequestByXML(userInfo *baseinfo.UserInfo, timeLineObj *baseinfo.TimelineObject, blackList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
if timeLineObj.ContentObjectVideo != nil {
|
|
|
|
|
|
return SendSnsPostRequestByXMLVideoNum(userInfo, timeLineObj, blackList)
|
|
|
|
|
|
}
|
|
|
|
|
|
var request wechat.SnsPostRequest
|
|
|
|
|
|
zeroValue32 := uint32(0)
|
|
|
|
|
|
zeroValue64 := uint64(0)
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// WithUserListCount
|
|
|
|
|
|
withUserListCount := uint32(0)
|
|
|
|
|
|
request.WithUserListCount = &withUserListCount
|
|
|
|
|
|
// WithUserList
|
|
|
|
|
|
request.WithUserList = make([]*wechat.SKBuiltinString, withUserListCount)
|
|
|
|
|
|
|
|
|
|
|
|
// BlackListCount
|
|
|
|
|
|
tmpCount := uint32(len(blackList))
|
|
|
|
|
|
request.BlackListCount = &tmpCount
|
|
|
|
|
|
request.BlackList = make([]*wechat.SKBuiltinString, tmpCount)
|
|
|
|
|
|
// BlackList
|
|
|
|
|
|
for index := uint32(0); index < tmpCount; index++ {
|
|
|
|
|
|
tmpSKBuiltinString := &wechat.SKBuiltinString{}
|
|
|
|
|
|
tmpSKBuiltinString.Str = &blackList[index]
|
|
|
|
|
|
request.BlackList[index] = tmpSKBuiltinString
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GroupUserCount
|
|
|
|
|
|
groupUserCount := uint32(0)
|
|
|
|
|
|
request.GroupUserCount = &groupUserCount
|
|
|
|
|
|
// GroupUser
|
|
|
|
|
|
request.GroupUser = make([]*wechat.SKBuiltinString, groupUserCount)
|
|
|
|
|
|
|
|
|
|
|
|
// otherFields
|
|
|
|
|
|
bgImageType := uint32(1)
|
|
|
|
|
|
request.PostBgimgType = &bgImageType
|
|
|
|
|
|
request.ObjectSource = &zeroValue32
|
|
|
|
|
|
request.ReferId = &zeroValue64
|
|
|
|
|
|
request.Privacy = &timeLineObj.Private
|
|
|
|
|
|
request.SyncFlag = &zeroValue32
|
|
|
|
|
|
|
|
|
|
|
|
// ClientId
|
|
|
|
|
|
tmpTime := int(time.Now().UnixNano() / 1000000000)
|
|
|
|
|
|
tmpTimeStr := strconv.Itoa(tmpTime)
|
|
|
|
|
|
clientID := string("sns_post_")
|
|
|
|
|
|
clientID = clientID + userInfo.WxId + "_" + tmpTimeStr + "_0"
|
|
|
|
|
|
request.ClientId = &clientID
|
|
|
|
|
|
|
|
|
|
|
|
// groupCount
|
|
|
|
|
|
request.GroupCount = &zeroValue32
|
|
|
|
|
|
request.GroupIds = make([]*wechat.SnsGroup, zeroValue32)
|
|
|
|
|
|
|
|
|
|
|
|
// mediaInfoCount MediaInfo
|
|
|
|
|
|
mediaInfoCount := uint32(len(timeLineObj.ContentObject.MediaList.Media))
|
|
|
|
|
|
request.MediaInfoCount = &mediaInfoCount
|
|
|
|
|
|
request.MediaInfo = make([]*wechat.MediaInfo, mediaInfoCount)
|
|
|
|
|
|
for index := uint32(0); index < mediaInfoCount; index++ {
|
|
|
|
|
|
tmpMediaItem := timeLineObj.ContentObject.MediaList.Media[index]
|
|
|
|
|
|
|
|
|
|
|
|
// 解析Source
|
|
|
|
|
|
mediaInfo := &wechat.MediaInfo{}
|
|
|
|
|
|
tmpSource := baseutils.ParseInt(tmpMediaItem.URL.Type)
|
|
|
|
|
|
mediaInfo.Source = &tmpSource
|
|
|
|
|
|
// MediaType
|
|
|
|
|
|
mediaType := tmpMediaItem.Type - 1
|
|
|
|
|
|
mediaInfo.MediaType = &mediaType
|
|
|
|
|
|
// VideoPlayLength
|
|
|
|
|
|
playLength := uint32(tmpMediaItem.VideoDuration)
|
|
|
|
|
|
mediaInfo.VideoPlayLength = &playLength
|
|
|
|
|
|
// SessionId
|
|
|
|
|
|
currentTime := int(time.Now().UnixNano() / 1000000)
|
|
|
|
|
|
sessionID := "memonts-" + strconv.Itoa(currentTime)
|
|
|
|
|
|
mediaInfo.SessionId = &sessionID
|
|
|
|
|
|
|
|
|
|
|
|
// startTime
|
|
|
|
|
|
startTime := uint32(time.Now().UnixNano() / 1000000000)
|
|
|
|
|
|
mediaInfo.StartTime = &startTime
|
|
|
|
|
|
request.MediaInfo[index] = mediaInfo
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ID和UserName置为0
|
|
|
|
|
|
timeLineObj.UserName = userInfo.WxId
|
|
|
|
|
|
timeLineObj.CreateTime = uint32(int(time.Now().UnixNano() / 1000000000))
|
|
|
|
|
|
// ObjectDesc
|
|
|
|
|
|
objectDescData, err := xml.Marshal(timeLineObj)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
str := string(objectDescData)
|
|
|
|
|
|
str = strings.ReplaceAll(str, "token=\"\"", "")
|
|
|
|
|
|
str = strings.ReplaceAll(str, "key=\"\"", "")
|
|
|
|
|
|
str = strings.ReplaceAll(str, "enc_idx=\"\"", "")
|
|
|
|
|
|
str = strings.ReplaceAll(str, "md5=\"\"", "")
|
|
|
|
|
|
str = strings.ReplaceAll(str, "videomd5=\"\"", "")
|
|
|
|
|
|
str = strings.ReplaceAll(str, "video", "")
|
|
|
|
|
|
objectDescData = []byte(str)
|
|
|
|
|
|
length := uint32(len(objectDescData))
|
|
|
|
|
|
var objectDesc wechat.SKBuiltinString_
|
|
|
|
|
|
objectDesc.Len = &length
|
|
|
|
|
|
objectDesc.Buffer = objectDescData
|
|
|
|
|
|
request.ObjectDesc = &objectDesc
|
|
|
|
|
|
|
|
|
|
|
|
// SnsPostOperationFields
|
|
|
|
|
|
var postOperationFields wechat.SnsPostOperationFields
|
|
|
|
|
|
postOperationFields.ContactTagCount = &zeroValue32
|
|
|
|
|
|
postOperationFields.TempUserCount = &zeroValue32
|
|
|
|
|
|
request.SnsPostOperationFields = &postOperationFields
|
|
|
|
|
|
|
|
|
|
|
|
// clientcheckdata
|
|
|
|
|
|
var extSpamInfo wechat.SKBuiltinString_
|
|
|
|
|
|
if userInfo.DeviceInfo != nil {
|
|
|
|
|
|
extSpamInfo.Buffer = GetExtPBSpamInfoDataIpad(userInfo)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
extSpamInfo.Buffer = GetExtPBSpamInfoDataA16(userInfo)
|
|
|
|
|
|
}
|
|
|
|
|
|
extSpamInfoLen := uint32(len(extSpamInfo.Buffer))
|
|
|
|
|
|
extSpamInfo.Len = &extSpamInfoLen
|
|
|
|
|
|
request.ExtSpamInfo = &extSpamInfo
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeMMSnsPost, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/mmsnspost", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSnsPostRequestByXML 通过XML的信息来发送朋友圈(视频号)
|
|
|
|
|
|
func SendSnsPostRequestByXMLVideoNum(userInfo *baseinfo.UserInfo, timeLineObj *baseinfo.TimelineObject, blackList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.SnsPostRequest
|
|
|
|
|
|
zeroValue32 := uint32(0)
|
|
|
|
|
|
zeroValue64 := uint64(0)
|
|
|
|
|
|
fmt.Println("发布 视频号视频")
|
|
|
|
|
|
newTimeLineObj := &baseinfo.TimelineObjectVideo{
|
|
|
|
|
|
ID: timeLineObj.ID,
|
|
|
|
|
|
UserName: timeLineObj.UserName,
|
|
|
|
|
|
CreateTime: timeLineObj.CreateTime,
|
|
|
|
|
|
ContentDesc: timeLineObj.ContentDesc,
|
|
|
|
|
|
ContentDescShowType: timeLineObj.ContentDescShowType,
|
|
|
|
|
|
ContentDescScene: timeLineObj.ContentDescScene,
|
|
|
|
|
|
Private: timeLineObj.Private,
|
|
|
|
|
|
SightFolded: timeLineObj.SightFolded,
|
|
|
|
|
|
ShowFlag: timeLineObj.ShowFlag,
|
|
|
|
|
|
AppInfo: timeLineObj.AppInfo,
|
|
|
|
|
|
SourceUserName: timeLineObj.SourceUserName,
|
|
|
|
|
|
SourceNickName: timeLineObj.SourceNickName,
|
|
|
|
|
|
StatisticsData: timeLineObj.StatisticsData,
|
|
|
|
|
|
StatExtStr: timeLineObj.StatExtStr,
|
|
|
|
|
|
ContentObject: *timeLineObj.ContentObjectVideo,
|
|
|
|
|
|
ActionInfo: timeLineObj.ActionInfo,
|
|
|
|
|
|
Location: timeLineObj.Location,
|
|
|
|
|
|
PublicUserName: timeLineObj.PublicUserName,
|
|
|
|
|
|
StreamVideo: timeLineObj.StreamVideo,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// WithUserListCount
|
|
|
|
|
|
withUserListCount := uint32(0)
|
|
|
|
|
|
request.WithUserListCount = &withUserListCount
|
|
|
|
|
|
// WithUserList
|
|
|
|
|
|
request.WithUserList = make([]*wechat.SKBuiltinString, withUserListCount)
|
|
|
|
|
|
|
|
|
|
|
|
// BlackListCount
|
|
|
|
|
|
tmpCount := uint32(len(blackList))
|
|
|
|
|
|
request.BlackListCount = &tmpCount
|
|
|
|
|
|
request.BlackList = make([]*wechat.SKBuiltinString, tmpCount)
|
|
|
|
|
|
// BlackList
|
|
|
|
|
|
for index := uint32(0); index < tmpCount; index++ {
|
|
|
|
|
|
tmpSKBuiltinString := &wechat.SKBuiltinString{}
|
|
|
|
|
|
tmpSKBuiltinString.Str = &blackList[index]
|
|
|
|
|
|
request.BlackList[index] = tmpSKBuiltinString
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GroupUserCount
|
|
|
|
|
|
groupUserCount := uint32(0)
|
|
|
|
|
|
request.GroupUserCount = &groupUserCount
|
|
|
|
|
|
// GroupUser
|
|
|
|
|
|
request.GroupUser = make([]*wechat.SKBuiltinString, groupUserCount)
|
|
|
|
|
|
|
|
|
|
|
|
// otherFields
|
|
|
|
|
|
bgImageType := uint32(1)
|
|
|
|
|
|
request.PostBgimgType = &bgImageType
|
|
|
|
|
|
request.ObjectSource = &zeroValue32
|
|
|
|
|
|
request.ReferId = &zeroValue64
|
|
|
|
|
|
request.Privacy = &newTimeLineObj.Private
|
|
|
|
|
|
request.SyncFlag = &zeroValue32
|
|
|
|
|
|
|
|
|
|
|
|
// ClientId
|
|
|
|
|
|
tmpTime := int(time.Now().UnixNano() / 1000000000)
|
|
|
|
|
|
tmpTimeStr := strconv.Itoa(tmpTime)
|
|
|
|
|
|
clientID := string("sns_post_")
|
|
|
|
|
|
clientID = clientID + userInfo.WxId + "_" + tmpTimeStr + "_0"
|
|
|
|
|
|
request.ClientId = &clientID
|
|
|
|
|
|
|
|
|
|
|
|
// groupCount
|
|
|
|
|
|
request.GroupCount = &zeroValue32
|
|
|
|
|
|
request.GroupIds = make([]*wechat.SnsGroup, zeroValue32)
|
|
|
|
|
|
|
|
|
|
|
|
// mediaInfoCount MediaInfo
|
|
|
|
|
|
mediaInfoCount := uint32(0)
|
|
|
|
|
|
request.MediaInfoCount = &mediaInfoCount
|
|
|
|
|
|
request.MediaInfo = make([]*wechat.MediaInfo, mediaInfoCount)
|
|
|
|
|
|
|
|
|
|
|
|
// ID和UserName置为0
|
|
|
|
|
|
newTimeLineObj.UserName = userInfo.WxId
|
|
|
|
|
|
newTimeLineObj.CreateTime = uint32(int(time.Now().UnixNano() / 1000000000))
|
|
|
|
|
|
// ObjectDesc
|
|
|
|
|
|
// 定义 XML 模板
|
|
|
|
|
|
const xmlTemplate = `<TimelineObject>
|
|
|
|
|
|
<id>{{.ID}}</id>
|
|
|
|
|
|
<username>{{.UserName}}</username>
|
|
|
|
|
|
<createTime>{{.CreateTime}}</createTime>
|
|
|
|
|
|
<contentDesc>{{.ContentDesc}}</contentDesc>
|
|
|
|
|
|
<contentDescShowType>{{.ContentDescShowType}}</contentDescShowType>
|
|
|
|
|
|
<contentDescScene>{{.ContentDescScene}}</contentDescScene>
|
|
|
|
|
|
<private>{{.Private}}</private>
|
|
|
|
|
|
<sightFolded>{{.SightFolded}}</sightFolded>
|
|
|
|
|
|
<showFlag>{{.ShowFlag}}</showFlag>
|
|
|
|
|
|
<appInfo>
|
|
|
|
|
|
<id>{{.AppInfo.ID}}</id>
|
|
|
|
|
|
<version>{{.AppInfo.Version}}</version>
|
|
|
|
|
|
<appName>{{.AppInfo.AppName}}</appName>
|
|
|
|
|
|
<installUrl>{{.AppInfo.InstallURL}}</installUrl>
|
|
|
|
|
|
<fromUrl>{{.AppInfo.FromURL}}</fromUrl>
|
|
|
|
|
|
<isForceUpdate>{{.AppInfo.IsForceUpdate}}</isForceUpdate>
|
|
|
|
|
|
</appInfo>
|
|
|
|
|
|
<sourceUserName>{{.SourceUserName}}</sourceUserName>
|
|
|
|
|
|
<sourceNickName>{{.SourceNickName}}</sourceNickName>
|
|
|
|
|
|
<statisticsData>{{.StatisticsData}}</statisticsData>
|
|
|
|
|
|
<statExtStr>{{.StatExtStr}}</statExtStr>
|
|
|
|
|
|
<ContentObject>
|
|
|
|
|
|
<finderFeed>
|
|
|
|
|
|
<objectId><![CDATA[{{.ContentObject.FinderFeed.ObjectId}}]]></objectId>
|
|
|
|
|
|
<nickname><![CDATA[{{.ContentObject.FinderFeed.Nickname}}]]></nickname>
|
|
|
|
|
|
<avatar><![CDATA[{{.ContentObject.FinderFeed.Avatar}}]]></avatar>
|
|
|
|
|
|
<mediaList>
|
|
|
|
|
|
{{range .ContentObject.FinderFeed.MediaList.Media}}
|
|
|
|
|
|
<media>
|
|
|
|
|
|
<mediaType>{{.MediaType}}</mediaType>
|
|
|
|
|
|
<url><![CDATA[{{.Url}}]]></url>
|
|
|
|
|
|
<thumbUrl><![CDATA[{{.ThumbUrl}}]]></thumbUrl>
|
|
|
|
|
|
<coverUrl><![CDATA[{{.CoverUrl}}]]></coverUrl>
|
|
|
|
|
|
<fullCoverUrl><![CDATA[{{.FullCoverUrl}}]]></fullCoverUrl>
|
|
|
|
|
|
<height>{{.Height}}</height>
|
|
|
|
|
|
<width>{{.Width}}</width>
|
|
|
|
|
|
<videoPlayDuration>{{.VideoPlayDuration}}</videoPlayDuration>
|
|
|
|
|
|
</media>
|
|
|
|
|
|
{{end}}
|
|
|
|
|
|
</mediaList>
|
|
|
|
|
|
</finderFeed>
|
|
|
|
|
|
</ContentObject>
|
|
|
|
|
|
<streamvideo>
|
|
|
|
|
|
<streamvideourl>{{.StreamVideo.StreamVideoURL}}</streamvideourl>
|
|
|
|
|
|
<streamvideothumburl>{{.StreamVideo.StreamVideoThumbURL}}</streamvideothumburl>
|
|
|
|
|
|
<streamvideoweburl>{{.StreamVideo.StreamVideoWebURL}}</streamvideoweburl>
|
|
|
|
|
|
</streamvideo>
|
|
|
|
|
|
</TimelineObject>`
|
|
|
|
|
|
|
|
|
|
|
|
// 创建模板
|
|
|
|
|
|
tmpl, err := template.New("xmlTemplate").Parse(xmlTemplate)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fmt.Println("SendSnsPostRequestByXMLVideoNum Error parsing template:", err)
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 执行模板并写入到 buffer
|
|
|
|
|
|
var output bytes.Buffer
|
|
|
|
|
|
err = tmpl.Execute(&output, newTimeLineObj)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fmt.Println("SendSnsPostRequestByXMLVideoNum Error executing template:", err)
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 正则表达式匹配 '><' 中间可能存在空白字符的情况
|
|
|
|
|
|
re := regexp.MustCompile(`>\s+<`)
|
|
|
|
|
|
// 替换为没有空白字符的 '><'
|
|
|
|
|
|
formattedXML := re.ReplaceAllString(strings.TrimSpace(output.String()), "><")
|
|
|
|
|
|
fmt.Println("Formatted XML:", formattedXML)
|
|
|
|
|
|
objectDescData := []byte(formattedXML)
|
|
|
|
|
|
length := uint32(len(objectDescData))
|
|
|
|
|
|
var objectDesc wechat.SKBuiltinString_
|
|
|
|
|
|
objectDesc.Len = &length
|
|
|
|
|
|
objectDesc.Buffer = objectDescData
|
|
|
|
|
|
request.ObjectDesc = &objectDesc
|
|
|
|
|
|
|
|
|
|
|
|
// SnsPostOperationFields
|
|
|
|
|
|
var postOperationFields wechat.SnsPostOperationFields
|
|
|
|
|
|
postOperationFields.ContactTagCount = &zeroValue32
|
|
|
|
|
|
postOperationFields.TempUserCount = &zeroValue32
|
|
|
|
|
|
request.SnsPostOperationFields = &postOperationFields
|
|
|
|
|
|
|
|
|
|
|
|
// clientcheckdata
|
|
|
|
|
|
var extSpamInfo wechat.SKBuiltinString_
|
|
|
|
|
|
if userInfo.DeviceInfo != nil {
|
|
|
|
|
|
extSpamInfo.Buffer = GetExtPBSpamInfoDataIpad(userInfo)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
extSpamInfo.Buffer = GetExtPBSpamInfoDataA16(userInfo)
|
|
|
|
|
|
}
|
|
|
|
|
|
extSpamInfoLen := uint32(len(extSpamInfo.Buffer))
|
|
|
|
|
|
extSpamInfo.Len = &extSpamInfoLen
|
|
|
|
|
|
request.ExtSpamInfo = &extSpamInfo
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeMMSnsPost, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/mmsnspost", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSnsObjectOpRequest 发送朋友圈操作
|
|
|
|
|
|
func SendSnsObjectOpRequest(userInfo *baseinfo.UserInfo, opItems []*baseinfo.SnsObjectOpItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.SnsObjectOpRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// OpCount
|
|
|
|
|
|
opCount := uint32(len(opItems))
|
|
|
|
|
|
request.OpCount = &opCount
|
|
|
|
|
|
|
|
|
|
|
|
// OpList
|
|
|
|
|
|
request.OpList = make([]*wechat.SnsObjectOp, opCount)
|
|
|
|
|
|
index := uint32(0)
|
|
|
|
|
|
for ; index < opCount; index++ {
|
|
|
|
|
|
snsObject := &wechat.SnsObjectOp{}
|
|
|
|
|
|
id, _ := strconv.ParseUint(opItems[index].SnsObjID, 0, 64)
|
|
|
|
|
|
snsObject.Id = &id
|
|
|
|
|
|
snsObject.OpType = &opItems[index].OpType
|
|
|
|
|
|
if opItems[index].DataLen > 0 {
|
|
|
|
|
|
skBuffer := &wechat.SKBuiltinString_{}
|
|
|
|
|
|
skBuffer.Len = &opItems[index].DataLen
|
|
|
|
|
|
skBuffer.Buffer = opItems[index].Data
|
|
|
|
|
|
}
|
|
|
|
|
|
if opItems[index].Ext != 0 {
|
|
|
|
|
|
extInfo := &wechat.SnsObjectOpExt{
|
|
|
|
|
|
Id: &opItems[index].Ext,
|
|
|
|
|
|
}
|
|
|
|
|
|
CommnetId, _ := proto.Marshal(extInfo)
|
|
|
|
|
|
snsObject.Ext = &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(CommnetId))),
|
|
|
|
|
|
Buffer: CommnetId,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
request.OpList[index] = snsObject
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeMMSnsObjectOp, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/mmsnsobjectop", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func Uint32ToBytes(n uint32) []byte {
|
|
|
|
|
|
return []byte{
|
|
|
|
|
|
byte(n),
|
|
|
|
|
|
byte(n >> 8),
|
|
|
|
|
|
byte(n >> 16),
|
|
|
|
|
|
byte(n >> 24),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSnsUserPageRequest 发送 获取朋友圈信息 请求
|
|
|
|
|
|
func SendSnsUserPageRequest(userInfo *baseinfo.UserInfo, userName string, firstPageMd5 string, maxID uint64) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.SnsUserPageRequest
|
|
|
|
|
|
var zeroValue64 = uint64(0)
|
|
|
|
|
|
var zeroValue32 = uint32(0)
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// 其它参数
|
|
|
|
|
|
request.Username = &userName
|
|
|
|
|
|
request.FirstPageMd5 = &firstPageMd5
|
|
|
|
|
|
request.MaxId = &maxID
|
|
|
|
|
|
request.MinFilterId = &zeroValue64
|
|
|
|
|
|
request.LastRequestTime = &zeroValue32
|
|
|
|
|
|
request.FilterType = &zeroValue32
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, srcData, baseinfo.MMRequestTypeMMSnsUserPage, 5)
|
|
|
|
|
|
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/mmsnsuserpage", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, srcData)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSnsCommentRequest 发送评论/点赞请求
|
|
|
|
|
|
func SendSnsCommentRequest(userInfo *baseinfo.UserInfo, commentItem *baseinfo.SnsCommentItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
request := wechat.SnsCommentRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Action: &wechat.SnsActionGroup{
|
|
|
|
|
|
Id: &commentItem.ItemID,
|
|
|
|
|
|
ParentId: proto.Uint64(0),
|
|
|
|
|
|
CurrentAction: &wechat.SnsAction{
|
|
|
|
|
|
FromUsername: &userInfo.WxId,
|
|
|
|
|
|
ToUsername: &commentItem.ToUserName,
|
|
|
|
|
|
Type: &commentItem.OpType,
|
|
|
|
|
|
Source: proto.Uint32(6),
|
|
|
|
|
|
ReplyCommentId: &commentItem.ReplyCommentID,
|
|
|
|
|
|
Content: &commentItem.Content,
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeMMSnsComment, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/mmsnscomment", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取收藏lit
|
|
|
|
|
|
func SendFavSyncListRequest(userInfo *baseinfo.UserInfo, keyBuf string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.FavSyncRequest
|
|
|
|
|
|
selector := uint32(1)
|
|
|
|
|
|
request.Selector = &selector
|
|
|
|
|
|
var skBufferT wechat.SKBuiltinString_
|
|
|
|
|
|
skBufferT.Len = proto.Uint32(0)
|
|
|
|
|
|
/*favSyncKeyLen := uint32(len(userInfo.FavSyncKey))
|
|
|
|
|
|
skBufferT.Len = &favSyncKeyLen
|
|
|
|
|
|
skBufferT.Buffer = userInfo.FavSyncKey*/
|
|
|
|
|
|
if keyBuf != "" {
|
|
|
|
|
|
key, _ := base64.StdEncoding.DecodeString(keyBuf)
|
|
|
|
|
|
skBufferT.Buffer = key
|
|
|
|
|
|
skBufferT.Len = proto.Uint32(uint32(len(key)))
|
|
|
|
|
|
}
|
|
|
|
|
|
request.KeyBuf = &skBufferT
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeFavSync, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/favsync", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendFavSyncRequest 同步收藏
|
|
|
|
|
|
func SendFavSyncRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.FavSyncRequest
|
|
|
|
|
|
|
|
|
|
|
|
// selector
|
|
|
|
|
|
selector := uint32(1)
|
|
|
|
|
|
request.Selector = &selector
|
|
|
|
|
|
|
|
|
|
|
|
var skBufferT wechat.SKBuiltinString_
|
|
|
|
|
|
favSyncKeyLen := uint32(len(userInfo.FavSyncKey))
|
|
|
|
|
|
skBufferT.Len = &favSyncKeyLen
|
|
|
|
|
|
skBufferT.Buffer = userInfo.FavSyncKey
|
|
|
|
|
|
request.KeyBuf = &skBufferT
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeFavSync, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/favsync", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendGetFavInfoRequest 获取 收藏信息
|
|
|
|
|
|
func SendGetFavInfoRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.GetFavInfoRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetFavInfo, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getfavinfo", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendBatchGetFavItemRequest 获取单条收藏
|
|
|
|
|
|
func SendBatchGetFavItemRequest(userInfo *baseinfo.UserInfo, favID uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.BatchGetFavItemRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// Count
|
|
|
|
|
|
favIDCount := uint32(1)
|
|
|
|
|
|
request.Count = &favIDCount
|
|
|
|
|
|
|
|
|
|
|
|
// FavIdList
|
|
|
|
|
|
request.FavIdList = make([]byte, 0)
|
|
|
|
|
|
tmpBytes := baseutils.EncodeVByte32(favID)
|
|
|
|
|
|
request.FavIdList = append(request.FavIdList, tmpBytes[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeBatchGetFavItem, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/batchgetfavitem", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendBatchDelFavItemRequest 删除收藏项
|
|
|
|
|
|
func SendBatchDelFavItemRequest(userInfo *baseinfo.UserInfo, favID uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.BatchDelFavItemRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// Count
|
|
|
|
|
|
tmpCount := uint32(1)
|
|
|
|
|
|
request.Count = &tmpCount
|
|
|
|
|
|
|
|
|
|
|
|
// FavIdList
|
|
|
|
|
|
request.FavIdList = make([]byte, 0)
|
|
|
|
|
|
tmpBytes := baseutils.EncodeVByte32(favID)
|
|
|
|
|
|
request.FavIdList = append(request.FavIdList, tmpBytes[0:]...)
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeBatchDelFavItem, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/batchdelfavitem", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendGetCDNDnsRequest 获取该帐号的CdnDns信息
|
|
|
|
|
|
func SendGetCDNDnsRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.GetCDNDnsRequest
|
|
|
|
|
|
emptyString := string("")
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// ClientIp
|
|
|
|
|
|
request.ClientIp = &emptyString
|
|
|
|
|
|
|
|
|
|
|
|
// Scene
|
|
|
|
|
|
scene := uint32(1)
|
|
|
|
|
|
request.Scene = &scene
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetCdnDNS, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getcdndns", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSnsObjectDetailRequest SendSnsObjectDetailRequest
|
|
|
|
|
|
func SendSnsObjectDetailRequest(userInfo *baseinfo.UserInfo, snsID uint64) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.SnsObjectDetailRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
request.GroupDetail = proto.Uint32(0)
|
|
|
|
|
|
// ID
|
|
|
|
|
|
request.Id = &snsID
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeMMSnsObjectDetail, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/mmsnsobjectdetail", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSnsSyncRequest 同步朋友圈
|
|
|
|
|
|
func SendSnsSyncRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.SnsSyncRequest
|
|
|
|
|
|
// baseRequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// Selector
|
|
|
|
|
|
tmpSelector := uint32(509)
|
|
|
|
|
|
request.Selector = &tmpSelector
|
|
|
|
|
|
|
|
|
|
|
|
// KeyBuf 第一次使用同步消息Key
|
|
|
|
|
|
tmpKeyBuffer := userInfo.SnsSyncKey
|
|
|
|
|
|
if len(tmpKeyBuffer) <= 0 {
|
|
|
|
|
|
tmpKeyBuffer = userInfo.SyncKey
|
|
|
|
|
|
}
|
|
|
|
|
|
tmpLen := uint32(len(tmpKeyBuffer))
|
|
|
|
|
|
var tmpKeyBuf wechat.SKBuiltinString_
|
|
|
|
|
|
tmpKeyBuf.Buffer = tmpKeyBuffer
|
|
|
|
|
|
tmpKeyBuf.Len = &tmpLen
|
|
|
|
|
|
request.KeyBuf = &tmpKeyBuf
|
|
|
|
|
|
|
|
|
|
|
|
// 打包数据 发送
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeMMSnsSync, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/mmsnssync", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendGetContactLabelListRequest 获取设置好的联系人标签列表
|
|
|
|
|
|
func SendGetContactLabelListRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.GetContactLabelListRequest
|
|
|
|
|
|
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetContactLabelList, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getcontactlabellist", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendAddContactLabelRequest 发送添加标签请求
|
|
|
|
|
|
func SendAddContactLabelRequest(userInfo *baseinfo.UserInfo, newLabelList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.AddContactLabelRequest
|
|
|
|
|
|
labelID := uint32(0)
|
|
|
|
|
|
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// LabelCount
|
|
|
|
|
|
labelCount := uint32(len(newLabelList))
|
|
|
|
|
|
request.LabelCount = &labelCount
|
|
|
|
|
|
|
|
|
|
|
|
// LabelPairList
|
|
|
|
|
|
request.LabelPairList = make([]*wechat.LabelPair, labelCount)
|
|
|
|
|
|
for index := uint32(0); index < labelCount; index++ {
|
|
|
|
|
|
labelPair := &wechat.LabelPair{}
|
|
|
|
|
|
labelPair.LabelName = &newLabelList[index]
|
|
|
|
|
|
labelPair.LabelId = &labelID
|
|
|
|
|
|
request.LabelPairList[index] = labelPair
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeAddContactLabel, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/addcontactlabel", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendDelContactLabelRequest 删除标签
|
|
|
|
|
|
func SendDelContactLabelRequest(userInfo *baseinfo.UserInfo, labelId string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.DelContactLabelRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
LabelIdlist: proto.String(labelId),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeDelContactLabel, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/delcontactlabel", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendModifyLabelRequest 修改标签请求
|
|
|
|
|
|
func SendModifyLabelRequest(userInfo *baseinfo.UserInfo, userLabelList []baseinfo.UserLabelInfoItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
_userLabelList := make([]*wechat.UserLabelInfo, 0)
|
|
|
|
|
|
for _, item := range userLabelList {
|
|
|
|
|
|
_userLabelList = append(_userLabelList, &wechat.UserLabelInfo{
|
|
|
|
|
|
UserName: proto.String(item.UserName),
|
|
|
|
|
|
LabelIdlist: proto.String(item.LabelIDList),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
req := wechat.ModifyContactLabelListRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
UserCount: proto.Uint32(uint32(len(_userLabelList))),
|
|
|
|
|
|
UserLabelInfoList: _userLabelList,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeModifyContactLabelList, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/modifycontactlabellist", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendBindQueryNewRequest SendBindQueryNewRequest
|
|
|
|
|
|
func SendBindQueryNewRequest(userInfo *baseinfo.UserInfo, reqItem *baseinfo.TenPayReqItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.TenPayRequest
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// CgiCmd
|
|
|
|
|
|
request.CgiCmd = &reqItem.CgiCMD
|
|
|
|
|
|
|
|
|
|
|
|
// OutPutType
|
|
|
|
|
|
outputType := baseinfo.MMTenPayReqOutputTypeJSON
|
|
|
|
|
|
request.OutPutType = &outputType
|
|
|
|
|
|
|
|
|
|
|
|
// ReqText
|
|
|
|
|
|
var reqTextSKBuf wechat.SKBuiltinString_
|
|
|
|
|
|
tmpLen := uint32(len(reqItem.ReqText))
|
|
|
|
|
|
reqTextSKBuf.Len = &tmpLen
|
|
|
|
|
|
reqTextSKBuf.Buffer = []byte(reqItem.ReqText)
|
|
|
|
|
|
request.ReqText = &reqTextSKBuf
|
|
|
|
|
|
|
|
|
|
|
|
// ReqTextWx
|
|
|
|
|
|
var wxReqTextSKBuf wechat.SKBuiltinString_
|
|
|
|
|
|
tmpText := "encrypt_key=" + userInfo.HBAesKeyEncrypted
|
|
|
|
|
|
tmpText = tmpText + "&encrypt_userinfo=" + GetEncryptUserInfo(userInfo)
|
|
|
|
|
|
tmpWXLen := uint32(len(tmpText))
|
|
|
|
|
|
wxReqTextSKBuf.Len = &tmpWXLen
|
|
|
|
|
|
wxReqTextSKBuf.Buffer = []byte(tmpText)
|
|
|
|
|
|
request.ReqTextWx = &wxReqTextSKBuf
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeBindQueryNew, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmpay-bin/tenpay/bindquerynew", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确定收款
|
|
|
|
|
|
func SendTenPayRequest(userInfo *baseinfo.UserInfo, reqItem *baseinfo.TenPayReqItem) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var request wechat.TenPayRequest
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// CgiCmd
|
|
|
|
|
|
request.CgiCmd = &reqItem.CgiCMD
|
|
|
|
|
|
|
|
|
|
|
|
// OutPutType
|
|
|
|
|
|
outputType := baseinfo.MMTenPayReqOutputTypeJSON
|
|
|
|
|
|
request.OutPutType = &outputType
|
|
|
|
|
|
|
|
|
|
|
|
// ReqText
|
|
|
|
|
|
var reqTextSKBuf wechat.SKBuiltinString_
|
|
|
|
|
|
tmpLen := uint32(len(reqItem.ReqText))
|
|
|
|
|
|
reqTextSKBuf.Len = &tmpLen
|
|
|
|
|
|
reqTextSKBuf.Buffer = []byte(reqItem.ReqText)
|
|
|
|
|
|
request.ReqText = &reqTextSKBuf
|
|
|
|
|
|
|
|
|
|
|
|
// ReqTextWx
|
|
|
|
|
|
var wxReqTextSKBuf wechat.SKBuiltinString_
|
|
|
|
|
|
wxReqTextSKBuf.Buffer = []byte(reqItem.ReqText)
|
|
|
|
|
|
wxReqTextSKBuf.Len = &tmpLen
|
|
|
|
|
|
|
|
|
|
|
|
request.ReqTextWx = &wxReqTextSKBuf
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 385, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/tenpay", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSnsTimeLineRequest 发送获取朋友圈请求
|
|
|
|
|
|
func SendSnsTimeLineRequest(userInfo *baseinfo.UserInfo, firstPageMD5 string, maxID uint64) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
/*var request wechat.SnsTimeLineRequest
|
|
|
|
|
|
// baserequest
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
request.BaseRequest = baseReq
|
|
|
|
|
|
|
|
|
|
|
|
// ClientLatestId
|
|
|
|
|
|
tmpLatestID := uint64(0)
|
|
|
|
|
|
request.ClientLatestId = &tmpLatestID
|
|
|
|
|
|
// FirstPageMd5
|
|
|
|
|
|
request.FirstPageMd5 = &firstPageMD5
|
|
|
|
|
|
// LastRequestTime
|
|
|
|
|
|
lastRequestTime := uint32(0)
|
|
|
|
|
|
request.LastRequestTime = &lastRequestTime
|
|
|
|
|
|
// MAXID
|
|
|
|
|
|
request.MaxId = &maxID
|
|
|
|
|
|
// MinFilterId
|
|
|
|
|
|
minFilterID := uint64(0)
|
|
|
|
|
|
request.MinFilterId = &minFilterID
|
|
|
|
|
|
// NetworkType
|
|
|
|
|
|
netWorkType := uint32(1)
|
|
|
|
|
|
request.NetworkType = &netWorkType*/
|
|
|
|
|
|
|
|
|
|
|
|
req := &wechat.SnsTimeLineRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
ClientLatestId: proto.Uint64(0),
|
|
|
|
|
|
FirstPageMd5: proto.String(firstPageMD5),
|
|
|
|
|
|
LastRequestTime: proto.Uint32(0),
|
|
|
|
|
|
MaxId: proto.Uint64(maxID),
|
|
|
|
|
|
MinFilterId: proto.Uint64(0),
|
|
|
|
|
|
NetworkType: proto.Uint32(1),
|
|
|
|
|
|
}
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
var tmpScene = uint32(0)
|
|
|
|
|
|
baseReq.Scene = &tmpScene
|
|
|
|
|
|
req.BaseRequest = baseReq
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeMMSnsTimeLine, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/mmsnstimeline", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// StatusNotify 发送状态通知
|
|
|
|
|
|
func StatusNotify(userInfo *baseinfo.UserInfo, toWxid string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
// 构造请求
|
|
|
|
|
|
request := wechat.StatusNotifyRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Code: proto.Uint32(2),
|
|
|
|
|
|
FromUserName: proto.String(userInfo.GetUserName()),
|
|
|
|
|
|
ToUserName: proto.String(toWxid),
|
|
|
|
|
|
ClientMsgId: proto.String(fmt.Sprintf("%v_%v", toWxid, time.Now().Unix())),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
srcData, _ := proto.Marshal(&request)
|
|
|
|
|
|
sendData := Pack(userInfo, srcData, baseinfo.MMRequestTypeStatusNotify, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/statusnotify", sendData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendAppMsgRequest 发送App消息
|
|
|
|
|
|
func SendAppMsgRequest(userInfo *baseinfo.UserInfo, contentType uint32, toUserName, xml string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
curTime := time.Now().Unix()
|
|
|
|
|
|
req := wechat.SendAppMsgRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Msg: &wechat.AppMsg{
|
|
|
|
|
|
FromUserName: proto.String(userInfo.GetUserName()),
|
|
|
|
|
|
AppId: proto.String(""),
|
|
|
|
|
|
SdkVersion: proto.Uint32(0),
|
|
|
|
|
|
ToUserName: proto.String(toUserName),
|
|
|
|
|
|
Type: proto.Uint32(contentType),
|
|
|
|
|
|
Content: proto.String(xml),
|
|
|
|
|
|
CreateTime: proto.Uint32(uint32(curTime)),
|
|
|
|
|
|
ClientMsgId: proto.String(fmt.Sprintf("%s_%v", toUserName, curTime)),
|
|
|
|
|
|
Source: proto.Int32(0),
|
|
|
|
|
|
RemindId: proto.Int32(0),
|
|
|
|
|
|
MsgSource: proto.String(""),
|
|
|
|
|
|
Thumb: &wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(0),
|
|
|
|
|
|
Buffer: []byte{},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
FromSence: proto.String(""),
|
|
|
|
|
|
DirectShare: proto.Int32(0),
|
|
|
|
|
|
SendMsgTicket: proto.String(""),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
src, _ := proto.Marshal(&req)
|
|
|
|
|
|
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, src, baseinfo.MMRequestTypeSendAppMsg, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/sendappmsg", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendEmojiRequest 发生表情
|
|
|
|
|
|
func SendEmojiRequest(userInfo *baseinfo.UserInfo, toUserName, Md5 string, length int32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
baseRequest := GetBaseRequest(userInfo)
|
|
|
|
|
|
//baseRequest.Scene = proto.Uint32(0)
|
|
|
|
|
|
req := wechat.UploadEmojiRequest{
|
|
|
|
|
|
BaseRequest: baseRequest,
|
|
|
|
|
|
EmojiItemCount: proto.Int32(1),
|
|
|
|
|
|
EmojiItem: []*wechat.EmojiUploadInfoReq{
|
|
|
|
|
|
{
|
|
|
|
|
|
MD5: proto.String(Md5),
|
|
|
|
|
|
StartPos: proto.Int32(length),
|
|
|
|
|
|
TotalLen: proto.Int32(length),
|
|
|
|
|
|
EmojiBuffer: &wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(0),
|
|
|
|
|
|
Buffer: []byte{},
|
|
|
|
|
|
},
|
|
|
|
|
|
Type: proto.Int32(2),
|
|
|
|
|
|
ToUserName: proto.String(toUserName),
|
|
|
|
|
|
ClientMsgID: proto.String(fmt.Sprintf("%d", time.Now().UnixNano()/1000/1000)),
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
src, _ := proto.Marshal(&req)
|
|
|
|
|
|
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, src, baseinfo.MMRequestTypeSendEmoji, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/sendemoji", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 发送表情 new 包含动图
|
|
|
|
|
|
func ForwardEmojiRequest(userInfo *baseinfo.UserInfo, toUserName, Md5 string, length int32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
baseRequest := GetBaseRequest(userInfo)
|
|
|
|
|
|
//baseRequest.Scene = proto.Uint32(0)
|
|
|
|
|
|
req := wechat.UploadEmojiRequest{
|
|
|
|
|
|
BaseRequest: baseRequest,
|
|
|
|
|
|
EmojiItemCount: proto.Int32(1),
|
|
|
|
|
|
EmojiItem: []*wechat.EmojiUploadInfoReq{
|
|
|
|
|
|
{
|
|
|
|
|
|
MD5: proto.String(Md5),
|
|
|
|
|
|
StartPos: proto.Int32(0),
|
|
|
|
|
|
TotalLen: proto.Int32(length),
|
|
|
|
|
|
EmojiBuffer: &wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(0),
|
|
|
|
|
|
Buffer: []byte{},
|
|
|
|
|
|
},
|
|
|
|
|
|
Type: proto.Int32(1),
|
|
|
|
|
|
ToUserName: proto.String(toUserName),
|
|
|
|
|
|
ClientMsgID: proto.String(strconv.FormatInt(time.Now().Unix(), 10)),
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
src, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, src, baseinfo.MMRequestTypeSendEmoji, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/sendemoji", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 下载语音
|
|
|
|
|
|
func SendGetMsgVoiceRequest(userInfo *baseinfo.UserInfo, toUserName, NewMsgIds, Bufid string, Length int) (*vo.DownloadVoiceData, error) {
|
|
|
|
|
|
I := 0
|
|
|
|
|
|
Startpos := 0
|
|
|
|
|
|
datalen := 50000
|
|
|
|
|
|
Databuff := make([]byte, Length+1000)
|
|
|
|
|
|
var VoiceLength uint32
|
|
|
|
|
|
totalBytesDownloaded := 0
|
|
|
|
|
|
maxIterations := (Length + datalen - 1) / datalen
|
|
|
|
|
|
NewMsgId, _ := strconv.ParseUint(NewMsgIds, 10, 64)
|
|
|
|
|
|
MasterBufId, _ := strconv.ParseUint(Bufid, 10, 64)
|
|
|
|
|
|
resp := new(wechat.DownloadVoiceResponse)
|
|
|
|
|
|
for {
|
|
|
|
|
|
if I >= maxIterations {
|
|
|
|
|
|
return nil, fmt.Errorf("超过最大可下载tier(%d)", maxIterations)
|
|
|
|
|
|
}
|
|
|
|
|
|
Startpos = I * datalen
|
|
|
|
|
|
count := 0
|
|
|
|
|
|
remainingBytes := Length - Startpos
|
|
|
|
|
|
if remainingBytes <= 0 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
if remainingBytes > datalen {
|
|
|
|
|
|
count = datalen
|
|
|
|
|
|
} else {
|
|
|
|
|
|
count = remainingBytes
|
|
|
|
|
|
}
|
|
|
|
|
|
req := wechat.DownloadVoiceRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
MsgId: proto.Uint32(0),
|
|
|
|
|
|
Offset: proto.Uint32(uint32(Startpos)),
|
|
|
|
|
|
Length: proto.Uint32(uint32(count)),
|
|
|
|
|
|
NewMsgId: proto.Uint64(NewMsgId),
|
|
|
|
|
|
ChatRoomName: proto.String(toUserName),
|
|
|
|
|
|
MasterBufId: proto.Uint64(MasterBufId),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeDownloadVoice, 5)
|
|
|
|
|
|
|
|
|
|
|
|
res, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/downloadvoice", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("network error downloading voice chunk %d at offset %d: %w", I+1, Startpos, err)
|
|
|
|
|
|
}
|
|
|
|
|
|
header, err := DecodePackHeader(res, nil)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("failed to decode response header for chunk %d at offset %d: %w", I+1, Startpos, err)
|
|
|
|
|
|
}
|
|
|
|
|
|
err = ParseResponseData(userInfo, header, resp)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("failed to parse response data for chunk %d at offset %d: %w", I+1, Startpos, err)
|
|
|
|
|
|
}
|
|
|
|
|
|
if resp.GetBaseResponse().GetRet() != 0 {
|
|
|
|
|
|
return nil, fmt.Errorf("server returned error %d for chunk %d at offset %d", resp.GetBaseResponse().GetRet(), I+1, Startpos)
|
|
|
|
|
|
}
|
|
|
|
|
|
// Fix: Write chunk data to correct buffer position instead of overwriting
|
|
|
|
|
|
// Validate chunk response before processing
|
|
|
|
|
|
if resp.GetData() == nil {
|
|
|
|
|
|
return nil, fmt.Errorf("chunk %d at offset %d: response data is nil", I+1, Startpos)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
chunkData := resp.GetData().GetBuffer()
|
|
|
|
|
|
chunkSize := len(chunkData)
|
|
|
|
|
|
|
|
|
|
|
|
// Validate that chunk data length matches expected size
|
|
|
|
|
|
expectedChunkSize := count
|
|
|
|
|
|
if chunkSize != expectedChunkSize {
|
|
|
|
|
|
return nil, fmt.Errorf("chunk %d at offset %d: expected %d bytes, got %d bytes", I+1, Startpos, expectedChunkSize, chunkSize)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Ensure proper handling of the last chunk which may be smaller
|
|
|
|
|
|
if I > 0 && chunkSize > datalen {
|
|
|
|
|
|
return nil, fmt.Errorf("chunk %d at offset %d: chunk size %d exceeds maximum chunk size %d", I+1, Startpos, chunkSize, datalen)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Calculate the correct offset for this chunk
|
|
|
|
|
|
bufferOffset := Startpos
|
|
|
|
|
|
|
|
|
|
|
|
// Buffer bounds checking - prevent buffer overflow
|
|
|
|
|
|
if bufferOffset+chunkSize > len(Databuff) {
|
|
|
|
|
|
return nil, fmt.Errorf("buffer overflow: chunk at offset %d with size %d exceeds buffer capacity %d",
|
|
|
|
|
|
bufferOffset, chunkSize, len(Databuff))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Validate that chunk data fits within allocated buffer space
|
|
|
|
|
|
if bufferOffset < 0 || bufferOffset >= len(Databuff) {
|
|
|
|
|
|
return nil, fmt.Errorf("invalid buffer offset: %d, buffer size: %d", bufferOffset, len(Databuff))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Copy chunk data to the correct position in the buffer
|
|
|
|
|
|
copy(Databuff[bufferOffset:bufferOffset+chunkSize], chunkData)
|
|
|
|
|
|
|
|
|
|
|
|
// Track bytes downloaded in this chunk
|
|
|
|
|
|
totalBytesDownloaded += chunkSize
|
|
|
|
|
|
|
|
|
|
|
|
// Progress tracking for validation and debugging
|
|
|
|
|
|
progressPercent := float64(totalBytesDownloaded) / float64(Length) * 100
|
|
|
|
|
|
_ = progressPercent // Available for debugging if needed
|
|
|
|
|
|
|
|
|
|
|
|
VoiceLength = resp.GetVoiceLength()
|
|
|
|
|
|
I++
|
|
|
|
|
|
|
|
|
|
|
|
// Ensure loop exits when all expected data is downloaded
|
|
|
|
|
|
if totalBytesDownloaded >= Length {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Validate that downloaded length matches expected Length parameter
|
|
|
|
|
|
if totalBytesDownloaded != Length {
|
|
|
|
|
|
return nil, fmt.Errorf("download incomplete: expected %d bytes, but downloaded %d bytes", Length, totalBytesDownloaded)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return &vo.DownloadVoiceData{
|
|
|
|
|
|
Base64: Databuff,
|
|
|
|
|
|
VoiceLength: VoiceLength,
|
|
|
|
|
|
}, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 群发图片
|
|
|
|
|
|
func SendGroupMassMsgImage(userInfo *baseinfo.UserInfo, toUSerName []string, ImageBase64 []byte) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
baseRequest := GetBaseRequest(userInfo)
|
|
|
|
|
|
baseRequest.Scene = proto.Uint32(0)
|
|
|
|
|
|
toList := strings.Join(toUSerName, ";")
|
|
|
|
|
|
tolistmd5 := baseutils.MD5ToLower(toList)
|
|
|
|
|
|
ClientImgId := fmt.Sprintf("%v_%v", time.Now().Unix(), tolistmd5)
|
|
|
|
|
|
var protobufdata []byte
|
|
|
|
|
|
imgStream := bytes.NewBuffer(ImageBase64)
|
|
|
|
|
|
Startpos := 0
|
|
|
|
|
|
datalen := 50000
|
|
|
|
|
|
datatotalength := imgStream.Len()
|
|
|
|
|
|
I := 0
|
|
|
|
|
|
for {
|
|
|
|
|
|
Startpos = I * datalen
|
|
|
|
|
|
count := 0
|
|
|
|
|
|
if datatotalength-Startpos > datalen {
|
|
|
|
|
|
count = datalen
|
|
|
|
|
|
} else {
|
|
|
|
|
|
count = datatotalength - Startpos
|
|
|
|
|
|
}
|
|
|
|
|
|
if count < 0 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
Databuff := make([]byte, count)
|
|
|
|
|
|
_, _ = imgStream.Read(Databuff)
|
|
|
|
|
|
req := wechat.MassSendRequest{
|
|
|
|
|
|
BaseRequest: baseRequest,
|
|
|
|
|
|
ToList: proto.String(toList),
|
|
|
|
|
|
ToListMd5: proto.String(tolistmd5),
|
|
|
|
|
|
ClientId: proto.String(ClientImgId),
|
|
|
|
|
|
MsgType: proto.Uint64(3),
|
|
|
|
|
|
MediaTime: proto.Uint64(0),
|
|
|
|
|
|
DataBuffer: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(Databuff))),
|
|
|
|
|
|
Buffer: Databuff,
|
|
|
|
|
|
},
|
|
|
|
|
|
DataStartPos: proto.Uint64(uint64(Startpos)),
|
|
|
|
|
|
DataTotalLen: proto.Uint64(uint64(len(Databuff))),
|
|
|
|
|
|
ThumbTotalLen: proto.Uint64(0),
|
|
|
|
|
|
ThumbStartPos: proto.Uint64(0),
|
|
|
|
|
|
ThumbData: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(0),
|
|
|
|
|
|
Buffer: []byte{},
|
|
|
|
|
|
},
|
|
|
|
|
|
CameraType: proto.Uint64(2),
|
|
|
|
|
|
VideoSource: proto.Uint64(0),
|
|
|
|
|
|
ToListCount: proto.Uint64(uint64(len(toUSerName))),
|
|
|
|
|
|
IsSendAgain: proto.Uint64(0),
|
|
|
|
|
|
CompressType: proto.Uint64(1),
|
|
|
|
|
|
VoiceFormat: proto.Uint64(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
src, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, src, 193, 5)
|
|
|
|
|
|
|
|
|
|
|
|
rsp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/masssend", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
protobufdata = rsp
|
|
|
|
|
|
I++
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(protobufdata, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func SendGroupMassMsgText(userInfo *baseinfo.UserInfo, toUSerName []string, content string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
baseRequest := GetBaseRequest(userInfo)
|
|
|
|
|
|
// baseRequest.Scene = proto.Uint32(0)
|
|
|
|
|
|
toList := strings.Join(toUSerName, ";")
|
|
|
|
|
|
tolistmd5 := baseutils.MD5ToLower(toList)
|
|
|
|
|
|
Databuff := []byte(content)
|
|
|
|
|
|
ClientImgId := fmt.Sprintf("%v_%v", time.Now().Unix(), tolistmd5)
|
|
|
|
|
|
fmt.Println("toList:", toList, "tolistmd5:", tolistmd5)
|
|
|
|
|
|
req := wechat.MassSendRequest{
|
|
|
|
|
|
BaseRequest: baseRequest,
|
|
|
|
|
|
ToList: proto.String(toList),
|
|
|
|
|
|
ToListMd5: proto.String(tolistmd5),
|
|
|
|
|
|
ClientId: proto.String(ClientImgId),
|
|
|
|
|
|
MsgType: proto.Uint64(1),
|
|
|
|
|
|
MediaTime: proto.Uint64(0),
|
|
|
|
|
|
DataBuffer: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(Databuff))),
|
|
|
|
|
|
Buffer: Databuff,
|
|
|
|
|
|
},
|
|
|
|
|
|
DataStartPos: proto.Uint64(0),
|
|
|
|
|
|
DataTotalLen: proto.Uint64(uint64(len(Databuff))),
|
|
|
|
|
|
ThumbTotalLen: proto.Uint64(0),
|
|
|
|
|
|
ThumbStartPos: proto.Uint64(0),
|
|
|
|
|
|
ThumbData: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(0),
|
|
|
|
|
|
Buffer: []byte{},
|
|
|
|
|
|
},
|
|
|
|
|
|
CameraType: proto.Uint64(2),
|
|
|
|
|
|
VideoSource: proto.Uint64(0),
|
|
|
|
|
|
ToListCount: proto.Uint64(uint64(len(toUSerName))),
|
|
|
|
|
|
IsSendAgain: proto.Uint64(1),
|
|
|
|
|
|
CompressType: proto.Uint64(0),
|
|
|
|
|
|
VoiceFormat: proto.Uint64(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
src, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, src, 193, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/masssend", sendEncodeData)
|
|
|
|
|
|
fmt.Println("resp:", string(resp))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetChatroomMemberDetailRequest 获取群成员详细
|
|
|
|
|
|
func GetChatroomMemberDetailRequest(userInfo *baseinfo.UserInfo, roomId string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.GetChatroomMemberDetailRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
ChatroomWxid: proto.String(roomId),
|
|
|
|
|
|
ClientVersion: proto.Uint32(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetChatRoomMemberDetail, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getchatroommemberdetail", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 群拍一拍
|
|
|
|
|
|
func SendSendPatRequest(userInfo *baseinfo.UserInfo, chatRoomName string, toUserName string, scene int64) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
ClientImgId := fmt.Sprintf("%v_%v_%v", userInfo.WxId, toUserName, time.Now().Unix())
|
|
|
|
|
|
req := wechat.SendPatRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
FromUsername: proto.String(userInfo.WxId),
|
|
|
|
|
|
ChatUsername: proto.String(chatRoomName),
|
|
|
|
|
|
PattedUsername: proto.String(toUserName),
|
|
|
|
|
|
ClientMsgId: proto.String(ClientImgId),
|
|
|
|
|
|
Scene: proto.Int64(scene),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 849, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/sendpat", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SetChatRoomAnnouncementRequest 设置群公告
|
|
|
|
|
|
func SetChatRoomAnnouncementRequest(userInfo *baseinfo.UserInfo, roomId, content string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.SetChatRoomAnnouncementRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
ChatRoomName: proto.String(roomId),
|
|
|
|
|
|
Announcement: proto.String(content),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeSetChatRoomAnnouncement, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/setchatroomannouncement", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 同意入群
|
|
|
|
|
|
func JoinGroupRequest(fullUrl string) (*wechat.JoinChatRoomResponse, error) {
|
|
|
|
|
|
client := &http.Client{
|
|
|
|
|
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
|
|
|
|
return http.ErrUseLastResponse
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
req, err := http.NewRequest("POST", fullUrl, strings.NewReader("s=1"))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, errors.New(fmt.Sprintf("异常:%v", err.Error()))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
|
|
resp, err := client.Do(req)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, errors.New(fmt.Sprintf("异常:%v", err.Error()))
|
|
|
|
|
|
}
|
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode == 302 {
|
|
|
|
|
|
QID := strings.Replace(resp.Header.Get("Location"), "weixin://jump/mainframe/", "", -1)
|
|
|
|
|
|
response := wechat.JoinChatRoomResponse{}
|
|
|
|
|
|
response.QID = QID
|
|
|
|
|
|
response.Msg = "入群成功"
|
|
|
|
|
|
return &response, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
str, _ := ioutil.ReadAll(resp.Body)
|
|
|
|
|
|
return nil, errors.New(fmt.Sprintf("异常:%v", string(str)))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取群详细
|
|
|
|
|
|
func SetGetChatRoomInfoDetailRequest(userInfo *baseinfo.UserInfo, roomId string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.GetChatRoomInfoDetailRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
ChatRoomName: proto.String(roomId),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetChatRoomInfoDetail, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getchatroominfodetail", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//保存群聊操作
|
|
|
|
|
|
/*func SetMoveToContractRequest(userInfo *baseinfo.UserInfo, ChatRoomName string, Val uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
UserNameListSplit := strings.Split(ChatRoomName, ",")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
req := wechat.GetChatRoomInfoDetailRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
ChatRoomName: proto.String(roomId),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetChatRoomInfoDetail, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getchatroominfodetail", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
// GetCreateChatRoomEntity 创建群
|
|
|
|
|
|
func GetCreateChatRoomEntity(userInfo *baseinfo.UserInfo, topIc string, userList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
userList = append([]string{userInfo.GetUserName()}, userList...)
|
|
|
|
|
|
memberList := make([]*wechat.MemberReq, 0)
|
|
|
|
|
|
for _, user := range userList {
|
|
|
|
|
|
memberList = append(memberList, &wechat.MemberReq{
|
|
|
|
|
|
MemberName: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(user),
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
req := wechat.CreateChatRoomRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Topic: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(topIc),
|
|
|
|
|
|
},
|
|
|
|
|
|
MemberCount: proto.Uint32(uint32(len(memberList))),
|
|
|
|
|
|
MemberList: memberList,
|
|
|
|
|
|
Scene: proto.Uint32(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeCreateChatRoom, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/createchatroom", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加群管理
|
|
|
|
|
|
func SendAddChatroomAdmin(userInfo *baseinfo.UserInfo, chatRoomName string, userList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.AddChatRoomAdminRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
ChatRoomName: proto.String(chatRoomName),
|
|
|
|
|
|
UserNameList: userList,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 889, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/addchatroomadmin", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetQrCodeRequest 获取(群聊/个人)二维码
|
|
|
|
|
|
func GetQrCodeRequest(userInfo *baseinfo.UserInfo, id string, style uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.GetQRCodeRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
UserName: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(id),
|
|
|
|
|
|
},
|
|
|
|
|
|
Style: proto.Uint32(style),
|
|
|
|
|
|
Opcode: proto.Uint32(1), // 安卓 0(群二维码) 1(个人二维码)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetQrCode, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getqrcode", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 删除群管理
|
|
|
|
|
|
func SendDelChatroomAdminRequest(userInfo *baseinfo.UserInfo, chatRoomName string, userList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.DelChatRoomAdminRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
ChatRoomName: proto.String(chatRoomName),
|
|
|
|
|
|
UserNameList: userList,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 259, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/delchatroomadmin", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取群列表
|
|
|
|
|
|
func SendWXSyncContactRequest(userInfo *baseinfo.UserInfo, key []byte) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
keyBuf := userInfo.SyncKey
|
|
|
|
|
|
if key != nil {
|
|
|
|
|
|
keyBuf = key
|
|
|
|
|
|
}
|
|
|
|
|
|
osType := ""
|
|
|
|
|
|
if userInfo.DeviceInfoA16 != nil {
|
|
|
|
|
|
osType = baseinfo.AndroidDeviceType
|
|
|
|
|
|
} else {
|
|
|
|
|
|
osType = userInfo.DeviceInfo.OsType
|
|
|
|
|
|
}
|
|
|
|
|
|
req := wechat.NewSyncRequest{
|
|
|
|
|
|
Oplog: &wechat.CmdList{
|
|
|
|
|
|
Count: proto.Uint32(0),
|
|
|
|
|
|
},
|
|
|
|
|
|
DeviceType: proto.String(osType),
|
|
|
|
|
|
Scene: proto.Uint32(3), //有时候03,有时候01
|
|
|
|
|
|
Selector: proto.Uint32(7), // 7
|
|
|
|
|
|
SyncMsgDigest: proto.Uint32(baseinfo.MMSyncMsgDigestTypeShortLink),
|
|
|
|
|
|
KeyBuf: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(keyBuf))),
|
|
|
|
|
|
Buffer: keyBuf,
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 138, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/newsync", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 搜手机或企业对外名片链接提取验证
|
|
|
|
|
|
func SendQWSearchContactRequest(userInfo *baseinfo.UserInfo, tg string, fromScene uint64, userName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.SearchQYContactRequest{}
|
|
|
|
|
|
if utils.IsMobile(tg) {
|
|
|
|
|
|
req.Tg = proto.String(tg)
|
|
|
|
|
|
req.FromScene = proto.Uint64(1)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
req.UserName = proto.String(tg)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 372, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/searchopenimcontact", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetAddChatRoomMemberRequest 拉人
|
|
|
|
|
|
func GetAddChatRoomMemberRequest(userInfo *baseinfo.UserInfo, chatRoomName string, userList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
memberList := make([]*wechat.MemberReq, 0)
|
|
|
|
|
|
for _, user := range userList {
|
|
|
|
|
|
memberList = append(memberList, &wechat.MemberReq{
|
|
|
|
|
|
MemberName: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(user),
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
req := wechat.AddChatRoomMemberRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
MemberCount: proto.Uint32(uint32(len(memberList))),
|
|
|
|
|
|
MemberList: memberList,
|
|
|
|
|
|
ChatRoomName: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(chatRoomName),
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeAddChatRoomMember, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/addchatroommember", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// DelDelChatRoomMember 删除群成员
|
|
|
|
|
|
func DelDelChatRoomMemberRequest(userInfo *baseinfo.UserInfo, chatRoomName string, delUserList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
memberList := make([]*wechat.DelMemberReq, 0)
|
|
|
|
|
|
for _, user := range delUserList {
|
|
|
|
|
|
memberList = append(memberList, &wechat.DelMemberReq{
|
|
|
|
|
|
MemberName: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(user),
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
req := wechat.DelChatRoomMemberRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
MemberCount: proto.Uint32(uint32(len(memberList))),
|
|
|
|
|
|
MemberList: memberList,
|
|
|
|
|
|
ChatRoomName: proto.String(chatRoomName),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeDelChatRoomMember, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/delchatroommember", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetTransferGroupOwnerRequest 转让群
|
|
|
|
|
|
func GetTransferGroupOwnerRequest(userInfo *baseinfo.UserInfo, chatRoomName, newOwnerUserName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.TransferChatRoomOwnerRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
ChatRoomName: proto.String(chatRoomName),
|
|
|
|
|
|
NewOwnerUserName: proto.String(newOwnerUserName),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeTransferChatRoomOwnerRequest, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/transferchatroomowner", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetInviteChatroomMembersEntity 邀请群成员
|
|
|
|
|
|
func GetInviteChatroomMembersRequest(userInfo *baseinfo.UserInfo, chatRoomName string, userList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
memberList := make([]*wechat.MemberReq, 0)
|
|
|
|
|
|
for _, user := range userList {
|
|
|
|
|
|
memberList = append(memberList, &wechat.MemberReq{
|
|
|
|
|
|
MemberName: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(user),
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
req := wechat.InviteChatRoomMemberRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
MemberCount: proto.Uint32(uint32(len(memberList))),
|
|
|
|
|
|
MemberList: memberList,
|
|
|
|
|
|
ChatRoomName: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(chatRoomName),
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeInviteChatRoomMember, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/invitechatroommember", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 查看附近的人
|
|
|
|
|
|
func SendGetPeopleNearbyResultRequest(userInfo *baseinfo.UserInfo, longitude float32, latitude float32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := &wechat.LbsRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
GPSSource: proto.Int64(0),
|
|
|
|
|
|
Latitude: proto.Float32(latitude),
|
|
|
|
|
|
Longitude: proto.Float32(longitude),
|
|
|
|
|
|
OpCode: proto.Uint64(1),
|
|
|
|
|
|
Precision: proto.Int64(65),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 148, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/lbsfind", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetA8KeyRequest 授权链接
|
|
|
|
|
|
// @opCode :
|
|
|
|
|
|
//
|
|
|
|
|
|
// enum GetA8KeyOpCode
|
|
|
|
|
|
// {
|
|
|
|
|
|
// MMGETA8KEY_OPENAPI = 1,
|
|
|
|
|
|
// MMGETA8KEY_QZONE = 3,
|
|
|
|
|
|
// MMGETA8KEY_REDIRECT = 2
|
|
|
|
|
|
// }
|
|
|
|
|
|
//
|
|
|
|
|
|
// @scene :
|
|
|
|
|
|
//
|
|
|
|
|
|
// enum GetA8KeyScene
|
|
|
|
|
|
// {
|
|
|
|
|
|
// MMGETA8KEY_SCENE_UNKNOW,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_MSG,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_TIMELINE,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_PROFILE,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_QRCODE,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_QZONE,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_OAUTH,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_OPEN,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_PLUGIN,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_JUMPURL,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_SHAKETV,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_SCANBARCODE,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_SCANIMAGE,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_SCANSTREETVIEW,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_FAV,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_MMBIZ,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_QQMAIL,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_LINKEDIN,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_SHAKETV_DETAIL,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_BIZHOMEPAGE,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_USBCONNECT,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_SHORT_URL,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_WIFI,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_OUTSIDE_DEEPLINK,
|
|
|
|
|
|
// MMGETA8KEY_SCENE_PUSH_LOGIN_URL
|
|
|
|
|
|
// }
|
|
|
|
|
|
func GetA8KeyRequest(userInfo *baseinfo.UserInfo, opCode, scene uint32, reqUrl string, getType baseinfo.GetA8KeyType) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.GetA8KeyRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
OpCode: proto.Uint32(opCode), //2
|
|
|
|
|
|
ReqUrl: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(reqUrl),
|
|
|
|
|
|
},
|
|
|
|
|
|
Scene: proto.Uint32(scene), //4
|
|
|
|
|
|
UserName: proto.String(userInfo.GetUserName()),
|
|
|
|
|
|
BundleID: proto.String(""),
|
|
|
|
|
|
NetType: proto.String("WiFi"),
|
|
|
|
|
|
FontScale: proto.Uint32(100),
|
|
|
|
|
|
RequestId: proto.Uint64(uint64(time.Now().Unix())),
|
|
|
|
|
|
CodeType: proto.Uint32(19),
|
|
|
|
|
|
//CodeType: proto.Uint32(15),
|
|
|
|
|
|
//CodeVersion: proto.Uint32(5),
|
|
|
|
|
|
OuterUrl: proto.String(""),
|
|
|
|
|
|
SubScene: proto.Uint32(1),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cgi := uint32(0)
|
|
|
|
|
|
cgiUrl := ""
|
|
|
|
|
|
|
|
|
|
|
|
switch getType {
|
|
|
|
|
|
case baseinfo.ThrIdGetA8Key:
|
|
|
|
|
|
cgi = baseinfo.MMRequestTypeThrIdGetA8Key
|
|
|
|
|
|
cgiUrl = "/cgi-bin/micromsg-bin/3rd-geta8key"
|
|
|
|
|
|
default:
|
|
|
|
|
|
cgi = baseinfo.MMRequestTypeGetA8Key
|
|
|
|
|
|
cgiUrl = "/cgi-bin/micromsg-bin/geta8key"
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, uint32(cgi), 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, cgiUrl, sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// JSLoginRequest 授权小程序 返回Code
|
|
|
|
|
|
// @appId :要授权wxappid
|
|
|
|
|
|
func JSLoginRequest(userInfo *baseinfo.UserInfo, appId string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.JSLoginRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
AppId: proto.String(appId),
|
|
|
|
|
|
LoginType: proto.Int32(1),
|
|
|
|
|
|
VersionType: proto.Int32(0),
|
|
|
|
|
|
WxaExternalInfo: &wechat.WxaExternalInfo{
|
|
|
|
|
|
Scene: proto.Int32(1001),
|
|
|
|
|
|
SourceEnv: proto.Int32(1),
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*req := wechat.JSLoginRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
AppId: proto.String(appId),
|
|
|
|
|
|
Scope: proto.String("snsapi_login"),
|
|
|
|
|
|
LoginType: proto.Int32(4),
|
|
|
|
|
|
Url: proto.String("https://open.weixin.qq.com/connect/confirm?uuid=021extwqXdPRRlbJ"),
|
|
|
|
|
|
VersionType: proto.Int32(0),
|
|
|
|
|
|
WxaExternalInfo: &wechat.WxaExternalInfo{
|
|
|
|
|
|
Scene: proto.Int32(1001),
|
|
|
|
|
|
SourceEnv: proto.Int32(1),
|
|
|
|
|
|
},
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
/*req := wechat.JSLoginRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
AppId: proto.String(appId),
|
|
|
|
|
|
LoginType: proto.Int32(1),
|
|
|
|
|
|
VersionType: proto.Int32(0),
|
|
|
|
|
|
WxaExternalInfo: &wechat.WxaExternalInfo{
|
|
|
|
|
|
Scene: proto.Int32(1066),
|
|
|
|
|
|
SourceEnv: proto.Int32(1),
|
|
|
|
|
|
},
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeJSLogin, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmbiz-bin/js-login", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// JSOperateWxDataRequest 小程序云函数操作; 授权小程序后返回 encryptedData,iv等信息
|
|
|
|
|
|
func JSOperateWxDataRequest(userInfo *baseinfo.UserInfo, appId string, opt int32, data string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.JSOperateWxDataRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
AppId: proto.String(appId),
|
|
|
|
|
|
Data: []byte(data),
|
|
|
|
|
|
GrantScope: proto.String("scope.userInfo"),
|
|
|
|
|
|
Opt: proto.Int32(opt), // 默认为 1
|
|
|
|
|
|
VersionType: proto.Int32(0),
|
|
|
|
|
|
WxaExternalInfo: &wechat.WxaExternalInfo{
|
|
|
|
|
|
Scene: proto.Int32(1001),
|
|
|
|
|
|
SourceEnv: proto.Int32(2),
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeJSOperateWxData, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmbiz-bin/js-operatewxdata", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SdkOauthAuthorizeRequest 授权app应用
|
|
|
|
|
|
func SdkOauthAuthorizeRequest(userInfo *baseinfo.UserInfo, appId string, sdkName string, packageName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.SdkOauthAuthorizeReq{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
AppId: proto.String(appId),
|
|
|
|
|
|
Tag3: proto.String("snsapi_userinfo"),
|
|
|
|
|
|
Tag4: proto.String(sdkName), //wechat_sdk_demo_test
|
|
|
|
|
|
Tag5: proto.String(packageName), //"com.yimu.renwuxiongObject"
|
|
|
|
|
|
Tag8: proto.String(""),
|
|
|
|
|
|
Tag9: proto.String(""),
|
|
|
|
|
|
Tag10: proto.String(""),
|
|
|
|
|
|
Tag11: proto.String(""),
|
|
|
|
|
|
Tag12: proto.Uint32(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeSdkOauthAuthorize, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmbiz-bin/sdk_oauth_authorize", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSearchContactRequest 搜索联系人
|
|
|
|
|
|
func SendSearchContactRequest(userInfo *baseinfo.UserInfo, opCode, fromScene, searchScene uint32, userName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.SearchContactRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
UserName: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(userName),
|
|
|
|
|
|
},
|
|
|
|
|
|
OpCode: proto.Uint32(opCode),
|
|
|
|
|
|
FromScene: proto.Uint32(fromScene),
|
|
|
|
|
|
SearchScene: proto.Uint32(searchScene),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeSearchContact, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/searchcontact", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// VerifyUserRequest 好友验证
|
|
|
|
|
|
func VerifyUserRequest(userInfo *baseinfo.UserInfo, opCode uint32, verifyContent string, scene int, V3, V4, ChatRoomUserName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
// clientcheckdata
|
|
|
|
|
|
var extSpamInfo wechat.SKBuiltinString_
|
|
|
|
|
|
if userInfo.DeviceInfo != nil {
|
|
|
|
|
|
extSpamInfo.Buffer = GetExtPBSpamInfoDataIPhone(userInfo)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
extSpamInfo.Buffer = GetExtPBSpamInfoDataA16(userInfo)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extSpamInfoLen := uint32(len(extSpamInfo.Buffer))
|
|
|
|
|
|
extSpamInfo.Len = &extSpamInfoLen
|
|
|
|
|
|
|
|
|
|
|
|
userTicket := V4
|
|
|
|
|
|
if ChatRoomUserName != "" {
|
|
|
|
|
|
userTicket = ""
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
req := wechat.VerifyUserRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
OpCode: proto.Uint32(opCode),
|
|
|
|
|
|
VerifyUserListSize: proto.Uint32(1),
|
|
|
|
|
|
VerifyUserList: []*wechat.VerifyUser{{
|
|
|
|
|
|
Value: proto.String(V3),
|
|
|
|
|
|
VerifyUserTicket: proto.String(userTicket),
|
|
|
|
|
|
AntispamTicket: proto.String(V4),
|
|
|
|
|
|
FriendFlag: proto.Uint32(0),
|
|
|
|
|
|
ChatRoomUserName: proto.String(ChatRoomUserName),
|
|
|
|
|
|
SourceUserName: proto.String(""),
|
|
|
|
|
|
SourceNickName: proto.String(""),
|
|
|
|
|
|
ScanQrcodeFromScene: proto.Uint32(0),
|
|
|
|
|
|
ReportInfo: proto.String(""),
|
|
|
|
|
|
OuterUrl: proto.String(""),
|
|
|
|
|
|
SubScene: proto.Uint32(0),
|
|
|
|
|
|
}},
|
|
|
|
|
|
VerifyContent: proto.String(verifyContent),
|
|
|
|
|
|
SceneListCount: proto.Uint32(1),
|
|
|
|
|
|
SceneList: []byte{byte(scene)},
|
|
|
|
|
|
ExtSpamInfo: &extSpamInfo,
|
|
|
|
|
|
//NeedConfirm: proto.Uint32(1),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeVerifyUser, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/verifyuser", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// UploadMContact 上传通讯录
|
|
|
|
|
|
func UploadMContactRequest(userInfo *baseinfo.UserInfo, mobile string, mobiles []string, opcdoe int32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
mobileList := make([]*wechat.Mobile, 0)
|
|
|
|
|
|
for _, mobile := range mobiles {
|
|
|
|
|
|
mobileList = append(mobileList, &wechat.Mobile{
|
|
|
|
|
|
V: proto.String(mobile),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
req := wechat.UploadMContactRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
UserName: proto.String(userInfo.WxId),
|
|
|
|
|
|
Opcode: &opcdoe,
|
|
|
|
|
|
Mobile: proto.String(mobile),
|
|
|
|
|
|
MobileListSize: proto.Int32(int32(len(mobileList))),
|
|
|
|
|
|
MobileList: mobileList,
|
|
|
|
|
|
EmailListSize: proto.Int32(0),
|
|
|
|
|
|
EmailList: []*wechat.MEmail{},
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeUploadMContact, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/uploadmcontact", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetMFriendRequest 获取通讯录
|
|
|
|
|
|
func GetMFriendRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.GetMFriendRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
OpType: proto.Uint32(0),
|
|
|
|
|
|
MD5: proto.String(uuid.New().String()),
|
|
|
|
|
|
Scene: proto.Uint32(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetMFriend, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getmfriend", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetCertRequest 获取证书
|
|
|
|
|
|
func GetCertRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
//userInfo.SessionKey = baseutils.RandomBytes(16)
|
|
|
|
|
|
req := wechat.GetCertRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
AesEncryptKey: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(16),
|
|
|
|
|
|
Buffer: userInfo.SessionKey[:16],
|
|
|
|
|
|
},
|
|
|
|
|
|
Version: proto.Uint32(135),
|
|
|
|
|
|
}
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 381, 7)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getcert", sendEncodeData)
|
|
|
|
|
|
// fmt.Println(hex.EncodeToString(resp))
|
|
|
|
|
|
// fmt.Println(hex.EncodeToString(userInfo.SessionKey))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetSdkOauthAuthorizeConfirmRequest
|
|
|
|
|
|
func GetSdkOauthAuthorizeConfirmRequest(userInfo *baseinfo.UserInfo, AppId, appName, appNamePack string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.SdkOauthAuthorizeConfirmNewReq{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Opt: proto.Uint32(1),
|
|
|
|
|
|
Scope: []string{"snsapi_userinfo"},
|
|
|
|
|
|
AppId: proto.String(AppId),
|
|
|
|
|
|
State: proto.String(appName),
|
|
|
|
|
|
BundleId: proto.String(appNamePack),
|
|
|
|
|
|
AvatarId: proto.Uint32(0),
|
|
|
|
|
|
UniversalLink: proto.String(""),
|
|
|
|
|
|
OpenSdkVersion: proto.String(""),
|
|
|
|
|
|
SdkToken: proto.String(""),
|
|
|
|
|
|
OpenSdkBundleId: proto.String(""),
|
|
|
|
|
|
SdkTokenChk: proto.Uint32(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 1346, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmbiz-bin/sdk_oauth_authorize_confirm", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetQRConnectAuthorizeRequest 获取授权二维码链接组包
|
|
|
|
|
|
func GetQRConnectAuthorizeRequest(userInfo *baseinfo.UserInfo, url string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.QRConnectAuthorizeReq{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
OAuthUrl: proto.String(url),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 2543, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmbiz-bin/qrconnect_authorize", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetQRConnectAuthorizeConfirmRequest 授权二维码链接确认组包
|
|
|
|
|
|
func GetQRConnectAuthorizeConfirmRequest(userInfo *baseinfo.UserInfo, url string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.QRConnectAuthorizeConfirmReq{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
OAuthUrl: proto.String(url),
|
|
|
|
|
|
Opt: proto.Uint32(1),
|
|
|
|
|
|
Scope: []string{"snsapi_login"},
|
|
|
|
|
|
AvatarId: proto.Uint32(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 1137, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmbiz-bin/qrconnect_authorize_confirm", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 授权链接
|
|
|
|
|
|
func SendGetMpA8Request(userInfo *baseinfo.UserInfo, url string, opcode uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.GetA8KeyRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
CodeType: proto.Uint32(19),
|
|
|
|
|
|
CodeVersion: proto.Uint32(10),
|
|
|
|
|
|
Flag: proto.Uint32(0),
|
|
|
|
|
|
FontScale: proto.Uint32(118),
|
|
|
|
|
|
NetType: proto.String("WIFI"),
|
|
|
|
|
|
OpCode: proto.Uint32(opcode),
|
|
|
|
|
|
UserName: proto.String(userInfo.WxId),
|
|
|
|
|
|
ReqUrl: &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(url),
|
|
|
|
|
|
},
|
|
|
|
|
|
FriendQq: proto.Uint32(0),
|
|
|
|
|
|
Scene: proto.Uint32(4),
|
|
|
|
|
|
SubScene: proto.Uint32(1),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 233, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/mp-geta8key", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetOnlineInfoRequest 获取登录信息组包
|
|
|
|
|
|
func GetOnlineInfoRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.GetOnlineInfoRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeGetOnlineInfo, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getonlineinfo", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetRevokeMsgRequest 撤销消息
|
|
|
|
|
|
func GetRevokeMsgRequest(userInfo *baseinfo.UserInfo, newMsgId string, clientMsgId uint64, toUserName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
msgId, _ := strconv.ParseUint(newMsgId, 10, 64)
|
|
|
|
|
|
reqData := wechat.RevokeMsgRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
ClientMsgId: proto.String(fmt.Sprintf("%v_%v", time.Now().Unix(), newMsgId)),
|
|
|
|
|
|
NewClientMsgId: proto.Uint32(uint32(time.Now().Unix())),
|
|
|
|
|
|
CreateTime: proto.Uint32(uint32(time.Now().Unix())),
|
|
|
|
|
|
SvrMsgId: proto.Uint64(clientMsgId),
|
|
|
|
|
|
FromUserName: proto.String(userInfo.GetUserName()),
|
|
|
|
|
|
ToUserName: proto.String(toUserName),
|
|
|
|
|
|
IndexOfRequest: proto.Uint32(26),
|
|
|
|
|
|
SvrNewMsgId: proto.Uint64(msgId),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&reqData)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeRevokeMsg, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/revokemsg", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// RevokeMsgRequestNew 撤回消息New
|
|
|
|
|
|
func RevokeMsgRequestNew(userInfo *baseinfo.UserInfo, m req.RevokeMsgModel) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
newMsgId, _ := strconv.ParseUint(m.NewMsgId, 10, 64)
|
|
|
|
|
|
|
|
|
|
|
|
reqData := wechat.RevokeMsgRequestNew{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
FromUserName: proto.String(userInfo.GetUserName()),
|
|
|
|
|
|
ToUserName: proto.String(m.ToUserName),
|
|
|
|
|
|
CreateTime: proto.Uint64(m.CreateTime),
|
|
|
|
|
|
IndexOfRequest: proto.Uint64(0),
|
|
|
|
|
|
NewMsgId: proto.Uint64(newMsgId),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if m.IsImage {
|
|
|
|
|
|
// 图片消息撤回
|
|
|
|
|
|
if m.ClientImgIdStr != "" {
|
|
|
|
|
|
reqData.ClientMsgId = proto.String(m.ClientImgIdStr) // 使用原始clientImgId字符串
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果未提供,尝试构造一个
|
|
|
|
|
|
reqData.ClientMsgId = proto.String(fmt.Sprintf("%s_%d", userInfo.GetUserName(), m.CreateTime))
|
|
|
|
|
|
}
|
|
|
|
|
|
reqData.MsgId = proto.Uint64(m.ClientMsgId) // 对图片消息,使用msgId值
|
|
|
|
|
|
reqData.NewClientMsgId = proto.Uint64(m.CreateTime) // 尝试使用createTime
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 文本消息撤回,保持原来的逻辑
|
|
|
|
|
|
reqData.ClientMsgId = proto.String("")
|
|
|
|
|
|
reqData.MsgId = proto.Uint64(0)
|
|
|
|
|
|
reqData.NewClientMsgId = proto.Uint64(m.ClientMsgId)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&reqData)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeRevokeMsg, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/revokemsg", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// UploadHeadImage 修改头像
|
|
|
|
|
|
func UploadHeadImage(userInfo *baseinfo.UserInfo, base64Image string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
|
|
|
|
|
|
ImgData := strings.Split(base64Image, ",")
|
|
|
|
|
|
var ImgBase64 []byte
|
|
|
|
|
|
if len(ImgData) > 1 {
|
|
|
|
|
|
ImgBase64, _ = base64.StdEncoding.DecodeString(ImgData[1])
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ImgBase64, _ = base64.StdEncoding.DecodeString(base64Image)
|
|
|
|
|
|
}
|
|
|
|
|
|
ImgStream := bytes.NewBuffer(ImgBase64)
|
|
|
|
|
|
Startpos := 0
|
|
|
|
|
|
datalen := 30000
|
|
|
|
|
|
datatotalength := ImgStream.Len()
|
|
|
|
|
|
ImgHash := GetFileMD5Hash(ImgBase64)
|
|
|
|
|
|
I := 0
|
|
|
|
|
|
resps := make([]byte, 0)
|
|
|
|
|
|
for {
|
|
|
|
|
|
Startpos = I * datalen
|
|
|
|
|
|
count := 0
|
|
|
|
|
|
if datatotalength-Startpos > datalen {
|
|
|
|
|
|
count = datalen
|
|
|
|
|
|
} else {
|
|
|
|
|
|
count = datatotalength - Startpos
|
|
|
|
|
|
}
|
|
|
|
|
|
if count < 0 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
Databuff := make([]byte, count)
|
|
|
|
|
|
_, _ = ImgStream.Read(Databuff)
|
|
|
|
|
|
req := wechat.UploadHDHeadImgRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
TotalLen: proto.Uint32(uint32(datatotalength)),
|
|
|
|
|
|
StartPos: proto.Uint32(uint32(Startpos)),
|
|
|
|
|
|
HeadImgType: proto.Uint32(1),
|
|
|
|
|
|
Data: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(Databuff))),
|
|
|
|
|
|
Buffer: Databuff,
|
|
|
|
|
|
},
|
|
|
|
|
|
ImgHash: proto.String(ImgHash),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeUploadHDHeadImg, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/uploadhdheadimg", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
resps = resp
|
|
|
|
|
|
I++
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
return DecodePackHeader(resps, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func GetFileMD5Hash(Data []byte) string {
|
|
|
|
|
|
hash := md5.New()
|
|
|
|
|
|
hash.Write(Data)
|
|
|
|
|
|
retVal := hash.Sum(nil)
|
|
|
|
|
|
return hex.EncodeToString(retVal)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetVerifyPwdRequest 验证密码
|
|
|
|
|
|
func GetVerifyPwdRequest(userInfo *baseinfo.UserInfo, pwd string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
|
|
|
|
|
|
req := wechat.VerifyPwdRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
OpCode: proto.Uint32(1),
|
|
|
|
|
|
Pwd1: proto.String(baseutils.Md5Value(pwd)),
|
|
|
|
|
|
Pwd2: proto.String(baseutils.Md5Value(pwd)),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeVerifyPassword, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/newverifypasswd", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
// 转 字符串
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendSetPwdRequest 修改密码
|
|
|
|
|
|
func SendSetPwdRequest(userInfo *baseinfo.UserInfo, ticket, newPwd string, OpCode uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
log.Println("SendSetPwdRequest:", newPwd)
|
|
|
|
|
|
log.Println("SendSetPwdRequest:", ticket)
|
|
|
|
|
|
req := &wechat.SetPwdRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Password: proto.String(baseutils.Md5Value(newPwd)),
|
|
|
|
|
|
Ticket: proto.String(ticket),
|
|
|
|
|
|
AutoAuthKey: &wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(uint32(len(userInfo.AutoAuthKey))),
|
|
|
|
|
|
Buffer: userInfo.AutoAuthKey,
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(req)
|
|
|
|
|
|
|
|
|
|
|
|
S2801, _ := hex.DecodeString("2801")
|
|
|
|
|
|
|
|
|
|
|
|
reqdataA := new(bytes.Buffer)
|
|
|
|
|
|
reqdataA.Write(srcData)
|
|
|
|
|
|
|
|
|
|
|
|
if len(userInfo.DeviceInfo.DeviceID) <= 16 {
|
|
|
|
|
|
reqdataA.Write(S2801)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, reqdataA.Bytes(), baseinfo.MMRequestTypeSetPassword, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/newsetpasswd", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendUploadVoiceRequest 发送语音
|
|
|
|
|
|
func SendUploadVoiceNewRequest(userInfo *baseinfo.UserInfo, ToWxId string, Startpos int, Databuff []byte, ClientImgId string, VoiceTime int32, Type int32, endFlag int) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.UploadVoiceRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
FromUserName: proto.String(userInfo.WxId),
|
|
|
|
|
|
ToUserName: proto.String(ToWxId),
|
|
|
|
|
|
Offset: proto.Uint32(uint32(Startpos)),
|
|
|
|
|
|
Length: proto.Uint32(uint32(len(Databuff))),
|
|
|
|
|
|
ClientMsgId: proto.String(ClientImgId),
|
|
|
|
|
|
MsgId: proto.Uint32(0),
|
|
|
|
|
|
VoiceLength: proto.Int32(VoiceTime * 1000),
|
|
|
|
|
|
VoiceFormat: proto.Int32(Type),
|
|
|
|
|
|
Data: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(Databuff))),
|
|
|
|
|
|
Buffer: Databuff,
|
|
|
|
|
|
},
|
|
|
|
|
|
EndFlag: proto.Uint32(uint32(endFlag)),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeUploadVoiceNew, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/uploadvoice", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendUploadVoiceRequest 发送语音
|
|
|
|
|
|
/*func SendUploadVoiceRequest(userInfo *baseinfo.UserInfo, toUserName string, data []byte, totalLen, startPos uint32, clientImgId string, voiceLen uint32, voiceFormat uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
endFlag := uint32(0)
|
|
|
|
|
|
if startPos+uint32(len(data)) >= totalLen {
|
|
|
|
|
|
endFlag = 1
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var req = wechat.UploadVoiceRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
FromUserName: proto.String(userInfo.GetUserName()),
|
|
|
|
|
|
ToUserName: proto.String(toUserName),
|
|
|
|
|
|
ClientMsgId: proto.String(clientImgId),
|
|
|
|
|
|
VoiceFormat: proto.Uint32(voiceFormat),
|
|
|
|
|
|
VoiceLength: proto.Uint32(voiceLen),
|
|
|
|
|
|
Length: proto.Uint32(uint32(len(data))),
|
|
|
|
|
|
Data: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(data))),
|
|
|
|
|
|
Buffer: data,
|
|
|
|
|
|
},
|
|
|
|
|
|
Offset: proto.Uint32(startPos),
|
|
|
|
|
|
EndFlag: proto.Uint32(endFlag),
|
|
|
|
|
|
MsgId: proto.Uint32(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeUploadVoice, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/uploadvoice", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
// SendNewInitSyncRequest 首次登录初始化
|
|
|
|
|
|
func SendNewInitSyncRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
mgr := userInfo.SyncKeyMgr()
|
|
|
|
|
|
if mgr.CurKey() == nil {
|
|
|
|
|
|
mgr.SetCurKey(&wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(0),
|
|
|
|
|
|
Buffer: make([]byte, 0),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
if mgr.MaxKey() == nil {
|
|
|
|
|
|
mgr.SetMaxKey(&wechat.BufferT{
|
|
|
|
|
|
ILen: proto.Uint32(0),
|
|
|
|
|
|
Buffer: make([]byte, 0),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
req := &wechat.NewInitRequest{}
|
|
|
|
|
|
req.BaseRequest = GetBaseRequest(userInfo)
|
|
|
|
|
|
//req.BaseRequest.Scene = proto.Uint32(0)
|
|
|
|
|
|
req.UserName = proto.String(userInfo.GetUserName())
|
|
|
|
|
|
req.CurrentSynckey = mgr.CurKey()
|
|
|
|
|
|
req.MaxSynckey = mgr.MaxKey()
|
|
|
|
|
|
req.Language = proto.String("zh_CN")
|
|
|
|
|
|
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, baseinfo.MMRequestTypeNewInit, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/newinit", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置微信号
|
|
|
|
|
|
func SetWechatRequest(userInfo *baseinfo.UserInfo, alisa string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.GeneralSetRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
SetType: proto.Int32(1),
|
|
|
|
|
|
SetValue: proto.String(alisa),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 177, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/generalset", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取设备
|
|
|
|
|
|
func GetBoundHardDeviceRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.GetBoundHardDevicesRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Version: proto.Uint32(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 539, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getboundharddevices", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取步数列表
|
|
|
|
|
|
func SendGetUserRankLikeCountRequest(userInfo *baseinfo.UserInfo, rankId string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.GetUserRankLikeCountRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Username: proto.String(userInfo.WxId),
|
|
|
|
|
|
LatestRank: proto.Bool(true),
|
|
|
|
|
|
RankId: proto.String(rankId),
|
|
|
|
|
|
AppUsername: proto.String("wx7fa037cc7dfabad5"),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 1042, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmbiz-bin/rank/getuserranklike", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 上传步数
|
|
|
|
|
|
func UploadStepSetRequestRequest(userInfo *baseinfo.UserInfo, deviceID string, deviceType string, number uint64) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
currentTime := time.Now()
|
|
|
|
|
|
startTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, currentTime.Location()).Unix()
|
|
|
|
|
|
endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location()).Unix()
|
|
|
|
|
|
var req = wechat.UploadDeviceStepRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
DeviceID: proto.String(deviceID),
|
|
|
|
|
|
DeviceType: proto.String(deviceType),
|
|
|
|
|
|
FromTime: proto.Uint32(uint32(startTime)),
|
|
|
|
|
|
ToTime: proto.Uint32(uint32(endTime)),
|
|
|
|
|
|
StepCount: proto.Uint32(uint32(number)),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 1261, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/mmoc-bin/hardware/uploaddevicestep", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取企业 wx 详情
|
|
|
|
|
|
func SendQWContactRequest(userInfo *baseinfo.UserInfo, openIm, chatRoom, t string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
req := wechat.GetQYContactRequest{}
|
|
|
|
|
|
req.Wxid = proto.String(openIm)
|
|
|
|
|
|
if chatRoom != "" {
|
|
|
|
|
|
req.Room = proto.String(chatRoom)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 881, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getopenimcontact", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取全部的企业通寻录
|
|
|
|
|
|
func SendQWSyncContactRequest(userInfo *baseinfo.UserInfo) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
ck := make([]*wechat.SyncKey_, 0)
|
|
|
|
|
|
ck = append(ck, &wechat.SyncKey_{
|
|
|
|
|
|
SyncKey: proto.Int64(0),
|
|
|
|
|
|
Type: proto.Uint32(400),
|
|
|
|
|
|
})
|
|
|
|
|
|
key := wechat.SyncMsgKey{
|
|
|
|
|
|
Len: proto.Uint32(1),
|
|
|
|
|
|
MsgKey: &wechat.SyncKey{
|
|
|
|
|
|
Size: proto.Uint32(1),
|
|
|
|
|
|
Type: ck,
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
keyMar, _ := proto.Marshal(&key)
|
|
|
|
|
|
var req = wechat.QYSyncRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Selector: proto.Int64(0x200000),
|
|
|
|
|
|
Key: keyMar,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 810, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/openimsync", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建企业群
|
|
|
|
|
|
func SendQWCreateChatRoomRequest(userInfo *baseinfo.UserInfo, userList []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
memberlist := make([]*wechat.Openimcontact, 0)
|
|
|
|
|
|
for _, val := range userList {
|
|
|
|
|
|
memberlist = append(memberlist, &wechat.Openimcontact{
|
|
|
|
|
|
UserName: proto.String(val),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
var req = wechat.CreateQYChatRoomRequest{
|
|
|
|
|
|
MemberList: memberlist,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 371, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/createopenimchatroom", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 向企业微信打招呼
|
|
|
|
|
|
func SendQWApplyAddContactRequest(userInfo *baseinfo.UserInfo, toUserName, v1, Content string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.QYVerifyUserRequest{
|
|
|
|
|
|
Wxid: proto.String(toUserName),
|
|
|
|
|
|
V1: proto.String(v1),
|
|
|
|
|
|
Content: proto.String(Content),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 0xF3, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/sendopenimverifyrequest", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 单向加企业微信
|
|
|
|
|
|
func SendQWAddContactRequest(userInfo *baseinfo.UserInfo, toUserName, v1, Content string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.QYVAddUserRequest{
|
|
|
|
|
|
Wxid: proto.String(toUserName),
|
|
|
|
|
|
V1: proto.String(v1),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 667, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/addopenimcontact", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取所有企业群
|
|
|
|
|
|
func SendQWSyncChatRoomRequest(userInfo *baseinfo.UserInfo, key string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
ck := make([]*wechat.SyncKey_, 0)
|
|
|
|
|
|
ck = append(ck, &wechat.SyncKey_{
|
|
|
|
|
|
SyncKey: proto.Int64(0),
|
|
|
|
|
|
Type: proto.Uint32(0),
|
|
|
|
|
|
})
|
|
|
|
|
|
keys := wechat.SyncMsgKey{
|
|
|
|
|
|
Len: proto.Uint32(1),
|
|
|
|
|
|
MsgKey: &wechat.SyncKey{
|
|
|
|
|
|
Size: proto.Uint32(1),
|
|
|
|
|
|
Type: ck,
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
keyMar, _ := proto.Marshal(&keys)
|
|
|
|
|
|
var req = wechat.QYSyncRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Selector: proto.Int64(2097152), //0x200000 2097152
|
|
|
|
|
|
Key: keyMar,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 810, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/openimsync", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 转让企业微信群
|
|
|
|
|
|
func SendQWChatRoomTransferOwnerRequest(userInfo *baseinfo.UserInfo, chatRoomName string, toUserName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.QWTransferChatRoomOwnerRequest{
|
|
|
|
|
|
Username: proto.String(chatRoomName),
|
|
|
|
|
|
Owner: &wechat.Openimcontact{
|
|
|
|
|
|
UserName: proto.String(toUserName),
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 811, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/modopenimchatroomowner", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 直接拉好友进群
|
|
|
|
|
|
func SendQWAddChatRoomMemberRequest(userInfo *baseinfo.UserInfo, chatRoomName string, toUserName []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
list := make([]*wechat.Openimcontact, 0)
|
|
|
|
|
|
for _, val := range toUserName {
|
|
|
|
|
|
list = append(list, &wechat.Openimcontact{
|
|
|
|
|
|
UserName: proto.String(val),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
var req = wechat.QYAddChatRoomRequest{
|
|
|
|
|
|
ChatRoomName: proto.String(chatRoomName),
|
|
|
|
|
|
MemberList: list,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 0x32E, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/addopenimchatroommember", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 发送群邀请链接
|
|
|
|
|
|
func SendQWInviteChatRoomMemberRequest(userInfo *baseinfo.UserInfo, chatRoomName string, toUserName []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
list := make([]*wechat.Openimcontact, 0)
|
|
|
|
|
|
for _, val := range toUserName {
|
|
|
|
|
|
list = append(list, &wechat.Openimcontact{
|
|
|
|
|
|
UserName: proto.String(val),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
var req = wechat.InviteQYChatRoomRequest{
|
|
|
|
|
|
ChatRoomName: proto.String(chatRoomName),
|
|
|
|
|
|
MemberList: list,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 887, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/inviteopenimchatroommember", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 删除企业群群成员
|
|
|
|
|
|
func SendQWDelChatRoomMemberRequest(userInfo *baseinfo.UserInfo, chatRoomName string, toUserName []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
list := make([]*wechat.Openimcontact, 0)
|
|
|
|
|
|
for _, val := range toUserName {
|
|
|
|
|
|
list = append(list, &wechat.Openimcontact{
|
|
|
|
|
|
UserName: proto.String(val),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
var req = wechat.QYDelChatRoomMemberRequest{
|
|
|
|
|
|
Username: proto.String(chatRoomName),
|
|
|
|
|
|
MemberList: list,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 0x3AF, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/delopenimchatroommember", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取企业群全部成员
|
|
|
|
|
|
func SendQWGetChatRoomMemberRequest(userInfo *baseinfo.UserInfo, chatRoomName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.GetQYChatroomMemberDetailRequest{
|
|
|
|
|
|
ChatroomUserName: proto.String(chatRoomName),
|
|
|
|
|
|
ClientVersion: proto.Uint64(0),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 942, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getopenimchatroommemberdetail", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取企业群名称公告设定等信息
|
|
|
|
|
|
func SendQWGetChatroomInfoRequest(userInfo *baseinfo.UserInfo, chatRoomName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.Openimcontact{
|
|
|
|
|
|
UserName: proto.String(chatRoomName),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 407, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getopenimchatroomcontact", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取企业群二维码
|
|
|
|
|
|
func SendQWGetChatRoomQRRequest(userInfo *baseinfo.UserInfo, chatRoomName string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.Openimcontact{
|
|
|
|
|
|
UserName: proto.String(chatRoomName),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 890, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/getopenimchatroomqrcode", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 增加企业管理员
|
|
|
|
|
|
func SendQWAppointChatRoomAdminRequest(userInfo *baseinfo.UserInfo, chatRoomName string, toUserName []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.QYChatRoomAdminRequest{
|
|
|
|
|
|
ChatRoomName: proto.String(chatRoomName),
|
|
|
|
|
|
MemberList: toUserName,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 776, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/addopenimchatroomadmin", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 移除企业群管理员
|
|
|
|
|
|
func SendQWDelChatRoomAdminRequest(userInfo *baseinfo.UserInfo, chatRoomName string, toUserName []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.QYChatRoomAdminRequest{
|
|
|
|
|
|
ChatRoomName: proto.String(chatRoomName),
|
|
|
|
|
|
MemberList: toUserName,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 3677, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/delopenimchatroomadmin", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 同意进企业群
|
|
|
|
|
|
func SendQWAcceptChatRoomRequest(userInfo *baseinfo.UserInfo, link string, opcode uint32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.GetA8KeyRequest{}
|
|
|
|
|
|
req.BaseRequest = GetBaseRequest(userInfo)
|
|
|
|
|
|
req.CodeType = proto.Uint32(0)
|
|
|
|
|
|
req.CodeVersion = proto.Uint32(8)
|
|
|
|
|
|
req.Flag = proto.Uint32(0)
|
|
|
|
|
|
req.FontScale = proto.Uint32(100)
|
|
|
|
|
|
req.NetType = proto.String("WIFI")
|
|
|
|
|
|
req.OpCode = proto.Uint32(opcode)
|
|
|
|
|
|
req.UserName = proto.String(userInfo.WxId)
|
|
|
|
|
|
req.ReqUrl = &wechat.SKBuiltinString{
|
|
|
|
|
|
Str: proto.String(link),
|
|
|
|
|
|
}
|
|
|
|
|
|
req.FriendQq = proto.Uint32(0)
|
|
|
|
|
|
req.Scene = proto.Uint32(37)
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 233, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/geta8key", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设定企业群管理审核进群
|
|
|
|
|
|
func SendQWAdminAcceptJoinChatRoomSetRequest(userInfo *baseinfo.UserInfo, link string, url string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.QYChatRoomAdminRequest{}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 3677, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/delopenimchatroomadmin", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 群管理批准进企业群
|
|
|
|
|
|
func SendQWAdminAcceptJoinChatRoomRequest(userInfo *baseinfo.UserInfo, chatRoomName, key, toUserName string, toUserNames []string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
list := make([]*wechat.Openimcontact, 0)
|
|
|
|
|
|
for _, val := range toUserNames {
|
|
|
|
|
|
list = append(list, &wechat.Openimcontact{
|
|
|
|
|
|
UserName: proto.String(val),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
var req = wechat.QYAdminAddRequest{
|
|
|
|
|
|
Room: proto.String(chatRoomName),
|
|
|
|
|
|
Key: proto.String(key),
|
|
|
|
|
|
Username: &wechat.Openimcontact{
|
|
|
|
|
|
UserName: proto.String(toUserName),
|
|
|
|
|
|
},
|
|
|
|
|
|
Usernamelist: list,
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 0x3AD, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/approveaddopenimchatroommember", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 视频号搜索
|
|
|
|
|
|
func SendGetFinderSearchRequest(userInfo *baseinfo.UserInfo, Index uint32, Userver int32, UserKey string, Uuid string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.FinderSearchRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
UserKey: proto.String(UserKey),
|
|
|
|
|
|
Offset: proto.Uint32(Index),
|
|
|
|
|
|
Scene: proto.Uint32(0),
|
|
|
|
|
|
Uuid: proto.String(Uuid),
|
|
|
|
|
|
FinderTxRequest: &wechat.FinderTxRequest{
|
|
|
|
|
|
Userver: proto.Int32(Userver),
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 3820, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/findersearch", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 视频号个人中心
|
|
|
|
|
|
func SendFinderUserPrepareRequest(userInfo *baseinfo.UserInfo, Userver int32) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
var req = wechat.FinderUserPrepareRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Scene: proto.Int32(0),
|
|
|
|
|
|
FinderTxRequest: &wechat.FinderTxRequest{
|
|
|
|
|
|
Userver: proto.Int32(Userver),
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 3761, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/finderuserprepare", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 视频号关注or取消关注
|
|
|
|
|
|
func SendFinderFollowRequest(userInfo *baseinfo.UserInfo, FinderUserName string, OpType int32, RefObjectId string, Cook string, Userver int32, PosterUsername string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
//refId, err := strconv.ParseUint(RefObjectId, 10, 64)
|
|
|
|
|
|
T := time.Now().Unix()
|
|
|
|
|
|
var req = wechat.FinderFollowRequest{
|
|
|
|
|
|
FinderUsername: proto.String(FinderUserName),
|
|
|
|
|
|
OpType: proto.Int32(OpType),
|
|
|
|
|
|
RefObjectId: proto.Uint64(0),
|
|
|
|
|
|
PosterUsername: proto.String(""),
|
|
|
|
|
|
FinderReq: &wechat.FinderTxRequest{
|
|
|
|
|
|
Userver: proto.Int32(Userver),
|
|
|
|
|
|
Scene: proto.Int32(6),
|
|
|
|
|
|
T: proto.Int32(1),
|
|
|
|
|
|
G: &wechat.FinderZd{
|
|
|
|
|
|
G1: proto.String(fmt.Sprintf("Finder_Enter%v", T)),
|
|
|
|
|
|
G2: proto.String(fmt.Sprintf("4-%v", T)),
|
|
|
|
|
|
G3: proto.String(fmt.Sprintf(`{"sessionId":"109_%v#$0_%v#"}`, T, T)),
|
|
|
|
|
|
},
|
|
|
|
|
|
Tg: proto.Int64(time.Now().Unix()),
|
|
|
|
|
|
},
|
|
|
|
|
|
Cook: proto.String(Cook),
|
|
|
|
|
|
EnterType: proto.Int32(7),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 3867, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/finderfollow", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取验证码
|
|
|
|
|
|
func SendWxBindOpMobileForRegRequest(userInfo *baseinfo.UserInfo, opcode int64, mobile, verifycode string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
tmpTime := int(time.Now().UnixNano() / 1000000000)
|
|
|
|
|
|
tmpTimeStr := strconv.Itoa(tmpTime)
|
|
|
|
|
|
var strClientSeqID = string(userInfo.DeviceInfo.Imei + "-" + tmpTimeStr)
|
|
|
|
|
|
var req = wechat.BindOpMobileForRegRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
Mobile: proto.String(mobile),
|
|
|
|
|
|
Opcode: proto.Int64(opcode),
|
|
|
|
|
|
Verifycode: proto.String(verifycode),
|
|
|
|
|
|
SafeDeviceName: proto.String("iPad"),
|
|
|
|
|
|
SafeDeviceType: proto.String("iPad"),
|
|
|
|
|
|
RandomEncryKey: &wechat.SKBuiltinString_{
|
|
|
|
|
|
Len: proto.Uint32(uint32(len(userInfo.SessionKey))),
|
|
|
|
|
|
Buffer: userInfo.SessionKey,
|
|
|
|
|
|
},
|
|
|
|
|
|
Language: proto.String("zh_CN"),
|
|
|
|
|
|
InputMobileReTrYs: proto.Uint32(0),
|
|
|
|
|
|
AdjustRet: proto.Uint32(0),
|
|
|
|
|
|
ClientSeqID: proto.String(strClientSeqID),
|
|
|
|
|
|
DialLang: proto.String(""),
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 145, 7)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/bindopmobileforreg", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendUploadAppAttach 上传文件
|
|
|
|
|
|
func SendUploadAppAttach(userInfo *baseinfo.UserInfo, fileData []byte) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
Stream := bytes.NewBuffer(fileData)
|
|
|
|
|
|
|
|
|
|
|
|
datalen := 50000
|
|
|
|
|
|
datatotalength := Stream.Len()
|
|
|
|
|
|
FileMD5 := lib.GetFileMD5Hash(fileData)
|
|
|
|
|
|
|
|
|
|
|
|
ClientAppDataId := fmt.Sprintf("%v_%v_UploadFile", userInfo.WxId, time.Now().Unix())
|
|
|
|
|
|
|
|
|
|
|
|
Startpos := 0
|
|
|
|
|
|
I := 0
|
|
|
|
|
|
var protobufdata []byte
|
|
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
|
Startpos = I * datalen
|
|
|
|
|
|
count := 0
|
|
|
|
|
|
if datatotalength-Startpos > datalen {
|
|
|
|
|
|
count = datalen
|
|
|
|
|
|
} else {
|
|
|
|
|
|
count = datatotalength - Startpos
|
|
|
|
|
|
}
|
|
|
|
|
|
if count <= 0 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Databuff := make([]byte, count)
|
|
|
|
|
|
_, _ = Stream.Read(Databuff)
|
|
|
|
|
|
|
|
|
|
|
|
req := &wechat.UploadAppAttachRequest{
|
|
|
|
|
|
BaseRequest: GetBaseRequest(userInfo),
|
|
|
|
|
|
AppId: proto.String(""),
|
|
|
|
|
|
SdkVersion: proto.Uint32(0),
|
|
|
|
|
|
ClientAppDataId: proto.String(ClientAppDataId),
|
|
|
|
|
|
UserName: proto.String(userInfo.WxId),
|
|
|
|
|
|
TotalLen: proto.Uint32(uint32(datatotalength)),
|
|
|
|
|
|
StartPos: proto.Uint32(uint32(Startpos)),
|
|
|
|
|
|
DataLen: proto.Uint32(uint32(len(Databuff))),
|
|
|
|
|
|
Data: &wechat.SKBuiltinBufferT{
|
|
|
|
|
|
ILen: proto.Uint32(uint32(len(Databuff))),
|
|
|
|
|
|
Buffer: Databuff,
|
|
|
|
|
|
},
|
|
|
|
|
|
Type: proto.Uint32(6),
|
|
|
|
|
|
Md5: proto.String(FileMD5),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 序列化请求数据
|
|
|
|
|
|
reqdata, err := proto.Marshal(req)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, reqdata, 220, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/uploadappattach", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protobufdata = resp
|
|
|
|
|
|
I++
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return DecodePackHeader(protobufdata, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendScanQrcodeEventReportRequest 扫码事件上报 (CGI ID: 8887)
|
|
|
|
|
|
// 模拟用户扫码行为
|
|
|
|
|
|
func SendScanQrcodeEventReportRequest(userInfo *baseinfo.UserInfo, loginUrl string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
baseReq := GetBaseRequest(userInfo)
|
|
|
|
|
|
|
|
|
|
|
|
var req = wechat.ScanQrcodeEventReportRequest{
|
|
|
|
|
|
A: &wechat.ScanQrcodeBaseInfo{
|
|
|
|
|
|
A1: proto.String(""),
|
|
|
|
|
|
A2: proto.Int32(int32(*baseReq.Uin)),
|
|
|
|
|
|
A3: proto.String(string(baseReq.DeviceId)),
|
|
|
|
|
|
A4: proto.Int32(int32(*baseReq.ClientVersion)),
|
|
|
|
|
|
A5: proto.String(*baseReq.OsType),
|
|
|
|
|
|
A6: proto.Int32(0),
|
|
|
|
|
|
},
|
|
|
|
|
|
D: proto.Int32(19), // 事件类型 (字段2)
|
|
|
|
|
|
E: proto.Int32(4), // Scene (字段3)
|
|
|
|
|
|
F: proto.Int32(102462105), // 时间戳 (字段4)
|
|
|
|
|
|
// 字段5不存在,跳过
|
|
|
|
|
|
H: proto.String(strings.Trim(strings.TrimSpace(loginUrl), " `\"'")), // 登录URL (字段6)
|
|
|
|
|
|
I: proto.String(""), // 空字符串 (字段7)
|
|
|
|
|
|
M: proto.Int32(0), // 标志 (字段8)
|
|
|
|
|
|
N: []byte("0.964844"), // 版本号二进制 (字段9)
|
|
|
|
|
|
O: proto.Int32(1), // 标志 (字段10)
|
|
|
|
|
|
P: []byte("0.992188"), // 版本号二进制 (字段11)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 8887, 5)
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/scan_qrcode_event_report_cgi", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendExtDeviceLoginConfirmGetRequest 微信小店获取确认信息 (CGI ID: 971)
|
|
|
|
|
|
func SendExtDeviceLoginConfirmGetRequest(userInfo *baseinfo.UserInfo, loginUrl string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
if userInfo == nil || len(userInfo.SessionKey) == 0 {
|
|
|
|
|
|
return nil, fmt.Errorf("session 未初始化")
|
|
|
|
|
|
}
|
|
|
|
|
|
extra := load971Extra()
|
|
|
|
|
|
// 替换时间戳为当前时间
|
|
|
|
|
|
extra = replaceTimestampIn971Extra(extra)
|
|
|
|
|
|
srcData := build971Raw(loginUrl, extra)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 971, 5)
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/extdeviceloginconfirmget", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func encodeVarint(n int) []byte {
|
|
|
|
|
|
b := make([]byte, 0, 10)
|
|
|
|
|
|
u := uint64(n)
|
|
|
|
|
|
for u >= 0x80 {
|
|
|
|
|
|
b = append(b, byte(u)|0x80)
|
|
|
|
|
|
u >>= 7
|
|
|
|
|
|
}
|
|
|
|
|
|
b = append(b, byte(u))
|
|
|
|
|
|
return b
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func build971Raw(url string, extra []byte) []byte {
|
|
|
|
|
|
b := make([]byte, 0, len(url)+len(extra)+16)
|
|
|
|
|
|
// Field 1: URL (string)
|
|
|
|
|
|
b = append(b, 0x0a) // field 1, wire type 2 (length-delimited)
|
|
|
|
|
|
b = append(b, encodeVarint(len(url))...)
|
|
|
|
|
|
b = append(b, []byte(url)...)
|
|
|
|
|
|
|
|
|
|
|
|
// Field 3: Extra data (nested message)
|
|
|
|
|
|
if len(extra) > 0 {
|
|
|
|
|
|
b = append(b, 0x1a) // field 3, wire type 2 (length-delimited)
|
|
|
|
|
|
b = append(b, encodeVarint(len(extra))...)
|
|
|
|
|
|
b = append(b, extra...)
|
|
|
|
|
|
}
|
|
|
|
|
|
return b
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// load971Extra 从扫码.txt文件中提取field 3的嵌套消息数据
|
|
|
|
|
|
// 文件结构: field1(url) + field3(nested message)
|
|
|
|
|
|
// 我们需要提取field3中的嵌套消息内容
|
|
|
|
|
|
func load971Extra() []byte {
|
|
|
|
|
|
p := "protobuf/扫码.txt"
|
|
|
|
|
|
d, err := ioutil.ReadFile(p)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
s := strings.TrimSpace(string(d))
|
|
|
|
|
|
s = strings.TrimPrefix(s, "0x")
|
|
|
|
|
|
s = strings.ReplaceAll(s, " ", "")
|
|
|
|
|
|
s = strings.ReplaceAll(s, "\n", "")
|
|
|
|
|
|
raw, err := hex.DecodeString(s)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 解析protobuf结构
|
|
|
|
|
|
// 跳过field 1 (URL)
|
|
|
|
|
|
if len(raw) < 3 || raw[0] != 0x0a {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
i := 1
|
|
|
|
|
|
// 读取URL长度
|
|
|
|
|
|
urlLen := 0
|
|
|
|
|
|
shift := 0
|
|
|
|
|
|
for {
|
|
|
|
|
|
if i >= len(raw) {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
b := raw[i]
|
|
|
|
|
|
i++
|
|
|
|
|
|
urlLen |= int(b&0x7f) << shift
|
|
|
|
|
|
if b < 0x80 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
shift += 7
|
|
|
|
|
|
}
|
|
|
|
|
|
// 跳过URL内容
|
|
|
|
|
|
i += urlLen
|
|
|
|
|
|
|
|
|
|
|
|
// 现在应该在field 3的位置
|
|
|
|
|
|
if i >= len(raw) || raw[i] != 0x1a {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
i++ // 跳过field tag
|
|
|
|
|
|
|
|
|
|
|
|
// 读取field 3的长度
|
|
|
|
|
|
field3Len := 0
|
|
|
|
|
|
shift = 0
|
|
|
|
|
|
for {
|
|
|
|
|
|
if i >= len(raw) {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
b := raw[i]
|
|
|
|
|
|
i++
|
|
|
|
|
|
field3Len |= int(b&0x7f) << shift
|
|
|
|
|
|
if b < 0x80 {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
shift += 7
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取field 3的内容
|
|
|
|
|
|
if i+field3Len > len(raw) {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
return raw[i : i+field3Len]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// replaceTimestampIn971Extra 替换 field 3 中的时间戳为当前时间
|
|
|
|
|
|
// 已知时间戳: 1765334020 (2025-12-10 10:33:40),以 varint 编码存储
|
|
|
|
|
|
func replaceTimestampIn971Extra(data []byte) []byte {
|
|
|
|
|
|
if data == nil || len(data) < 100 {
|
|
|
|
|
|
return data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 旧时间戳: 1765334020 -> varint: 84b8e3c906 (5字节)
|
|
|
|
|
|
oldTimestamp := int64(1765334020)
|
|
|
|
|
|
oldVarint := encodeVarint64(oldTimestamp)
|
|
|
|
|
|
|
|
|
|
|
|
// 新时间戳: 当前时间
|
|
|
|
|
|
newTimestamp := time.Now().Unix()
|
|
|
|
|
|
newVarint := encodeVarint64(newTimestamp)
|
|
|
|
|
|
|
|
|
|
|
|
// 在 data 中搜索并替换旧时间戳
|
|
|
|
|
|
result := make([]byte, len(data))
|
|
|
|
|
|
copy(result, data)
|
|
|
|
|
|
|
|
|
|
|
|
// 搜索旧时间戳的位置
|
|
|
|
|
|
for i := 0; i <= len(result)-len(oldVarint); i++ {
|
|
|
|
|
|
match := true
|
|
|
|
|
|
for j := 0; j < len(oldVarint); j++ {
|
|
|
|
|
|
if result[i+j] != oldVarint[j] {
|
|
|
|
|
|
match = false
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if match {
|
|
|
|
|
|
// 找到了,替换
|
|
|
|
|
|
if len(newVarint) == len(oldVarint) {
|
|
|
|
|
|
// 长度相同,直接替换
|
|
|
|
|
|
copy(result[i:], newVarint)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 长度不同,需要重新构建整个数组
|
|
|
|
|
|
newResult := make([]byte, 0, len(data)-len(oldVarint)+len(newVarint))
|
|
|
|
|
|
newResult = append(newResult, result[:i]...)
|
|
|
|
|
|
newResult = append(newResult, newVarint...)
|
|
|
|
|
|
newResult = append(newResult, result[i+len(oldVarint):]...)
|
|
|
|
|
|
return newResult
|
|
|
|
|
|
}
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func encodeVarint64(n int64) []byte {
|
|
|
|
|
|
b := make([]byte, 0, 10)
|
|
|
|
|
|
u := uint64(n)
|
|
|
|
|
|
for u >= 0x80 {
|
|
|
|
|
|
b = append(b, byte(u)|0x80)
|
|
|
|
|
|
u >>= 7
|
|
|
|
|
|
}
|
|
|
|
|
|
b = append(b, byte(u))
|
|
|
|
|
|
return b
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SendExtDeviceLoginConfirmOkRequest 微信小店确认登录 (CGI ID: 972)
|
|
|
|
|
|
func SendExtDeviceLoginConfirmOkRequest(userInfo *baseinfo.UserInfo, loginUrl string) (*baseinfo.PackHeader, error) {
|
|
|
|
|
|
// 自动拼接deviceId: wxid,newsapp,wxid,weixin
|
|
|
|
|
|
wxid := userInfo.GetUserName()
|
|
|
|
|
|
deviceId := fmt.Sprintf("%s,newsapp,%s,weixin", wxid, wxid)
|
|
|
|
|
|
fmt.Println(deviceId)
|
|
|
|
|
|
var req = wechat.ExtDeviceLoginConfirmOkRequest{
|
|
|
|
|
|
D: proto.String(strings.Trim(strings.TrimSpace(strings.Replace(loginUrl, "https", "http", -1)), " `\"'")),
|
|
|
|
|
|
E: proto.String(deviceId), // 字段2: 设备ID
|
|
|
|
|
|
H: proto.Int32(0), // 字段4
|
|
|
|
|
|
J: proto.Int32(0), // 字段5
|
|
|
|
|
|
M: proto.Int32(0), // 字段7
|
|
|
|
|
|
}
|
|
|
|
|
|
// 打包发送数据
|
|
|
|
|
|
srcData, _ := proto.Marshal(&req)
|
|
|
|
|
|
sendEncodeData := Pack(userInfo, srcData, 972, 5)
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := mmtls.MMHTTPPostData(userInfo.MMInfo, "/cgi-bin/micromsg-bin/extdeviceloginconfirmok", sendEncodeData)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(resp) <= 32 {
|
|
|
|
|
|
return nil, fmt.Errorf("请求被拒绝: %d", len(resp))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return DecodePackHeader(resp, nil)
|
|
|
|
|
|
}
|