ads_handler.go 17 KB

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