# FAQ 常见问题
# 广告请求中的 pos.id 是什么
提示
{pos.id} 是火眼平台提供的广告位 ID,形如 A64B204EE728
# 广告返回中的{pos.id}是什么
# 广告返回中的 pos.ad_spec 如何理解
# 为什么要特殊处理广告返回中 platform_type 为 2 的情况
提示
当pos.platform_type为 2 时表示广点通的下载,广点通的下载有其独立逻辑,需要媒体主单独处理。
此外,广点通的下载广告上报事件时有一个名为 __CLICK_ID__ 的宏需要替换成真实的值。
# 第三方监测如何上报
提示
通常来说,一条第三方监测地址就是一个 url 链接,媒体主的客户端只需要通过 GET 请求触发一下即可。
如果有多条监测链接,全部通过 GET 请求触发即可。
# 什么是宏
提示
广告返回中会有很多监测事件(例如 展示上报事件),这些事件的链接上会包含一个或多个固定的字符串(例如:__WIDTH__、__HEIGHT__),这些固定格式的字符串我们称之为 宏
# 什么是宏替换
提示
将事件监测链接中的 宏,替换成真实值得过程我们称之为 宏替换
# 为什么要进行宏替换
提示
宏替换中的 宏 参数是各大平台用来衡量流量真实性的依据,本着能传尽量传的原则,希望媒体主按照真实的值进行替换,这有利于媒体主收入的提升。
需要注意的是
宏替换 必须在 客户端 准确替换才行,否则会影响媒体主的收入。
# 什么是 Deeplink
Deeplink 是通过一个链接直接跳转到已安装的应用中的某个页面的技术
常见的 deeplink 链接如下
tbopen://m.taobao.com/tbopen/index.html?&action=ali.open.nav&module=h5&bootImage=0&source=alimama&appkey=30132400&h5Url=https%3A%2F%2Fsrd.simba.taobao.com%2Ferd%3Fw%3Dunionitemjump%26f%3Dv3Ti%252Fx85Z%252B3GKe1rQbugJglvP7pI2SNqxFcw3hOCItBulAcyoTW0Em%252F3FhENbIQRI1%252FHihEei4H7yDDu%252FUovZndg%252FMpKZjQy47IBebN97vBjzjmYX%252BljVQ5W1PBqHAwmzxHTWWW0yCGLn8%252FhsK7P7kNX47DL0ffvGjOtwTMHnIEoOwhOZiyCU8haTctSDp8C0Jv%252B6Ocsv8Z1bbhz%252BwTGqU4da6Bx1ybbFMmam6ccFFx4%252BGzURd3v%252FUOyxcbHNwNzElD3OnAK4XAIEOnQ8drnkhzXMcFnfwfl77Oyt%252FWYcPXAs7sAnHoJCHhnLn7ptYTR%26k%3D5cd3316a8543165a%26pvid%3D4aa48af9fe3a4eea83b72e4a844795b6%26p%3Dmm_1029440115_1726450249_110431400352%26es%3D%26l%3D321%26bc_fl_src%3Dtunion_vipmedia_dandelion&bc_fl_src=tunion_vipmedia_dandelion
# Deeplink 为什么会唤起失败
- deeplink 只能唤起本地已安装的应用,若用户未安装 deeplink 对应的应用,则会唤起失败。
# 业界对 Deeplink 类广告是如何处理的
当返回的是 deeplink 类的广告时,媒体主有一套标准的处理流程
首先尝试通过 deeplink 唤起应用
若唤起失败(应用未安装),直接通过浏览器打开 click_link 即可。
# 常见的广告尺寸有哪些
提示
开屏
- 640*960
- 720*1280
信息流
- 480*320
- 1280*720
激励视频
- 720*1280
- 1280*720
横幅
- 640*100
# 媒体主的非标尺寸广告位如何处理通用尺寸的广告
提示
媒体主客户端自适应即可,通用尺寸已能适配市面上的大部分都机型。
# 宏 DOWN_X 和 OFFSET_X 有什么区别
提示
这两者间没有什么区别。只是不同的上游对同一种宏参数定义的名称不一样。
# 客户端无法支持所有的宏怎么办
提示
能传尽量传,实在无法获取的可以不传。
# 火眼广告返回中有文档未提及的字段怎么办
提示
媒体主以文档中提及的字段为准,不在文档中的可以不用理会。
# 火眼服务器单次广告请求的响应时长是多少
提示
正常情况下耗时平均在 200ms 左右,如果上游平台的响应变慢,则火眼平台的返回时间也会相应的增加。
# 火眼平台没有广告返回怎么办
提示
建议媒体主支持流量回流的功能,即当火眼平台无广告返回时,将流量分发给其他平台。
# WIN_PRICE 宏如何加解密
提示
秘钥请联系运营获取
加密校验
price = 100
token = UG1NudebnMTRZaLV
加密后价格 = 9be6bb522d5f2519fddc92384efe4a43
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.exception.ExceptionUtils;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
@Slf4j
public class AesECB {
private static final String KEY_ALGORITHM = "AES";
private static final String ALGORITHM = "AES/ECB/PKCS5Padding";
private static final String ENCODING = "utf-8";
private Cipher decCipher;
private Cipher encCipher;
/**
* aes构造函数
*/
public AesECB(String key) {
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), KEY_ALGORITHM);
try {
decCipher = Cipher.getInstance(ALGORITHM);
encCipher = Cipher.getInstance(ALGORITHM);
encCipher.init(Cipher.ENCRYPT_MODE, keyspec);
decCipher.init(Cipher.DECRYPT_MODE, keyspec);
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
}
}
public String encrypt(String text) {
byte[] encrypted;
try {
encrypted = encCipher.doFinal(text.getBytes(ENCODING));
return Hex.encodeHexString(encrypted);
} catch (Exception e) {
log.error(e.toString());
}
return null;
}
public String decrypt(String text) {
byte[] decrypted;
try {
decrypted = decCipher.doFinal(Hex.decodeHex(text.toCharArray()));
return new String(decrypted, ENCODING).trim();
} catch (Exception e) {
log.error(e.getMessage());
}
return null;
}
}
<?php
function encrypt($data = '', $key = NULL) {
if($key != NULL && $data != ""){
$method = "AES-128-ECB";
$encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA);
$result = bin2hex($encrypted);
return $result;
}else{
return "String to encrypt, Key is required.";
}
}
function decrypt($data="", $key = NULL) {
if($key != NULL && $data != ""){
$method = "AES-128-ECB";
$decrypted = openssl_decrypt(hex2bin($data), $method, $key, OPENSSL_RAW_DATA);
return $decrypted;
}else{
return "Encrypted String to decrypt, Key is required.";
}
}
$data = '100';
$key = 'UG1NudebnMTRZaLV';
$encrypted = encrypt($data,$key);
$decrypted = decrypt('9be6bb522d5f2519fddc92384efe4a43', $key);
print("$data 加密后 ${encrypted}\n");
print("$encrypted 解密后 ${decrypted}\n");
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"fmt"
)
type ecb struct {
b cipher.Block
blockSize int
}
func newECB(b cipher.Block) *ecb {
return &ecb{
b: b,
blockSize: b.BlockSize(),
}
}
type ecbEncrypter ecb
func NewECBEncrypter(b cipher.Block) cipher.BlockMode {
return (*ecbEncrypter)(newECB(b))
}
func (x *ecbEncrypter) BlockSize() int { return x.blockSize }
func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("crypto/cipher: input not full blocks")
}
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
for len(src) > 0 {
x.b.Encrypt(dst, src[:x.blockSize])
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
}
type ecbDecrypter ecb
func NewECBDecrypter(b cipher.Block) cipher.BlockMode {
return (*ecbDecrypter)(newECB(b))
}
func (x *ecbDecrypter) BlockSize() int { return x.blockSize }
func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("crypto/cipher: input not full blocks")
}
if len(dst) < len(src) {
panic("crypto/cipher: output smaller than input")
}
for len(src) > 0 {
x.b.Decrypt(dst, src[:x.blockSize])
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
}
func AESEncrypt(src, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
return nil
}
ecb := NewECBEncrypter(block)
content := []byte(src)
content = PKCS5Padding(content, block.BlockSize())
des := make([]byte, len(content))
ecb.CryptBlocks(des, content)
return des
}
func AesDecrypt(crypted, key []byte) []byte {
block, err := aes.NewCipher(key)
if err != nil {
return nil
}
blockMode := NewECBDecrypter(block)
origData := make([]byte, len(crypted))
blockMode.CryptBlocks(origData, crypted)
origData = PKCS5UnPadding(origData)
return origData
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
// 去掉最后一个字节 unpadding 次
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
func main() {
var v1 = "100"
var key = "UG1NudebnMTRZaLV"
var v2 = "9be6bb522d5f2519fddc92384efe4a43"
enc := AESEncrypt([]byte(v1), []byte(key))
msg := fmt.Sprintf("原始字符串: %v 加密后的结果: %v", v1, hex.EncodeToString(enc))
fmt.Println(msg)
dec, _ := hex.DecodeString(v2)
data := AesDecrypt(dec, []byte(key))
msg = fmt.Sprintf("解密字符串: %v 加密后的结果: %v", v2, string(data))
fmt.Println(msg)
}