ads_handler.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/gin-gonic/gin"
  6. "hash"
  7. "math/rand"
  8. "miads/adslib"
  9. "miads/adslib/addata"
  10. "miads/adslib/ads_checker"
  11. "miads/adslib/city"
  12. "miads/adslib/device"
  13. "miads/adslib/encrypt"
  14. "miads/adslib/graylog"
  15. "miads/adslib/ip2region"
  16. "miads/adslib/redis_data"
  17. "miads/adslib/utils"
  18. "net/url"
  19. "strconv"
  20. "strings"
  21. "time"
  22. )
  23. var SECERET_KEY = "%videoopen%!@#$%"
  24. type Response struct {
  25. Result int `json:"result"`
  26. Msg string`json:"msg"`
  27. AdsResult string`json:"ads_result"`
  28. }
  29. func adsHandler(c *gin.Context) {
  30. c.Header("Content-Type", "application/json")
  31. request := Request{}
  32. request.Parse(c)
  33. //uaClientOrigin := utils.GetArgument(c, "ua","")
  34. //originMac := utils.GetArgument(c, "mac","")
  35. //clientImei := request.Imei
  36. fmt.Printf("%+v", request)
  37. advertiser := "xiaomi"
  38. uaClient := request.UaClient
  39. // 获取ua
  40. if uaClient == "" {
  41. uaClient = c.GetHeader("User-Agent")
  42. if uaClient == "" {
  43. uaClient = "Dalvik/2.1.0 (Linux; U; Android 6.0.1; MI 4LTE MIUI/6.9.1)"
  44. }
  45. }
  46. // 获取ip
  47. checkReqSourceFlag, err := ads_checker.CheckReqSource(request.ReqSource)
  48. if err != nil {
  49. c.String(404, "check req source failed")
  50. return
  51. }
  52. ip := ""
  53. if checkReqSourceFlag {
  54. ip = request.ReqSourceIp
  55. }
  56. if ip=="" {
  57. ip = c.GetHeader("X-Forwarded-For")
  58. }
  59. if ip == "" {
  60. ip = c.GetHeader("X-Real-IP")
  61. }
  62. if ip == "" {
  63. ip = c.Request.RemoteAddr
  64. }
  65. if strings.Index(ip, ",") != -1 {
  66. ip = strings.Split(ip, ",")[0]
  67. }
  68. ipInfo, err := ip2region.Ip2Region(ip)
  69. if err != nil {
  70. c.String(404, "ip 2 region failed")
  71. return
  72. }
  73. // 上報
  74. if request.NewAdsFlag == 1 {
  75. grayLogData := struct {
  76. Ip string
  77. Imei string
  78. Model string
  79. NetworkType int `json:"network_type"`
  80. Province string
  81. City string
  82. ScreeSize string `json:"screen_size"`
  83. Ua string
  84. Brand string
  85. Androidid string `json:"android_id"`
  86. ShortMessage string `json:"short_message"`
  87. ReqSource string `json:"req_source"`
  88. }{
  89. Ip: ip,
  90. Imei: request.Imei,
  91. Model: request.Model,
  92. NetworkType: request.NetworkType,
  93. Province: ipInfo.Province,
  94. City: ipInfo.City,
  95. ScreeSize: request.ScreenSize,
  96. Ua: request.UaClient,
  97. Brand: request.Brand,
  98. Androidid: request.Androidid,
  99. ShortMessage: "ads_api_log",
  100. ReqSource: "zhiku",
  101. }
  102. graylog.Log(grayLogData)
  103. }
  104. cityCode, err := city.GetCityCode(ipInfo.City)
  105. if err != nil {
  106. c.String(404, "get city code failed")
  107. return
  108. }
  109. // 是否是安卓
  110. if request.Imei =="" {
  111. device.SetAdsTagLog(advertiser, request.ReqSource, "DS_IOS", cityCode)
  112. graylog.LogApi("ios_device", request.Idfa,"", request.ReqSource)
  113. } else {
  114. device.SetAdsTagLog(advertiser, request.ReqSource,"DS_ANDRIOID", cityCode)
  115. }
  116. freqControlInterval := 600
  117. // 深圳,东莞强行用600秒控制, 其他地区从配置读取
  118. if strings.Index(ipInfo.City, "深圳")== -1 && strings.Index(ipInfo.City, "东莞")==-1 {
  119. // 频率控制
  120. freqControlConf, err := redis_data.GetFreqCrontolConf(request.ReqSource)
  121. if err != nil {
  122. c.String(404, "get freq control conf failed")
  123. return
  124. }
  125. hour, _ := strconv.Atoi(time.Now().Format("01"))
  126. tmpCrontrolInterval, ok := freqControlConf.GetControlTime(hour)
  127. if ok {
  128. freqControlInterval = tmpCrontrolInterval
  129. }
  130. }
  131. lastReqTime, err := device.GetIpReqTime(ip)
  132. if err != nil {
  133. c.String(404, "get last req time failed")
  134. return
  135. }
  136. needControl := false
  137. if request.ReqSource != "wzb_h5" && lastReqTime != 0 && time.Now().Unix() - lastReqTime < int64(freqControlInterval) {
  138. // 需要凭空
  139. needControl = true
  140. device.SetAdsTagLog(advertiser, request.ReqSource,"DS_FREQ_0", cityCode)
  141. } else {
  142. device.SetIpReqTime(ip, time.Now().Unix())
  143. device.SetAdsTagLog(advertiser, request.ReqSource,"DS_FREQ_1", cityCode)
  144. }
  145. //### 检查是否是ip黑名单
  146. isIpBlack, err := ads_checker.CheckBlackIp(ip)
  147. if err != nil {
  148. c.String(404, "get city code failed")
  149. return
  150. }
  151. if isIpBlack {
  152. graylog.LogApi("black_ip_list", ip,"", request.ReqSource)
  153. device.SetAdsTagLog(advertiser, request.ReqSource,"DS_BLACK_IP", cityCode)
  154. }
  155. // 获取渠道的黑白性
  156. reqChannelFlag, err := redis_data.GetChannelFlag(request.ReqSource,"ads_req")
  157. if err != nil {
  158. c.String(404, "get req channel flag failed")
  159. return
  160. }
  161. flowWeight := reqChannelFlag.Weigth
  162. flowRandomNum := rand.Intn(100)
  163. flowFlag := 0 // 有效的百分比
  164. if flowRandomNum <= flowWeight{
  165. flowFlag = 1
  166. }
  167. if reqChannelFlag.ChannelFlag == 1 {
  168. device.SetAdsTagLog(advertiser, request.ReqSource,fmt.Sprintf("DS_REQ_SOURCE_{%d}", reqChannelFlag.ChannelFlag), cityCode)
  169. }
  170. // 替换成小米的设备
  171. replaceFlag := 0
  172. imei := request.Imei
  173. sendPhoneType := 0
  174. userFlag := 0
  175. originImei := ""
  176. // 检查是否是小米的设备
  177. specialDeviceNum := 0
  178. if request.ReqSource == "wzb_h5" {
  179. specialDeviceNum = 6 // wzb_h5渠道只綁定一个imei, 具体愿意不知道
  180. }
  181. if request.ReqSource == "moyuntv" || (!request.IsMiDevice() &&
  182. (!isIpBlack && !needControl && reqChannelFlag.ChannelFlag ==1) && flowFlag == 1) {
  183. randomNum := 3
  184. deviceConf, realRedisKey, err := device.GetMiDeviceConf(ip, randomNum, specialDeviceNum)
  185. if err != nil {
  186. c.String(404, "get req channel flag failed")
  187. return
  188. }
  189. if deviceConf != nil {
  190. device.SetAdsTagLog(advertiser, request.ReqSource, "DS_CACHE", cityCode) // 通过缓存请求
  191. imei = deviceConf.Imei
  192. uaClient = deviceConf.Ua
  193. originImei = deviceConf.OriginImei
  194. if imei != "" {
  195. replaceFlag = 1
  196. userFlag = 1
  197. }
  198. } else {
  199. // 先从对应的城市找,找不到在走原来的逻辑
  200. // 上报事件
  201. graylog.LogApi("city_search_city_code", strconv.Itoa(cityCode), ipInfo.City, request.ReqSource)
  202. device.SetAdsTagLog(advertiser, request.ReqSource, "DS_CODE_REQ", cityCode) // 可做城市替换
  203. if cityCode != 0 {
  204. device.SetAdsTagLog(advertiser, request.ReqSource, "DS_CODE", cityCode) // 替换成功
  205. fakeImei := ""
  206. fakeDeviceConf, leftCnt, err := device.GetDailyFakeDeviceConfByCityCode(cityCode)
  207. if err != nil {
  208. c.String(404, "get device conf failed")
  209. return
  210. }
  211. // 0 没有获取到, 1 获取到了
  212. gotCityFakeDeviceConfFlag := 0
  213. replaceUa := ""
  214. if fakeDeviceConf != nil {
  215. device.SetAdsTagLog(advertiser, request.ReqSource, "DS_REPL", cityCode)
  216. device.SetMiDeviceConf(realRedisKey, *fakeDeviceConf)
  217. imei = fakeDeviceConf.Imei
  218. uaClient = fakeDeviceConf.Ua
  219. originImei = fakeDeviceConf.OriginImei
  220. fakeImei = fakeDeviceConf.Imei
  221. if fakeDeviceConf.Imei != "" {
  222. gotCityFakeDeviceConfFlag = 1
  223. userFlag = 2
  224. replaceFlag = 1
  225. }
  226. }
  227. grayLogData := struct {
  228. ReqSource string `json:"req_source"`
  229. OldImei string `json:"old_imei"`
  230. NewImei string `json:"new_imei"`
  231. IP string `json:"ip"`
  232. City string `json:"city"`
  233. CityCode int `json:"city_code"`
  234. Province string
  235. HitFlag int `json:"hit_flag"`
  236. LeftCnt int `json:"left_cnt"`
  237. ReplaceUa string `json:"replace_ua"`
  238. ShortMessage string `json:"short_message"`
  239. }{
  240. ReqSource: request.ReqSource,
  241. OldImei: request.Imei,
  242. NewImei: fakeImei,
  243. IP: ip,
  244. City: ipInfo.City,
  245. CityCode: cityCode,
  246. Province: ipInfo.Province,
  247. HitFlag: gotCityFakeDeviceConfFlag,
  248. LeftCnt: leftCnt,
  249. ReplaceUa: replaceUa,
  250. ShortMessage: "",
  251. }
  252. // 进行日志的上报
  253. graylog.Log(grayLogData)
  254. }
  255. }
  256. // 解码ua_client
  257. uaClient, _ = url.QueryUnescape(uaClient)
  258. } else if request.IsMiDevice() {
  259. device.SetAdsTagLog(advertiser, request.ReqSource,"DS_MI_REAL", cityCode) // 是小米设备
  260. userFlag = 3
  261. sendPhoneType = 1
  262. }
  263. // 检查下,替换后的设备是否是黑名单, 再次检查, 防止放入cache后, 新增了黑名单
  264. isBlackImei, err := device.CheckIsBlackImei(imei, false)
  265. if err != nil {
  266. c.String(404, "get device conf failed")
  267. return
  268. }
  269. if isBlackImei {
  270. if replaceFlag == 1 {
  271. device.SetAdsTagLog(advertiser, request.ReqSource, "DS_BLACK_IMEI_REPLACE", cityCode)
  272. } else {
  273. device.SetAdsTagLog(advertiser, request.ReqSource,"DS_BLACK_IMEI", cityCode)
  274. }
  275. }
  276. // 组装公共的dsp_info
  277. dspInfo := utils.DspParam{}
  278. dspInfo.Init()
  279. dspInfo.DspCityCode = cityCode
  280. dspInfo.Imei = imei
  281. dspInfo.OriginImei = request.Imei
  282. dspInfo.OsVersion = request.OsVersion
  283. dspInfo.Mac = strings.ToUpper(request.Mac)
  284. dspInfo.OriginMac = request.Mac
  285. dspInfo.Idfa = request.Idfa
  286. dspInfo.Model = request.Model
  287. dspInfo.Brand = request.Brand
  288. dspInfo.ScreenSize = request.ScreenSize
  289. dspInfo.NetworkType = request.NetworkType
  290. dspInfo.Androidid = request.Androidid
  291. dspInfo.Platform = request.Platform
  292. dspInfo.Ip = ip
  293. dspInfo.Ua = uaClient
  294. dspInfo.City = ipInfo.City
  295. dspInfo.Province = ipInfo.Province
  296. dspInfo.UaOrigin = request.UaClient
  297. dspInfo.ReqSource = request.ReqSource
  298. if request.IsMiDevice() {
  299. dspInfo.RealMiFlag = 1
  300. }
  301. dspInfo.ReplaceFlag = replaceFlag
  302. dspInfo.RealReqSource = request.ReqSource
  303. dspInfo.SendPhoneType = sendPhoneType
  304. md5Imei := imei
  305. if dspInfo.ReplaceFlag == 0 {
  306. md5Imei = utils.Md5(imei)
  307. }
  308. dspInfo.RealMd5Imei = md5Imei
  309. //response = {'result': 0, 'msg': 'ok','ads_result':''}
  310. //ads_item = None
  311. //xiaomi_response = []
  312. hour, _ := strconv.Atoi(time.Now().Format("01"))
  313. canRequest := true
  314. if 0 <= hour && hour <=1 {
  315. randNum := rand.Intn(100)
  316. if randNum > 5 {
  317. canRequest = false
  318. }
  319. }
  320. var adData *addata.AdData
  321. var xiaomiResponse []addata.XiaomiAdData
  322. xiaomiRspAction := make(map[string]int, 100)
  323. var adDataNum int
  324. // 非频率控制,设备黑名单,ip黑名单,白名单渠道,并且替换了小米设备的
  325. if canRequest && !isBlackImei && reqChannelFlag.ChannelFlag == 1 && flowFlag ==1 && !isIpBlack && advertiser == "xiaomi" && request.ReqSource != "" && !isBlackImei && !needControl && (replaceFlag==1 || request.IsMiDevice()) {
  326. adData, xiaomiResponse, xiaomiRspAction, adDataNum, err = addata.GetAdsInfos(&dspInfo, advertiser)
  327. }
  328. canMixFlag := 0
  329. xiaomiResponseFlag := 0
  330. response := Response{}
  331. if adData != nil && len(adData.TargetAddition) > 1 {
  332. realTarget := ""
  333. if adData.Target != ""{
  334. md5Skip := utils.Md5(addata.Target)
  335. conf := adslib.GetConf()
  336. realTarget = conf.Host + fmt.Sprintf("?action=LOADING&req_source=%s&advertiser=video&skip=%s&brand=%s&request_id=%s&skip_other=%s",
  337. dspInfo.ReqSource, "", dspInfo.Brand, dspInfo.RequestId, md5Skip)
  338. // 塞入Redis中
  339. redis_data.SetSkipInfo(md5Skip, adData.Target)
  340. }
  341. adData.Target = realTarget
  342. adData.JsOrderId, _ = redis_data.GetMinScriptOrderByAdv(advertiser)
  343. adData.UserAgent = uaClient
  344. if dspInfo.ReqSource =="kuxin" && adData.Target != "" {
  345. adData.DpReport = fmt.Sprintf("%s?action=DP_CLICK&advertiser=video&req_source=%s", common.get_request_host(None), dspInfo.ReqSource)
  346. adData.Dp = adslib.GetConf().DpTest
  347. }
  348. if dspInfo.SendPhoneType == 0 {
  349. device.SetAdsTagLog(advertiser,dspInfo.ReqSource,"ADS_GET", cityCode) // 广告获取成功
  350. } else if dspInfo.SendPhoneType==1 {
  351. device.SetAdsTagLog(advertiser,dspInfo.ReqSource,"ADS_GET_1", cityCode) // 广告获取成功
  352. }
  353. device.SetAdsTagLog(advertiser, dspInfo.ReqSource, fmt.Sprintf("ADS_USER_%d", userFlag), cityCode) // 广告类型,缓存,新用户,小米手机
  354. // 判断这个渠道是否要去融合和融合的流量占比
  355. mixChannelFlag, err := redis_data.GetChannelFlag(dspInfo.ReqSource, "ads_mix")
  356. if err != nil {
  357. c.String(404, "get device conf failed")
  358. return
  359. }
  360. flowRandomNum = rand.Intn(100)
  361. isOverFlow := false
  362. //flow_flag = 0
  363. if flowRandomNum > mixChannelFlag.Weigth {
  364. isOverFlow = true
  365. }
  366. if mixChannelFlag.ChannelFlag !=1 || isOverFlow {
  367. //extra_infos = []
  368. }
  369. // 组装返回去的action
  370. serverActionResponse := map[string]int{"server_view":0,"server_click":0,"server_close":0,"server_video_finish":0,"server_video_timer":0}
  371. for _, targetInfo := range adData.TargetAddition {
  372. if targetInfo.Type == "VIEW" {
  373. serverActionResponse["server_view"]=1
  374. redis_data.SetReqSourceView(advertiser, dspInfo.ReqSource,"xiafa")
  375. } else if targetInfo.Type == "CLICK" {
  376. serverActionResponse["server_click"]=1
  377. } else if targetInfo.Type=="CLOSE" {
  378. serverActionResponse["server_close"]=1
  379. } else if targetInfo.Type=="VIDEO_FINISH" {
  380. serverActionResponse["server_video_finish"]=1
  381. } else if targetInfo.Type =="VIDEO_TIMER" {
  382. serverActionResponse["server_video_timer"]=1
  383. }
  384. }
  385. // 增加跟随订单
  386. if len(adData.TargetAddition) == 2 && serverActionResponse["server_video_finish"] == 1 && (dspInfo.ReqSource == "kuxin" || dspInfo.ReqSource == "zhiku") {
  387. adData, err = addata.CombineOrderBy(adData, advertiser, &dspInfo)
  388. if err != nil {
  389. return err
  390. }
  391. }
  392. //# 检查最后是否有click
  393. //last_target_addition_infos = ads_item_new.get('target_addition',[])
  394. for _, targetAddition := range adData.TargetAddition {
  395. if targetAddition.Type =="CLICK" || targetAddition.Type == "VIDEO_TIMER" {
  396. canMixFlag = 0
  397. break
  398. }
  399. }
  400. if request.NewAdsFlag==0 {
  401. //response.update(ads_item_new)
  402. } else {
  403. jsonBytes, err := json.Marshal(*adData)
  404. if err != nil {
  405. return err
  406. }
  407. encryptData, _ := encrypt.Encrypt(jsonBytes, []byte(SECERET_KEY))
  408. response.AdsResult = encryptData
  409. }
  410. hour, _ := strconv.Atoi(time.Now().Format("01"))
  411. if 0 <= hour && hour <=23 && replaceFlag ==1 {
  412. randomNum := utils.Hash(imei) % 10000
  413. if randomNum < 3000 {
  414. //add_beanstalk_response.BeanstalkHandle().add_ads_response_info(md5_imei,ads_ip,web.utf8(province),web.utf8(city),ads_item_new,dsp_city_code,req_source,real_imei,xiaomi_response,xiaomi_action,server_action_response,dsp_info.request_id,xiaomi_ads_data_num)
  415. }
  416. }
  417. }
  418. if canMixFlag==1 {
  419. response.Result = 2
  420. response.Msg = "no ads"
  421. if xiaomiResponseFlag==1 {
  422. response.Result = 0
  423. response.Msg = "ok"
  424. }
  425. // 增加打底广告
  426. if (dspInfo.ReqSource == "kuxin" || dspInfo.ReqSource == "zhiku") && !needCotrol ==1 && !isBlackImei {
  427. shortMessage := "kong"
  428. // 先跑定投
  429. customAdData, err := addata.GetCustomAdsInfos(&dspInfo, advertiser, 0, 0, xiaomiResponseFlag)
  430. if err != nil {
  431. return err
  432. }
  433. // 定投没有就跑其他的
  434. if customAdData == nil {
  435. customAdData, err = addata.GetCustomAdsInfos(&dspInfo, advertiser, 0, 1, xiaomiResponseFlag)
  436. if err != nil {
  437. return err
  438. }
  439. }
  440. device.SetAdsTagLog(advertiser, dspInfo.ReqSource,"ADS_ZIYOU_GET", cityCode) // 广告获取成功
  441. if customAdData != nil {
  442. shortMessage = "ads_tt_thirds"
  443. }
  444. if customAdData != nil && (shortMessage == "ads_vast_response" || shortMessage == "ads_tt_thirds") {
  445. //response_data_report = {}
  446. //response_data_report['ip'] = ads_ip
  447. //response_data_report['short_message'] = short_message
  448. //response_data_report['req_source'] = req_source
  449. //response_data_report['response_vast'] = json.dumps(extra_item)
  450. //response_data_report['order_name']=order_name
  451. //response_data_report['advertiser']=advertiser
  452. //log.send_to_graylog_tornado(gelf_data=response_data_report)
  453. adDataBytes, err :=
  454. grayLogData := struct {
  455. Ip string
  456. ShortMessage string `json:"short_message"`
  457. ReqSource string `json:"req_source"`
  458. ResponseVast string `json:"response_vast"`
  459. OrderName string `json:"order_name"`
  460. Advertiser string `json:"advertiser"`
  461. }{
  462. Ip: ip,
  463. ShortMessage: "ads_api_log",
  464. ReqSource: "zhiku",
  465. ResponseVast: ""
  466. OrderName: customAdData.OrderName,
  467. Advertiser: advertiser,
  468. }
  469. graylog.Log(grayLogData)
  470. }
  471. //if short_message=="ads_tt_thirds":
  472. //from thirds import thirds_mix_xiaomi
  473. //extra_item = thirds_mix_xiaomi.mix_last_infos(extra_item,response)
  474. //if (extra_item) != None:
  475. //redis_device.set_ads_tag_log(advertiser,req_source,'ADS_ZIYOU_HAVE',dsp_city_code) # 广告获取成功
  476. //if req_source in ['zhiku']:
  477. //response['result']=0
  478. //response['msg']='ok'
  479. //response['ads_result']= self.prpcrypt_tools.to_encrypt_content(json.dumps(extra_item))
  480. //self.report_graylog(json.dumps(extra_item))
  481. //self.write(json.dumps(response))
  482. //self.finish()
  483. //return
  484. //else:
  485. //extra_item['result']=0
  486. //extra_item['msg']="ok"
  487. //json_response = json.dumps(extra_item)
  488. //self.report_graylog(json_response)
  489. //self.write(json_response)
  490. //self.finish()
  491. //return
  492. }
  493. }
  494. //redis_tools.set_ads_real_request_num(advertiser)
  495. //json_response = json.dumps(response)
  496. //try:
  497. //if new_ads_flag==0:
  498. //self.report_graylog(json_response)
  499. //redis_device.set_ads_tag_log(advertiser,req_source,'DS_REQ',dsp_city_code) # 所有请求
  500. //except:
  501. //pass
  502. //self.write(json_response)
  503. //self.finish()
  504. c.String(200, "hehe")
  505. }