#!/usr/bin/python # -*- coding: utf-8 -*- # ##@package # # @todo: 基于头条广告API对接广告点击 激活 注册 付费信息交互 # # @author: Alee # @date 2018-5-4 22:10:51 # @version 1.0 # # @note: 中文必须传utf8,收到的为urlencode内容 .decode('gbk').encode('utf8') # !!!注意大小写区分 # #--------------------------------------------------------------------- from bottle import Bottle, request from lib import mylog, CommFunc import ADDB import json import md5 import time myapp = Bottle() Def_URLPARAM_STR = "__" # 参数两边用两个下划线包裹 #==================== # 参数adid cid timestamp callback_url mac1 ua1 idfa androidid1 imei ip #==================== #center.secondworld.net.cn:53004/ad/feedback/2001?adid=__AID__&cid=__CID__&csite=__CSITE__&ctype=__CTYPE__&mac1=__MAC1__&ua1=__UA1__&androidid1=__ANDROIDID1__&imei=__IMEI__&os=__OS__&ip=__IP__&ts=__TS__&callback_url=__CALLBACK_URL__ #接口1 # 点击广告记录,通过广告ID、包体ID和唯一标识(IMEI或MAC等)匹配对应后续的激活注册付费操作 # 情况1-重复:同一用户多次点击同一个广告ID下载 # 情况2-重复:同一用户多次点击不同广告ID下载 # 情况3-无点击: 不是从广告进入的用户 @myapp.route('/ad/feedback/:packid') def ADFeedback(packid): getDict = request.GET #print "---------" for key in getDict: mylog.debug("feedback: %s-%s"%(key, getDict[key])) adid = getDict.get("adid", "") if not adid: mylog.error("no adid") return json.dumps({"status":-1}, ensure_ascii=False) if adid == "__AID__": return dbController = ADDB.GetDBEventCon() if not dbController: # 无法获取数据库 mylog.debug("no dbController") return json.dumps({"status":-1}, ensure_ascii=False) #adid 和 包ID为唯一标识 result, findDict = FindUserFromAD(dbController, getDict, packid, adid) mylog.debug("result:%s-%s"%(result, findDict)) newDict = {"adid":adid} # 广告计划ID newDict["cid"] = getDict.get("cid", "") # 广告创意ID newDict["csite"] = getDict.get("csite", "") # 广告投放位置 newDict["ctype"] = getDict.get("ctype", "") # 创意样式 newDict["mac1"] = getDict.get("mac1", "") # 入网硬件地址 eth0 MAC md5 newDict["ua1"] = getDict.get("ua1", "") # user-agent newDict["idfa"] = getDict.get("idfa", "") # 苹果的idfa newDict["androidid1"] = getDict.get("androidid1", "") newDict["imei"] = getDict.get("imei", "") # md5 newDict["os"] = getDict.get("os", "") newDict["ip"] = getDict.get("ip", "") newDict["ts"] = int(getDict.get("ts", time.time()*1000)) # 时间戳毫秒 点击和激活最长7天 newDict["callback_url"] = getDict.get("callback_url", "") newDict["packid"] = packid #包ID if not result: newDict["clickcnt"] = 1 # 重复点击数 newDict["event_type"] = 0 #插入新数据 dbController.insert(ADDB.AdColName, newDict) else: # 更新数据 newDict["clickcnt"] = result[0].get("clickcnt", 0) + 1 # 重复点击数 newDict["event_type"] = result[0].get("event_type", 0) dbController.update(ADDB.AdColName, findDict, newDict) return json.dumps({"status":0}, ensure_ascii=False) #center.secondworld.net.cn:53004/ad/eventtype/包id?mac1=xxx....event_type=0 # 客户端激活 注册 付费 # MAC1 UA IDFA ANDROIDID1 IMEI IP event_type @myapp.route('/ad/eventtype/:packid') def ClientActive(packid): getDict = request.GET #print "---------" for key in getDict: mylog.debug("ClientActive: %s-%s"%(key, getDict[key])) mylog.info("ClientActive - IMEI:%s ANDROIDID1: %s event_type: %s"%( getDict.get("IMEI", ""), getDict.get("ANDROIDID1", ""), getDict.get("event_type", ""))) event_type = getDict.get("event_type", "") if event_type == "": mylog.error("no event_type") return event_type = CommFunc.ToIntDef(event_type, 0) dbController = ADDB.GetDBEventCon() if not dbController: # 无法获取数据库 mylog.debug("no dbController") return # 理论上adid和packid是唯一对应,此处最多只能找到一个 result, findDict = FindUserFromClient(dbController, getDict, packid) if not result: # 非广告用户 return if len(result) > 1: mylog.warn("more result:%s-%s"%(len(result), findDict)) dbEvent = result[0]['event_type'] clientEvent = pow(2, event_type) if dbEvent&clientEvent != 0: # 已设置过,不处理 return if dbEvent == 0 and event_type > 0: # 未设置过激活不设置注册和付费 return callback_url = result[0]['callback_url'] # 发送给头条广告 try: result = CommFunc.DoGet(callback_url + "&event_type=%s"%event_type) except: mylog.warn("toutiao no answer") result = None if result: resultDict = json.loads(result) mylog.debug("%s"%resultDict) if resultDict.get("ret", -1) == 0: dbController.update(ADDB.AdColName, findDict, {"$set":{'event_type':dbEvent|clientEvent}}) return @myapp.route('/ad/getip') def GetIP(): return request.environ.get("REMOTE_ADDR", "0.0.0.0") # !!!注意大小写区分 # 同类型手机在同wifi网络下 ip和ua可能相同,放最后判断 def FindUserFromAD(dbController, getDict, packid, adid): if "idfa" in getDict: # 苹果 if getDict.get("idfa", ""): findDict = {"adid":adid, "packid":packid, "idfa":getDict.get("idfa", "")} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict if getDict.get("mac1", ""): findDict = {"adid":adid, "packid":packid, "mac1":getDict.get("mac1", "")} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict if (getDict.get("ip", "") and getDict.get("ua1", "")): findDict = {"adid":adid, "packid":packid, "ip":getDict.get("ip", ""), "ua1":getDict.get("ua1", "")} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict else: # 安卓 if getDict.get("imei", ""): findDict = {"adid":adid, "packid":packid, "imei":getDict.get("imei", "")} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict if getDict.get("androidid1", ""): findDict = {"adid":adid, "packid":packid, "androidid1":getDict.get("androidid1", "")} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict if getDict.get("mac1", ""): findDict = {"adid":adid, "packid":packid, "mac1":getDict.get("mac1", "")} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict if (getDict.get("ip", "") and getDict.get("ua1", "")): findDict = {"adid":adid, "packid":packid, "ip":getDict.get("ip", ""), "ua1":getDict.get("ua1", "")} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict return None, None # MAC1 UA IDFA ANDROIDID1 IMEI IP event_type # !!!注意大小写区分 # 同类型手机在同wifi网络下 ip和ua可能相同,放最后判断 def FindUserFromClient(dbController, getDict, packid): intime = int(time.time()*1000 - 7*24*60*60*1000) # 查找7天内的数据 if "IDFA" in getDict: # 苹果 if getDict.get("IDFA", ""): findDict = {"packid":packid, "idfa":getDict.get("IDFA", ""), "ts":{'$gt':intime}} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict if getDict.get("MAC1", ""): findDict = {"packid":packid, "mac1":md5.md5(getDict.get("MAC1", "")).hexdigest(), "ts":{'$gt':intime}} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict if (getDict.get("IP", "") and getDict.get("UA", "")): findDict = {"packid":packid, "ip":getDict.get("IP", ""), "ua1":getDict.get("UA", ""), "ts":{'$gt':intime}} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict else: # 安卓 if getDict.get("IMEI", ""): findDict = {"packid":packid, "imei":md5.md5(getDict.get("IMEI", "")).hexdigest(), "ts":{'$gt':intime}} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict if getDict.get("ANDROIDID1", ""): findDict = {"packid":packid, "androidid1":getDict.get("ANDROIDID1", ""), "ts":{'$gt':intime}} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict if getDict.get("MAC1", ""): findDict = {"packid":packid, "mac1":md5.md5(getDict.get("MAC1", "")).hexdigest(), "ts":{'$gt':intime}} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict if (getDict.get("IP", "") and getDict.get("UA", "")): findDict = {"packid":packid, "ip":getDict.get("IP", ""), "ua1":getDict.get("UA", ""), "ts":{'$gt':intime}} result = dbController.find(ADDB.AdColName, findDict) if result[1]: return result[1], findDict return None, None