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:接受人微信id,content:消息内容,atWxIDList:@用户微信id列表(toWxid只能是群的wxid,content应为:@用户昵称 @用户昵称 消息内容)
func SendTextMsg(userInfo *baseinfo.UserInfo, toWxid string, content string, atWxIDList []string, ContentType int) (*baseinfo.PackHeader, error) {
// 构造请求
var request wechat.NewSendMsgRequest
var count uint32 = 1
request.MsgCount = &count
var msgRequestNewList []*wechat.MicroMsgRequestNew = make([]*wechat.MicroMsgRequestNew, count)
var msgRequestNew wechat.MicroMsgRequestNew
var recvierString wechat.SKBuiltinString
recvierString.Str = &toWxid
msgRequestNew.ToUserName = &recvierString // 设置接收人wxid
msgRequestNew.Content = &content // 设置发送内容
if ContentType == 0 {
ContentType = 1
}
var tmpType uint32 = uint32(ContentType)
msgRequestNew.Type = &tmpType // 发送的类型
currentTime := time.Now()
misSecond := currentTime.UnixNano() / 1000000
var seconds = uint32(misSecond / 1000)
msgRequestNew.CreateTime = &seconds // 设置时间 秒为单位
seqID := time.Now().UnixNano() / int64(time.Millisecond)
var tmpCheckCode = WithSeqidCalcCheckCode(toWxid, seqID)
msgRequestNew.ClientMsgId = &tmpCheckCode // 设置校验码
// atUserList
var atUserStr = string("")
size := len(atWxIDList)
if size > 0 {
atUserStr = atUserStr + ""
for index := 0; index < size; index++ {
atUserStr = atUserStr + atWxIDList[index]
if index < size-1 {
atUserStr = atUserStr + ","
}
}
atUserStr = atUserStr + ""
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 = `
{{.ID}}
{{.UserName}}
{{.CreateTime}}
{{.ContentDesc}}
{{.ContentDescShowType}}
{{.ContentDescScene}}
{{.Private}}
{{.SightFolded}}
{{.ShowFlag}}
{{.AppInfo.ID}}
{{.AppInfo.Version}}
{{.AppInfo.AppName}}
{{.AppInfo.InstallURL}}
{{.AppInfo.FromURL}}
{{.AppInfo.IsForceUpdate}}
{{.SourceUserName}}
{{.SourceNickName}}
{{.StatisticsData}}
{{.StatExtStr}}
{{range .ContentObject.FinderFeed.MediaList.Media}}
{{.MediaType}}
{{.Height}}
{{.Width}}
{{.VideoPlayDuration}}
{{end}}
{{.StreamVideo.StreamVideoURL}}
{{.StreamVideo.StreamVideoThumbURL}}
{{.StreamVideo.StreamVideoWebURL}}
`
// 创建模板
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)
}