Files
wechat_ipad_pro/clientsdk/request.go
2026-02-17 13:06:23 +08:00

5148 lines
170 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
// 打包发送数据
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)
}
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接受人微信idcontent消息内容atWxIDList@用户微信id列表toWxid只能是群的wxidcontent应为@用户昵称 @用户昵称 消息内容)
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)
}