最近对接了百度信息流广告,将对接流程记录如下:
业务需求:通过用户点击广告, 获取用户信息,统计有用户信息
实现原理:
*.用户点击百度app中的广告
*.百度app记录手机用户点击事件,信息,并将用户信息传给百度服务器
*.百度服务器回调广告主事先在百度监控平台设置好的url(广告主自己开发)
*.广告主url获取用户点击事件,根据请求参数,来匹配用户的转换数据(应用激活)
*.广告主将匹配陈宫的转换数据拼接后
*.使用callback_rul,将数据回传到百度
*.百度后台会显示数据上传成功的界面
*.结束
业务流程如下:
具体接口文档很清楚,就不多说:
接口 文档地址: http://ocpc.baidu.com/developer/ocpc-doc/app/app-interface/README1.html
回调地址文档:http://ocpc.baidu.com/developer/ocpc-doc/app/app-interface/README1.html#callbackUrl
需要注意地方:
1.百度推广后台回调监测 URL,即feedback url(由广告主自行开发)
2.广告主将匹配成功的转化数据与广告点击数据进行拼接,使用callback_url将数据回传给百度
3.广告主需要将url,在百度监控后台设置好(就是广告主的应用发布地址)
4.用户扫描对应的二维码
5.返回到推荐页面,轻轻刷一下推荐,然后 往下拉,找到百度测试广告的链接
6.点击广告测试广告的链接 (7.点击后,百度会回调个广告主的的应用,然后,点击后,百度会回调个广告主的的应用)
7.然后百度后台,会提示:数据上传中,
8.数据上传成功(=如果一直是数据上传中,没有上传成功,那么就要检查应用的配置,代码的设置)
注意:如果你调用feedback函数,的请求参url错了,如:sign,没有进行md5加密,或者没有sign参数,百度也会显示回调成功(error_code=0)
这个时候,数据一直是上传中。需要调整代码
百度监测中心:
设置url地方:工具中心->转换追踪->新建
数据上传成功后的截图:
调试的时候,elk的记录
百度推广回调广告主代码逻辑:
private static string Okey = "";
public AdChannelNotice Notify(ushort behaviorType, HttpRequest request)
{
var qs = request.Query;
var os = ParseOs(qs["os"]);
var idfa = qs["idfa"];
var imeiMd5 = qs["imei_md5"];
var timestamp = qs["ts"];
var id = qs["ip"];
var uid = qs["uid"];
var raw = request.QueryString.ToString();
return new AdChannelNotice
{
AdId = uid,
Idfa = idfa,
AndroidIdMd5 = "",
ImeiMd5 = imeiMd5,
Os = os,
Raw = raw,
Time = TimestampHelper.FromTimestamp(timestamp)
};
}
private ushort ParseOs(string os)
{
switch (os)
{
case "1": return MobileOs.Ios;
case "2": return MobileOs.Android;
default: return 1;
}
}
广告主拼接数据后,将数据md5后给到百度广告主
代码逻辑:
public async Task Feedback(ushort channelId, ushort typeId, string raw)
{
var parameter = QueryHelpers.ParseQuery(raw);
if (parameter == null)
{
_logger.Info($"Tuhu.Marketing.RealTime->BaiduAd->Feedback 获取Feedback参数失败,raw:{raw},channelId:{channelId},typeId:{typeId}");
return;
}
var callbackUrl = parameter["callback_url"];
var url = BuildCallBackUrl(callbackUrl);
await SendBaiduMessage(channelId, url);
}
private async Task SendBaiduMessage(ushort channelId, string url)
{
_logger.Info($"Tuhu.Marketing.RealTime->BaiduAd->Feedback 百度,请求参数,channelId:{channelId},url:{url}");
var responseMessage = await HttpClient.GetAsync(url);
var details = await responseMessage.Content.ReadAsStringAsync();
if (!responseMessage.IsSuccessStatusCode) throw new Exception($"Tuhu.Marketing.RealTime->BaiduAd->Feedback->error occured when feedback to channel {channelId} , details:{details}");
if (responseMessage.StatusCode == HttpStatusCode.OK)
{
_logger.Info($"Tuhu.Marketing.RealTime->BaiduAd->Feedback 百度,返回成功,Message:{details}");
var jObj = JsonConvert.DeserializeObject<JObject>(details);
var code = jObj.Value<int>("error_code");
if (code != 0) _logger.Error($"Tuhu.Marketing.RealTime->BaiduAd->Feedback 百度,服务器错误,Code:{code},Message:{details}");
}
}
private static string BuildCallBackUrl(Microsoft.Extensions.Primitives.StringValues callbackUrl)
{
var url = HttpUtility.UrlDecode(callbackUrl, Encoding.UTF8);
url = url.Replace("{{ATYPE}}", "activate");
url = url.Replace("{{AVALUE}}", "0");
var sign = ToMd5($"{url}{Okey}");
url = $"{url}&sign={sign}";
return url;
}
/// <summary>
/// 字符串加密Md5
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private static string ToMd5(string str)
{
StringBuilder sb = new StringBuilder(32);
MD5 md5 = new MD5CryptoServiceProvider();
byte[] t = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
for (int i = 0; i < t.Length; i++)
{
sb.Append(t[i].ToString("x2"));
}
return sb.ToString();
}
private static class HttpUtility
{
/// <summary>
/// 对 URL 字符串进行编码
/// </summary>
/// <param name="str">字符串</param>
/// <returns>编码结果</returns>
public static string UrlEncode(string str, Encoding e)
{
return System.Web.HttpUtility.UrlEncode(str, e);
}
/// <summary>
/// 将已经为在 URL 中传输而编码的字符串转换为解码的字符串
/// </summary>
/// <param name="str">字符串</param>
/// <returns>解码结果</returns>
public static string UrlDecode(string str, Encoding e)
{
return System.Web.HttpUtility.UrlDecode(str, e);
}
}