package clientsdk import ( "encoding/hex" "errors" "fmt" "hash/crc32" "net/url" "strconv" "strings" "time" "xiawan/wx/clientsdk/android" "xiawan/wx/clientsdk/android/mmproto" "xiawan/wx/clientsdk/baseinfo" "xiawan/wx/clientsdk/baseutils" "xiawan/wx/clientsdk/extinfo" "xiawan/wx/protobuf/wechat" "github.com/golang/protobuf/proto" "github.com/micro/go-micro/util/log" ) // GetClientCheckData 获取ClientCheckData // func GetClientCheckData(userInfo *baseinfo.UserInfo) []byte { // retData, err := ccdata.CreateClientCheckData(userInfo.DeviceInfo.ClientCheckDataXML) // if err != nil { // log.Info(err) // return retData // } // // DeviceRunningInfo // deviceRuntimInfo := &wechat.DeviceRunningInfo{} // mode := uint32(1) // deviceRuntimInfo.Mode = &mode // deviceRuntimInfo.Type = []byte("00000003") // deviceRuntimInfo.Data = retData // // 序列化 // finalData, err := proto.Marshal(deviceRuntimInfo) // if err != nil { // log.Info(err) // } // return finalData // } // GetExtSpamInfoData 获取ExtSpamInfo // func GetExtSpamInfoData(userInfo *baseinfo.UserInfo) []byte { // ccdata := GetClientCheckData(userInfo) // // WCExtInfoLod // extInfo := &wechat.WCExtInfo{} // // ccDataBuffer // var ccDataBuffer wechat.SKBuiltinString_ // tmpLen := uint32(len(ccdata)) // ccDataBuffer.Len = &tmpLen // ccDataBuffer.Buffer = ccdata // extInfo.CcData = &ccDataBuffer // // 序列化 // retData, err := proto.Marshal(extInfo) // if err != nil { // log.Info(err) // } // return retData // } func GetExtPBSpamInfoDataA16(userInfo *baseinfo.UserInfo, wxId ...string) []byte { wxId_ := "" if len(wxId) == 0 { wxId_ = userInfo.GetUserName() } else { wxId_ = wxId[0] } ccd1 := GetCCD1(wxId_) ccd1PB, _ := proto.Marshal(ccd1) ccd2 := GetCCD2() ccd2PB, _ := proto.Marshal(ccd2) ccd3 := GetCCD3(*userInfo.DeviceInfoA16) ccd3PB, _ := proto.Marshal(ccd3) devicetoken := GetDeviceToken(userInfo.DeviceInfoA16.DeviceIdStr) dtPB, _ := proto.Marshal(devicetoken) spamdatabody := &mmproto.SpamDataBody{ Ccd1: &mmproto.SpamDataSubBody{ Ilen: proto.Uint32(uint32(len(ccd1PB))), Ztdata: ccd1, }, Ccd2: &mmproto.SpamDataSubBody{ Ilen: proto.Uint32(uint32(len(ccd2PB))), Ztdata: ccd2, }, Ccd3: &mmproto.SpamDataSubBody{ Ilen: proto.Uint32(uint32(len(ccd3PB))), Ztdata: ccd3, }, Dt: &mmproto.DeviceTokenBody{ Ilen: proto.Uint32(uint32(len(dtPB))), DeviceToken: devicetoken, }, } retData, err := proto.Marshal(spamdatabody) if err != nil { log.Info(err) } return retData } func GetCCD1(UserName string) *mmproto.ZTData { return android.AndroidWcstf(UserName) } func GetCCD2() *mmproto.ZTData { // return android.AndroidWcste(384214787666497617, 384002236977512448) return android.AndroidWcste(0, 0) } // 算法 func GetCCD3(accoutInfo baseinfo.AndroidDeviceInfo) *mmproto.ZTData { curtime := uint32(time.Now().Unix()) ccd3body := &mmproto.Ccd3Body{ KernelReleaseNumber: proto.String(accoutInfo.KernelReleaseNumber), UsbState: proto.Uint32(0), Sign: proto.String(accoutInfo.PackageSign), PackageFlag: proto.Uint32(14), AccessFlag: proto.Uint32(364604), Unkonwn: proto.Uint32(3), TbVersionCrc: proto.Uint32(553983350), SfMD5: proto.String("d001b450158a85142c953011c66d531d"), SfArmMD5: proto.String("bf7f84d081f1dffd587803c233d4e235"), SfArm64MD5: proto.String("85801b3939f277ad31c9f89edd9dd008"), SbMD5: proto.String("683e7beb7a44017ca2e686e3acedfb9f"), SoterId2: proto.String(""), TimeCheck: proto.Uint32(0), NanoTime: proto.Uint32(455583), } pb, _ := proto.Marshal(ccd3body) crc := crc32.ChecksumIEEE(pb) ccd3 := &mmproto.Ccd3{ Crc: &crc, TimeStamp: &curtime, Body: nil, } pb, _ = proto.Marshal(ccd3) // var b bytes.Buffer // w := zlib.NewWriter(&b) // w.Write(pb) // w.Close() // zt := new(android.ZT) // zt.Init() // encData := zt.Encrypt(b.Bytes()) compressData := android.DoZlibCompress(pb) encData := android.SaeEncrypt07(compressData) Ztdata := &mmproto.ZTData{ Version: proto.String("00000007\x00"), Encrypted: proto.Uint32(1), Data: encData, TimeStamp: &curtime, Optype: proto.Uint32(5), Uin: proto.Uint32(0), } // MS, _ := proto.Marshal(Ztdata) // return MS return Ztdata } func GetDeviceToken(devicetoken string) *mmproto.DeviceToken { curtime := uint32(time.Now().Unix()) return &mmproto.DeviceToken{ Version: proto.String(""), Encrypted: proto.Uint32(1), Data: &mmproto.SKBuiltinStringt{ String_: &devicetoken, }, TimeStamp: &curtime, Optype: proto.Uint32(2), Uin: proto.Uint32(0), } } func GetExtPBSpamInfoDataIpad(userInfo *baseinfo.UserInfo, wxId ...string) []byte { wxId_ := "" if len(wxId) == 0 { wxId_ = userInfo.GetUserName() } else { wxId_ = wxId[0] } retData, err := extinfo.GetCCDPbLib( userInfo.DeviceInfo.OsTypeNumber, userInfo.DeviceInfo.OsType, userInfo.DeviceInfo.UUIDTwo, userInfo.DeviceInfo.UUIDTwo, userInfo.DeviceInfo.DeviceName, userInfo.DeviceInfo.DeviceToken, hex.EncodeToString(userInfo.DeviceInfo.DeviceID), wxId_, userInfo.DeviceInfo.GUID2, ) if err != nil { log.Info(err) } return retData } func GetExtPBSpamInfoDataLogin(userInfo *baseinfo.UserInfo, wxId ...string) []byte { wxId_ := "" if len(wxId) == 0 { wxId_ = userInfo.GetUserName() } else { wxId_ = wxId[0] } retData, err := extinfo.GetCCDPbLibLogin( userInfo.DeviceInfo.OsTypeNumber, userInfo.DeviceInfo.OsType, userInfo.DeviceInfo.UUIDTwo, userInfo.DeviceInfo.UUIDTwo, userInfo.DeviceInfo.DeviceName, userInfo.DeviceInfo.DeviceToken, hex.EncodeToString(userInfo.DeviceInfo.DeviceID), wxId_, userInfo.DeviceInfo.GUID2, ) if err != nil { log.Info(err) } return retData } func GetExtPBSpamInfoDataIPhone(userInfo *baseinfo.UserInfo, wxId ...string) []byte { wxId_ := "" if len(wxId) == 0 { wxId_ = userInfo.GetUserName() } else { wxId_ = wxId[0] } retData, err := extinfo.GetCCDPbLibIPhone( userInfo.DeviceInfo.OsTypeNumber, userInfo.DeviceInfo.OsType, userInfo.DeviceInfo.UUIDTwo, userInfo.DeviceInfo.UUIDTwo, userInfo.DeviceInfo.DeviceName, userInfo.DeviceInfo.DeviceToken, hex.EncodeToString(userInfo.DeviceInfo.DeviceID), wxId_, userInfo.DeviceInfo.GUID2, ) if err != nil { log.Info(err) } return retData } // GetAutoAuthRsaReqDataMarshal 生成自动登陆rsareq项 func GetAutoAuthRsaReqDataMarshal(userInfo *baseinfo.UserInfo) []byte { var rsaReqData wechat.AutoAuthRsaReqData // AesEncyptKey var aesEncryptKey wechat.SKBuiltinString_ aesEncryptKey.Buffer = []byte(userInfo.SessionKey) var aesKeyLen = uint32(len(userInfo.SessionKey)) aesEncryptKey.Len = &aesKeyLen rsaReqData.AesEncryptKey = &aesEncryptKey // ecdh var ecdhKey wechat.ECDHKey var tmpNid = uint32(713) ecdhKey.Nid = &tmpNid // ecdhKey var ecdhKeyBuffer wechat.SKBuiltinString_ var ecdhKeyLen = uint32(len(userInfo.EcPublicKey)) ecdhKeyBuffer.Len = &ecdhKeyLen ecdhKeyBuffer.Buffer = userInfo.EcPublicKey ecdhKey.Key = &ecdhKeyBuffer rsaReqData.PubEcdhKey = &ecdhKey retData, err := proto.Marshal(&rsaReqData) if err != nil { log.Info("proto.Marshal AutoAuthRsaReqData failed: ", err) } return retData } // GetAutoAuthAesReqDataMarshal 生成自动登陆aesreq项 func GetAutoAuthAesReqDataMarshal(userInfo *baseinfo.UserInfo) []byte { var zeroUint32 = uint32(0) var emptyString = string("") var aesReqData wechat.AutoAuthAesReqData baseReq := GetBaseRequest(userInfo) var tmpScene uint32 = 2 baseReq.Scene = &tmpScene baseReq.SessionKey = []byte{} aesReqData.BaseRequest = baseReq // autoauthkey tmpAuthKeyLen := uint32(len(userInfo.AutoAuthKey)) var tmpAutoAuthKey wechat.SKBuiltinString_ tmpAutoAuthKey.Buffer = userInfo.AutoAuthKey tmpAutoAuthKey.Len = &tmpAuthKeyLen aesReqData.AutoAuthKey = &tmpAutoAuthKey // BaseAuthReqInfo var baseReqInfo wechat.BaseAuthReqInfo baseReqInfo.AuthReqFlag = &zeroUint32 baseReqInfo.AuthTicket = &emptyString aesReqData.BaseReqInfo = &baseReqInfo if userInfo.DeviceInfo == nil { //return GetManualAuthAesReqDataA16Protobuf(userInfo) aesReqData.Imei = proto.String(userInfo.DeviceInfoA16.AndriodImei(userInfo.DeviceInfoA16.DeviceIdStr)) aesReqData.SoftType = proto.String(userInfo.DeviceInfoA16.AndriodGetSoftType(userInfo.DeviceInfoA16.DeviceIdStr)) aesReqData.ClientSeqId = proto.String(fmt.Sprintf("%s_%d", userInfo.DeviceInfoA16.DeviceIdStr, (time.Now().UnixNano() / 1e6))) aesReqData.DeviceName = proto.String(userInfo.DeviceInfoA16.AndroidManufacturer(userInfo.DeviceInfoA16.DeviceIdStr) + "-" + userInfo.DeviceInfoA16.AndroidPhoneModel(userInfo.DeviceInfoA16.DeviceIdStr)) aesReqData.Language = proto.String("Zh") aesReqData.TimeZone = proto.String("8.0") aesReqData.Channel = &zeroUint32 // TimeStamp aesReqData.Signature = proto.String(userInfo.DeviceInfoA16.AndriodPackageSign(userInfo.DeviceInfoA16.DeviceIdStr)) aesReqData.BuiltinIpSeq = &zeroUint32 ext, err := GetExtSpamInfoAndroid(userInfo) if err != nil { log.Error("Android extSpam err", err.Error()) } // extSpamInfo var extSpamInfo wechat.SKBuiltinString_ extSpamInfo.Buffer = ext extSpamInfoLen := uint32(len(extSpamInfo.Buffer)) extSpamInfo.Len = &extSpamInfoLen aesReqData.ExtSpamInfo = &extSpamInfo reqData, _ := proto.Marshal(&aesReqData) return reqData } else { // imei aesReqData.Imei = &userInfo.DeviceInfo.Imei aesReqData.TimeZone = &userInfo.DeviceInfo.TimeZone aesReqData.DeviceName = &userInfo.DeviceInfo.DeviceName aesReqData.Language = &userInfo.DeviceInfo.Language aesReqData.BuiltinIpSeq = &zeroUint32 aesReqData.Signature = &emptyString aesReqData.SoftType = &userInfo.DeviceInfo.SoftTypeXML tmpTime := int(time.Now().UnixNano() / 1000000000) tmpTimeStr := strconv.Itoa(tmpTime) var strClientSeqID = string(userInfo.DeviceInfo.Imei + "-" + tmpTimeStr) aesReqData.ClientSeqId = &strClientSeqID aesReqData.Channel = &zeroUint32 // extSpamInfo var extSpamInfo wechat.SKBuiltinString_ extSpamInfo.Buffer = GetExtPBSpamInfoDataLogin(userInfo) extSpamInfoLen := uint32(len(extSpamInfo.Buffer)) extSpamInfo.Len = &extSpamInfoLen aesReqData.ExtSpamInfo = &extSpamInfo retData, err := proto.Marshal(&aesReqData) if err != nil { log.Info("proto.Marshal AutoAuthAesReqData failed: ", err) } return retData } } // GetManualAuthAesReqDataMarshal 生成自动登陆aesreq项 func GetManualAuthAesReqDataMarshal(userInfo *baseinfo.UserInfo) []byte { zeroUint32 := uint32(0) zeroInt32 := int32(0) emptyString := string("") var aesRequest wechat.ManualAuthAesReqData // BaseRequest baseReq := GetBaseRequest(userInfo) var tmpScene uint32 = 1 baseReq.Scene = &tmpScene baseReq.SessionKey = []byte{} aesRequest.BaseRequest = baseReq // imei aesRequest.Imei = &userInfo.DeviceInfo.Imei aesRequest.TimeZone = &userInfo.DeviceInfo.TimeZone aesRequest.DeviceName = &userInfo.DeviceInfo.DeviceName aesRequest.DeviceType = &userInfo.DeviceInfo.DeviceName aesRequest.Channel = &zeroInt32 aesRequest.Language = &userInfo.DeviceInfo.Language aesRequest.BuiltinIpseq = &zeroUint32 aesRequest.Signature = &emptyString aesRequest.SoftType = &userInfo.DeviceInfo.SoftTypeXML aesRequest.DeviceBrand = &userInfo.DeviceInfo.DeviceBrand aesRequest.RealCountry = &userInfo.DeviceInfo.RealCountry aesRequest.BundleId = &userInfo.DeviceInfo.BundleID aesRequest.AdSource = &userInfo.DeviceInfo.AdSource inputType := uint32(2) aesRequest.InputType = &inputType // ClientSeqId tmpTime := int(time.Now().UnixNano() / 1000000000) tmpTimeStr := strconv.Itoa(tmpTime) var strClientSeqID = string(userInfo.DeviceInfo.Imei + "-" + tmpTimeStr) aesRequest.ClientSeqId = &strClientSeqID // TimeStamp tmpTime2 := uint32(time.Now().UnixNano() / 1000000000) aesRequest.TimeStamp = &tmpTime2 // extSpamInfo var extSpamInfo wechat.SKBuiltinString_ extSpamInfo.Buffer = GetExtPBSpamInfoDataLogin(userInfo) extSpamInfoLen := uint32(len(extSpamInfo.Buffer)) extSpamInfo.Len = &extSpamInfoLen aesRequest.ExtSpamInfo = &extSpamInfo retData, err := proto.Marshal(&aesRequest) if err != nil { log.Info("proto.Marshal AutoAuthAesReqData failed: ", err) } return retData } // ParseHongBaoURL 解析红包URL func ParseHongBaoURL(hongBaoURL string, senderUserName string) (*baseinfo.HongBaoURLItem, error) { // 捕获错误返回 nil if len(hongBaoURL) == 0 { return nil, errors.New("ParseHongBaoURL hongbao url is empty") } retURL, err := url.Parse(hongBaoURL) if err != nil { return nil, err } retMaps, err := url.ParseQuery(retURL.RawQuery) if err != nil { return nil, err } //retMaps 下面可能不存在 数据,所以需要判断 if len(retMaps["msgtype"]) == 0 || len(retMaps["channelid"]) == 0 || len(retMaps["sendid"]) == 0 || len(retMaps["ver"]) == 0 || len(retMaps["sign"]) == 0 { return nil, errors.New("ParseHongBaoURL hongbao url is invalid") } retItem := &baseinfo.HongBaoURLItem{} retItem.MsgType = retMaps["msgtype"][0] retItem.ChannelID = retMaps["channelid"][0] retItem.SendID = retMaps["sendid"][0] retItem.Ver = retMaps["ver"][0] retItem.Sign = retMaps["sign"][0] retItem.SendUserName = senderUserName return retItem, nil } // CreateMediaItemXML 将mediaItem转换成XML func CreateMediaItemXML(mediaItem *baseinfo.SnsMediaItem) string { retString := string("") if mediaItem.EncKey != "" { retString = retString + "" + strconv.Itoa(int(mediaItem.EncValue)) + "" } retString = retString + "" + strconv.Itoa(int(mediaItem.ID)) + "" retString = retString + "" + strconv.Itoa(int(mediaItem.Type)) + "" // title titleString := "" if len(mediaItem.Title) > 0 { titleString = "<title>" + mediaItem.Title + "" } retString = retString + titleString // description descriptionString := "" if len(mediaItem.Description) > 0 { descriptionString = "" + mediaItem.Description + "" } retString = retString + descriptionString // private retString = retString + "" + strconv.Itoa(int(mediaItem.Private)) + "" // userData userDataString := "" if len(mediaItem.UserData) > 0 { userDataString = "" + mediaItem.UserData + "" } retString = retString + userDataString // subType retString = retString + "" + strconv.Itoa(int(mediaItem.SubType)) + "" // videoSize retString = retString + "" // url retString = retString + "" retString = retString + mediaItem.URL + "" // thumb retString = retString + "" retString = retString + mediaItem.Thumb + "" // size retString = retString + "" // videoDuration 如果是视频 if mediaItem.Type == baseinfo.MMSNSMediaTypeVideo { // 格式化 tmpValue := strconv.FormatFloat(mediaItem.VideoDuration, 'f', 6, 64) retString = retString + "" + tmpValue + "" } retString = retString + "" return retString } // CreateSnsPostItemXML 转成xml字符串,字节数组 func CreateSnsPostItemXML(userName string, postItem *baseinfo.SnsPostItem) []byte { // createTime tmpTime := int(time.Now().UnixNano() / 1000000000) tmpTimeStr := strconv.Itoa(tmpTime) // start retString := string("") retString = retString + "" retString = retString + "" retString = retString + "" retString = retString + "" retString = retString + "" retString = retString + "" retString = retString + "" + strconv.Itoa(int(postItem.Privacy)) + "" retString = retString + "" + strconv.Itoa(0) + "" retString = retString + "" + strconv.Itoa(0) + "" // location // appInfo retString = retString + "" retString = retString + "" retString = retString + "" retString = retString + "" retString = retString + "" retString = retString + "" retString = retString + "" + strconv.Itoa(0) + "" retString = retString + "" retString = retString + "" retString = retString + "" retString = retString + "" retString = retString + "" // ContentObject /*retString = retString + "" retString = retString + "" + strconv.Itoa(int(postItem.ContentStyle)) + "" retString = retString + " 习近平<title/>" retString = retString + "<description/>"*/ // location if postItem.LocationInfo != nil { // float, int 转成string longitudeStr := postItem.LocationInfo.Longitude latitudeStr := postItem.LocationInfo.Latitude poiScaleStr := strconv.Itoa(int(postItem.LocationInfo.PoiScale)) poiClassfyTypeStr := strconv.Itoa(int(postItem.LocationInfo.PoiClassifyType)) poiClickableStatusStr := strconv.Itoa(int(postItem.LocationInfo.PoiClickableStatus)) // 增加 LocationXml retString = retString + "<location " retString = retString + "city = \"" + postItem.LocationInfo.City + "\" " retString = retString + "longitude = \"" + longitudeStr + "\" " retString = retString + "latitude = \"" + latitudeStr + "\" " retString = retString + "poiName = \"" + postItem.LocationInfo.PoiName + "\" " retString = retString + "poiAddress = \"" + postItem.LocationInfo.PoiAddress + "\" " retString = retString + "poiScale = \"" + poiScaleStr + "\" " retString = retString + "poiInfoUrl = \"" + postItem.LocationInfo.PoiInfoURL + "\" " retString = retString + "poiClassifyId = \"" + postItem.LocationInfo.PoiClassifyID + "\" " retString = retString + "poiClassifyType = \"" + poiClassfyTypeStr + "\" " retString = retString + "poiClickableStatus = \"" + poiClickableStatusStr + "\" " retString = retString + "></location>" } retString = retString + "<ContentObject>" if postItem.ContentUrl != "" { retString = retString + "<contentUrl><![CDATA[" + postItem.ContentUrl + "]]></contentUrl>" } retString = retString + "<contentStyle><![CDATA[" + strconv.Itoa(int(postItem.ContentStyle)) + "]]></contentStyle>" if len(postItem.MediaList) > 0 && postItem.ContentUrl != "" { retString = retString + "<title><![CDATA[" + postItem.MediaList[0].Title + "]]> 习近平--习大大" //习近平 } else { retString = retString + " 习近平;习大大" //习近平 } if postItem.Description != "" { retString = retString + "![CDATA[" + postItem.Description + "]]>" } else { retString = retString + "" } // mediaList mediaListString := "" mediaCount := len(postItem.MediaList) if mediaCount > 0 { mediaListString = "" for index := 0; index < mediaCount; index++ { mediaListString = mediaListString + CreateMediaItemXML(postItem.MediaList[index]) } mediaListString = mediaListString + "" } retString = retString + mediaListString retString = retString + "" // end retString = retString + "" // fmt.Println(retString) return []byte(retString) } // CreateSnsMediaItem 创建媒体项 // privacy:公开/不公开 // description:描述 func CreateSnsMediaItem(snsImgResponse *baseinfo.CdnSnsImageUploadResponse, privacy uint32, description string) *baseinfo.SnsMediaItem { mediaItem := &baseinfo.SnsMediaItem{} mediaItem.ID = 0 mediaItem.Type = baseinfo.MMSNSMediaTypeImage mediaItem.Title = "" mediaItem.Description = description mediaItem.Private = privacy mediaItem.UserData = "" mediaItem.SubType = 0 mediaItem.URL = snsImgResponse.FileURL mediaItem.URLType = "1" mediaItem.Thumb = snsImgResponse.ThumbURL mediaItem.ThumType = "1" mediaItem.MD5 = snsImgResponse.ImageMD5 mediaItem.VideoMD5 = "" mediaItem.VideoWidth = strconv.Itoa(int(snsImgResponse.ImageWidth)) mediaItem.VideoHeight = strconv.Itoa(int(snsImgResponse.ImageHeight)) tmpWidth := float64(snsImgResponse.ImageWidth) tmpHeight := float64(snsImgResponse.ImageHeight) mediaItem.SizeWidth = strconv.FormatFloat(tmpWidth, 'f', 6, 64) mediaItem.SizeHeight = strconv.FormatFloat(tmpHeight, 'f', 6, 64) mediaItem.TotalSize = "0" return mediaItem } // CreateSnsCommentLikeItem 创建评论项:朋友圈点赞 func CreateSnsCommentLikeItem(itemID uint64, toUserName string) *baseinfo.SnsCommentItem { retItem := &baseinfo.SnsCommentItem{} retItem.OpType = baseinfo.MMSnsCommentTypeLike retItem.ItemID = itemID retItem.ToUserName = toUserName retItem.CreateTime = uint32(time.Now().UnixNano() / 1000000000) retItem.Content = "" retItem.ReplyCommentID = 0 retItem.ReplyItem = nil return retItem } // CreateSnsCommentItem 创建评论项:朋友圈评论 func CreateSnsCommentItem(itemID uint64, toUserName string, content string, replyComment *wechat.SnsCommentInfo) *baseinfo.SnsCommentItem { retItem := &baseinfo.SnsCommentItem{} retItem.OpType = baseinfo.MMSnsCommentTypeComment retItem.ItemID = itemID retItem.ToUserName = toUserName retItem.CreateTime = uint32(time.Now().UnixNano() / 1000000000) retItem.Content = content retItem.ReplyCommentID = 0 retItem.ReplyItem = nil // 回复 if replyComment != nil { retItem.ReplyItem = &baseinfo.ReplyCommentItem{} retItem.ReplyItem.UserName = replyComment.GetUsername() retItem.ReplyItem.NickName = replyComment.GetNickname() retItem.ReplyCommentID = replyComment.GetCommentId() retItem.ReplyItem.OpType = replyComment.GetType() retItem.ReplyItem.Source = replyComment.GetSource() } return retItem } // CreateSnsLocationInfo 创建朋友圈项: 发送朋友圈地址 func CreateSnsLocationInfo(lbsLife *wechat.LbsLife, cityName string, longitude string, latitude string) *baseinfo.SnsLocationInfo { retLocationInfo := &baseinfo.SnsLocationInfo{} retLocationInfo.City = cityName retLocationInfo.Longitude = longitude retLocationInfo.Latitude = latitude retLocationInfo.PoiName = lbsLife.GetTitle() retLocationInfo.PoiAddress = "" retLocationInfo.PoiScale = 11.0 retLocationInfo.PoiInfoURL = lbsLife.GetPoiUrl() retLocationInfo.PoiClassifyID = lbsLife.GetBid() retLocationInfo.PoiClassifyType = 1 if lbsLife.GetType() == 1 { retLocationInfo.PoiClassifyType = 2 } retLocationInfo.PoiClickableStatus = 0 return retLocationInfo } // CreateGetLbsLifeListItem 创建GetLbsLifeListItem项 func CreateGetLbsLifeListItem(longitude float64, latitude float64, buff []byte, keyWord string) *baseinfo.GetLbsLifeListItem { // 获取Lbs地址列表 lbsLifeListItem := &baseinfo.GetLbsLifeListItem{} lbsLifeListItem.Opcode = baseinfo.MMLbsLifeOpcodeNormal lbsLifeListItem.Buffer = buff lbsLifeListItem.Longitude = float32(longitude) lbsLifeListItem.Latitude = float32(latitude) lbsLifeListItem.KeyWord = keyWord return lbsLifeListItem } // CreateCDNUploadMsgImgPrepareRequest 创建 CreateCDNUploadMsgImgPrepareRequest请求 // prepareRequestItem: 请求项 func CreateCDNUploadMsgImgPrepareRequest(userInfo *baseinfo.UserInfo, prepareRequestItem *baseinfo.CDNUploadMsgImgPrepareRequestItem) []byte { var request wechat.CDNUploadMsgImgPrepareRequest var emptyString = string("") var zeroValue32 = int32(0) // FromUserName request.FromUserName = &userInfo.WxId // ToUserName request.ToUserName = &prepareRequestItem.ToUser // ClientImgId clientImgID := prepareRequestItem.ToUser + prepareRequestItem.LocalName + "_" + strconv.Itoa(int(prepareRequestItem.CreateTime)) request.ClientImgId = &clientImgID // ThumbWidth request.ThumbWidth = &prepareRequestItem.ThumbWidth // ThumbHeight request.ThumbHeight = &prepareRequestItem.ThumbHeight // encryVer request.EncryVer = &zeroValue32 // Scene request.Scene = &zeroValue32 // Crc32 request.Crc32 = &prepareRequestItem.Crc32 // Aeskey aesKey := baseutils.BytesToHexString(prepareRequestItem.AesKey, false) request.Aeskey = &aesKey // MsgForwardType msgForwardType := uint32(1) request.MsgForwardType = &msgForwardType // AttachedContent request.AttachedContent = &emptyString // Longitude longitude := float32(0.0) request.Longitude = &longitude // Latitude request.Latitude = &longitude // Source source := uint32(2) request.Source = &source // Appid request.Appid = &emptyString // MessageAction request.MessageAction = &emptyString // MessageExt request.MeesageExt = &emptyString // MediaTagName request.MediaTagName = &emptyString // 打包 srcData, _ := proto.Marshal(&request) retData := Pack(userInfo, srcData, 625, 5) return retData } // CreateSendEmojiMsgXMl 生成表情xml func CreateSendEmojiMsgXMl(md5 string, totallen int32) string { retString := strings.Builder{} retString.WriteString("") retString.WriteString("") retString.WriteString("") retString.WriteString("") retString.WriteString("8") // 发送表情 type:8 retString.WriteString("0") retString.WriteString("0") retString.WriteString("") retString.WriteString("") retString.WriteString("") retString.WriteString("") retString.WriteString("0") retString.WriteString("") retString.WriteString("") retString.WriteString("") retString.WriteString("") retString.WriteString("") retString.WriteString("") retString.WriteString("") retString.WriteString(fmt.Sprintf("%d", totallen)) retString.WriteString(fmt.Sprintf("0:0:%s", md5)) retString.WriteString(fmt.Sprintf("%s", md5)) retString.WriteString("pic") retString.WriteString("" + "" + "" + "" + "" + "" + "" + "" + "" + "0" + "" + "") return retString.String() } // CreateCDNUploadMsgImgPrepareRequestWithSource 创建 CDN 上传图片准备请求 func CreateCDNUploadMsgImgPrepareRequestWithSource(userInfo *baseinfo.UserInfo, prepareRequestItem *baseinfo.CDNUploadMsgImgPrepareRequestItem, sourceValue uint32) []byte { var request wechat.CDNUploadMsgImgPrepareRequest var emptyString = string("") var zeroValue32 = int32(0) // FromUserName request.FromUserName = &userInfo.WxId toUserName := prepareRequestItem.ToUser if toUserName == "" || toUserName == "filehelper" { toUserName = userInfo.WxId } request.ToUserName = &toUserName // ClientImgId clientImgID := toUserName + prepareRequestItem.LocalName + "_" + strconv.Itoa(int(prepareRequestItem.CreateTime)) request.ClientImgId = &clientImgID // ThumbWidth request.ThumbWidth = &prepareRequestItem.ThumbWidth // ThumbHeight request.ThumbHeight = &prepareRequestItem.ThumbHeight // encryVer request.EncryVer = &zeroValue32 // Scene request.Scene = &zeroValue32 // Crc32 request.Crc32 = &prepareRequestItem.Crc32 // Aeskey aesKey := baseutils.BytesToHexString(prepareRequestItem.AesKey, false) request.Aeskey = &aesKey // MsgForwardType msgForwardType := uint32(1) request.MsgForwardType = &msgForwardType // AttachedContent request.AttachedContent = &emptyString // Longitude longitude := float32(0.0) request.Longitude = &longitude // Latitude request.Latitude = &longitude // Source - 使用传入的值 request.Source = &sourceValue // Appid request.Appid = &emptyString // MessageAction request.MessageAction = &emptyString // MessageExt request.MeesageExt = &emptyString // MediaTagName request.MediaTagName = &emptyString // 打包 srcData, _ := proto.Marshal(&request) retData := Pack(userInfo, srcData, 625, 5) return retData }