腾讯广告小游戏 SDK 开发指引
腾讯广告小游戏 SDK 为广告主提供了一种新的数据接入方式,数据上报更为便捷且时效性更高,助力提升您的广告投放效果。目前支持微信原生小游戏及采用 CocosCreator、Egret、LayaAir 游戏引擎开发的微信小游戏( Unity 开发的小游戏如能支持 JS 也可使用此 SDK )。
SDK名称:腾讯广告小游戏 SDK
开发者:深圳市腾讯计算机系统有限公司
版本号:1.5.4
主要功能:为开发者提供广告投放、广告归因、广告效果优化的基本功能
合规使用说明:https://datanexus.qq.com/doc/develop/compliance/minigame/compliance_guide
隐私政策:https://datanexus.qq.com/doc/develop/compliance/minigame/privacy_policy
1 前置条件
1.1 完成 SDK 接入流程文档阅读
查看 SDK 接入流程。
1.2 添加 SDK 安全域名
为了保障小游戏的数据采集和发送成功,需要在对应小游戏后台的开发设置中,将SDK的后端域名 https://api.datanexus.qq.com
添加为request 合法域名。以微信小游戏后台的操作为例,具体步骤如下:
登录微信公众平台,进入【开发】 -> 【开发设置】-> 【服务器域名】。
首次配置点击服务器域名模块中【开始配置】按钮,追加域名点击【修改】按钮,打开【配置服务器域名】弹窗。
在 request 合法域名中将 `https://api.datanexus.qq.com `添加为 request 合法域名。
2 下载 SDK
方式1:通过 npm 下载和引用
npm i @dn-sdk/minigame
import { SDK } from '@dn-sdk/minigame';
如果游戏引擎不支持 npm 包引入可以从 node_modules 拷贝 @dn-sdk/minigame/build 文件夹到项目中引用,这样可以获得更好的代码提示。
方式2:通过链接下载
下载 SDK,下载的压缩包 dn-sdk-minigame.zip 中包含 index.js 文件和 index.d.ts 类型声明文件,导入整个文件夹可以获得更好的代码提示。假设将解压后的 dn-sdk-minigame 文件夹放到根目录下的 lib 文件夹中,可以这样引用:
import { SDK } from './lib/dn-sdk-minigame/index.js';
3 引用 SDK 并完成初始化
请尽早初始化 SDK,避免数据丢失。建议通过 require 或 import 引入 SDK 后,立即调用 new SDK() 方法生成实例完成初始化 。
3.1 原生小游戏
import { SDK } from '@dn-sdk/minigame';
// 是否打开调试模式, 建议仅在调试期间开启
SDK.setDebug(true);
const sdk = new SDK({
// 数据源 ID,数字,必填
user_action_set_id: 'your_user_action_set_id',
// 加密 key,必填
secret_key: 'your_secret_key',
// 微信小游戏 APPID,wx开头,必填
appid: 'wx123xyz123xyz123x',
});
初始化参数
参数 | 类型 | 必填 | 描述 | 示例值 |
---|---|---|---|---|
user_action_set_id | number | 是 | 行为数据源ID | 100001 |
secret_key | string | 是 | 加密密钥 | 5e853xxxxxxd57a690xxxxxxxxxx |
appid | string | 是 | 微信小游戏 appid | wx123xyz123xyz123x |
auto_track | boolean | 否 | 是否开启自动采集,默认开启 | true |
openid | string | 否 | 初始化时无需设置,请参考步骤3.2.3,调用setOpenId方法设置,openid 和 unionid 只需设置一个,优先使用openid | 获取openid |
unionid | string | 否 | 初始化时无需设置,请参考步骤3.2.3,调用 setUnionId方法设置,没有 openid时才需要unionid | 获取unionid |
user_unique_id | string | 否 | 非必填,业务自定义的用户ID |
本 SDK 将直接收集本服务所需的必选信息;同时,开发者可以在初始化时自行配置参数,决定是否授权同意本SDK 收集可选信息,或选择自行向本 SDK 提供可选信息。
3.2 LayaAir
import { SDK } from '@dn-sdk/minigame/build/index';
// import { SDK } from './lib/dn-sdk-minigame.min.js';
const { regClass, property } = Laya;
@regClass()
export class Main extends Laya.Script {
onStart() {
new SDK({
appid: 'wx123xyz123xyz123x',
user_action_set_id: 'your_user_action_set_id',
secret_key: '5e853xxxxxxxxxxd57a690xxxxxxxxxx',
});
}
}
3.3 CocosCreator
// 库
import * as cc from 'cc';
// 引入sdk
import { SDK } from '@dn-sdk/minigame/build/index.mjs';
// 常量
const { ccclass } = cc._decorator;
@ccclass('GameManager')
export default class GameManager extends cc.Component {
static instance: GameManager;
public sdk: SDK;
protected onLoad(): void {
// 添加常驻节点
cc.director.addPersistRootNode(this.node);
// 初始化SDK
try {
this.sdk = new SDK({
user_action_set_id: 'your_user_action_set_id',
secret_key: "5e853xxxxxxxxxxd57a690xxxxxxxxxx",
appid: "wx123xyz123xyz123x",
});
} catch (error) {
console.error(error);
}
// 缓存实例对象
GameManager.instance = this;
}
}
3.4 Egret
import { SDK } from './lib/dn-sdk-minigame.min.js';
class Main extends egret.DisplayObjectContainer {
public constructor() {
super();
this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
}
private onAddToStage(event: egret.Event) {
const sdkInstance = new SDK({
user_action_set_id: 'your_user_action_set_id',
secret_key: "5e853xxxxxxxxxxd57a690xxxxxxxxxx",
appid: "wx123xyz123xyz123x",
});
this.runGame().catch(e => {
console.log(e);
})
}
private async runGame() {
// 游戏代码
}
}
3.5 Unity
请参考以下 unity 小游戏使用 case。
jslib调用dn-sdk.js里的代码。
mergeInto(LibraryManager.library,{
SetOpenId:function(openId,isNewUser){
//GameGlobal.setOpenId(openId,isNewUser);
GameGlobal.setopenId({
openId: UTF8Tostring(openId),
isNewUser:isNewUser
});
},
CreateRole:function(userName){
GameGlobal.createRole({
userName: UTF8ToString(userName)
});
},
TutorialFinish:function(){
GameGlobal.tutorialFinish();
},
Purchase:function(price){
GameGlobal.purchase({
price: price
});
},
});
dn-sdk.js 调用 sdk 中的 index.ts 代码
import { SDK }from './index.js';
SDK.setDebug(true);
GameGlobal.setOpenId = (args) => {
//设置opneid,必须先设置openid再上报注册行为。setopenId为同步方法,设需完请交即上报注册行为。
sdk.setopenId(args.openId);
console.log("设置opneid:"+args.openId);
//上报注册行为,后台接口判断是否为注册用户,与API口径保持一致,比如30天后回流的用户是否当做注册用户。
if(args.isNewUser==1){
sdk.onRegister();
}
};
GameGlobal.createRole = (args) => {
//事件注册在GameGloble里
console.log("创建角色:"+args.userName);
sdk.onCreateRole(args.userName);
};
GameGlobal.tutorialFinish = () => {
sdk.onTutorialFinish();
};
GameGlobal.purchase = (args) => {
console.log("支付价格:"+args.price);
var price = args.price;
sdk.onPurchase(price*100);
};
GameGlobal
import'./texture-config';
import unityNamespace from './unity-namespace';
import '.$DOTNET_RUNTIME_FOLD/$GAME_NAME.wasm.framework.unityweb';
import './unity-sdk/index';
import checkVersion from './check-version';
import { launchEventType, scaleMode } from './plugin-config';
import { preloadWxCommonFont } from './unity-sdk/font/index';
import './dn-sdk-minigame/dn-sdk';
//微信小游戏插件game.js里import dn-sdk.js。
//在jslib里通过微信小游戏插件的GameGlobal这个全局变量调用js的函数。
import { SDK }from './index.js';
//dn-sdk.js调用sdk中index.js的函数
SDK.setDebug(true);
const sdk = new SDK({
//数据源ID,数字,必填。
user_action_set_id: 123xxxx
//加密key,必填。
secret)key: 'key'
//微信小游戏AppID,wx开头,必填。
appid: 'AppID'
};
4 设置用户 ID
4.1 setOpenId
wx.request({
url: '后端获取openid以及判断是否注册用户的接口url',
success: function(res){
if(res.openid){
// 设置opneid,必须先设置openid再上报注册行为。setOpenId 为同步方法,设置完可立即上报注册行为。
sdk.setOpenId(res.openid);
//上报注册行为
if(res.isRegisterUser){
sdk.onRegister();
}
}
}
});
4.2 setUnionId
wx.request({
url: '后端获取openid以及判断是否注册用户的接口 url',
success: function(res){
if(res.unionid){
// 设置 unionid ,请优先使用 openid,没有 openid 或者后台统一使用 unionid 才设置。
sdk.setUnionId(res.unionid);
//上报注册行为
if(res.isRegisterUser){
sdk.onRegister();
}
}
}
});
5 事件上报
5.1 通用上报方法
可通过 track 方法上报用户行为事件,并为事件添加自定义属性:
sdk.track(action_type, [,action_param]);
track方法参数
参数 | 类型 | 必填 | 描述 | 示例值 |
---|---|---|---|---|
action_type | string | 是 | 行为名称, 查看行为枚举值 | PURCHASE、REGISTER、CREATE_ROLE |
action_param | object | 否 | 为用户行为事件添加自定义属性,类型:Object。 | { value: 600 } |
行为参数 action_param 是Key-Value
类型;Key 只可以为 String 类型,只能包含字母、数字和下划线,必须以字母开头,长度不能超过 255;Value 可以是 String/Number/Boolean/Object 其中一种,当 Value 为 Object 时,它的元素只能为 String/Number/Boolean 中的一种。
代码示例:
// 上报付费行为
sdk.track('PURCHASE', {
value: 600,
});
5.2 通用上报方法
针对部分常用行为,提供了专用上报方法,建议优先使用如下专用上报方法上报数据:
行为 | 专用上报方法 | 参数 | 调用示例 | 调用时机 |
---|---|---|---|---|
注册(REGISTER) | onRegister() | 无 | sdk.onRegister() | 注册成功 |
创建角色(CREATE_ROLE) | onCreateRole(string roleName) | roleName: 角色名称 | sdk.onCreateRole("SuperMan") | 创建角色成功 |
完成新手指引(TUTORIAL_FINISH) | onTutorialFinish() | 无 | sdk.onTutorialFinish() | 完成新手教程 |
付费(PURCHASE) | onPurchase(int value) | value: 付费金额(分) | sdk.onPurchase(600) | 完成付费 |
小游戏进入前台(ENTER_FOREGROUND) | onEnterForeground() | 无 | sdk.onEnterForeground() | 小游戏进入前台 |
小游戏进入后台(ENTER_BACKGROUND) | onEnterBackground() | 无 | sdk.onEnterBackground() | 小游戏进入后台 |
小游戏启动(START_APP) | onAppStart() | 无 | sdk.onAppStart() | 小游戏启动 |
小游戏退出(APP_QUIT) | onAppQuit() | 无 | sdk.onAppQuit() | 小游戏退出 |
收藏小游戏(ADD_TO_WISHLIST) | onAddToWishlist() | 无 | sdk.onAddToWishlist() | 收藏小游戏 |
6 调试查看事件信息
6.1 事件的触发日志
当小游戏SDK初始化完成并上报数据后,可通过微信开发者工具查看是否有调用接口api.datanexus.qq.com/data-nexus-cgi/miniprogram
,当该接口调用成功且 code 码为 0 表示数据上报成功。如果上报失败控制台会打印错误日志,日志前缀为 [@dn-sdk/minigame v1.x.x] ,可根据日志中错误原因自行排查或参考下文 FAQ。
为保证数据安全,从v.1.4.0 开始,接口请求参数已加密,抓包将看不到明文数据。开发阶段如需查看上报数据信息,请开启调试模式查看日志信息。
// 打开调试模式, 建议仅在调试期间开启
SDK.setDebug(true);
7 兼容性测试
在接入完 SDK 正式发布小游戏之前,请在微信小游戏后台云测试服务模块完成兼容性测试。
8 数据对账
使用初始化 SDK 时的数据源 ID 所属账号登录 DataNexus 平台,在 DataNexus 平台日志查询页面的【用户】子菜单下,右侧输入微信小程序 APP ID 或 数据源 ID 即可实时查询SDK上报的原始数据,对比行为类型、行为参数和行为时间确认数据上报的正确性。
9 高级功能
9.1 设置上报请求并发数
wx.request 最大并发限制是 10 ,小游戏 SDK 默认占用的最大并发数量为 4,不会影响小游戏本身的网络请求。同时 SDK 也提供了设置最大并发数的方法,最小可设置为1。
SDK.setRequestConcurrency(5);
9.2 自动采集能力
小游戏SDK从 V1.1.3 版本开始支持行为自动采集的能力,自动采集行为仅用于数据校验。自动采集行为详见表格。
行为英文名 | 行为中文名 | 行为参数 | 触发时机 | 备注 |
---|---|---|---|---|
TICKET | 心跳 | 无 | 间隔1分钟触发一次 | |
START_APP | 启动小游戏 | 无 | 小游戏冷启动的时候触发 | |
ENTER_FOREGROUND | 小游戏进入前台 | 无 | 小游戏进入前台时触发 | 详细触发场景参考官方文档 wx.onShow |
ENTER_BACKGROUND | 小游戏进入后台 | 无 | 小游戏进入后台时触发 | 详细触发场景参考官方文档 wx.onHide |
LOGIN | 登录小游戏 | 无 | 调用wx.login方法登录成功后触发 | SDK初始化早于此方法调用 |
ADD_TO_WISHLIST | 收藏小游戏 | 无 | 点击右上角菜单【收藏】 | 前置条件:在小游戏内部调用方法wx.onAddToFavorites 实现收藏,且SDK初始化早于此方法调用。暂时只支持Android系统 |
SHARE | 分享小游戏 | {"target": "","trigger": ""} | ① 点击右上角菜单【转发给好友】② 点击右上角菜单【分享到朋友圈】③ 调用wx.shareAppMessage主动拉起转发 | 前置条件:① 小游戏已设置显示转发按钮② 在小游戏内部有调用方法:wx.onShareAppMessage、wx.onShareTimeline 实现分享功能,且SDK初始化早于此方法调用。 |
CREATE_GAME_CLUB | 创建游戏圈 | 无 | 调用 wx.createGameClubButton 方法创建游戏圈后触发 | SDK初始化早于此方法调用 |
TAP_GAME_CLUB | 点击游戏圈 | 无 | 点击游戏圈时触发 | 前置条件:在小游戏内部有调用方法GameClubButton.onTap |
CREATE_GAME_ROOM | 创建游戏房间 | 无 | 调用GameServerManager.createRoom方法创建游戏房间成功后触发 | SDK初始化早于此方法调用 |
JOIN_GAME_ROOM | 加入游戏房间 | 无 | 调用GameServerManager.joinRoom方法加入房间成功后触发 | SDK初始化早于此方法调用 |
START_PAY | 开始米大师支付 | {"quantity": "","mode": "","platform": "","no": "","payType": ""} | 调用 wx.requestMidasPayment 发起米大师支付时触发 | 暂时只支持Android系统 |
FINISH_PAY | 完成米大师支付 | {"status": "" "quantity": "","mode": "","platform": "","no": "","payType": ""} | 米大师支付接口返回结果后触发 | 暂时只支持Android系统 |
10 FAQ
Q: SDK是否可以在微信小程序中使用?
A: SDK只可以在微信小游戏中使用,如果在微信小程序中引入使用会报错,如需使用请使用微信小程序的SDK。
Q: 多数据源上报是否有上限?
A: 多数据源上报时有上限,目前最多允许初始化 4 个实例上报。
Q: appid不正确?
A: 需要正确填写当前接入SDK的小游戏appid,不可错填或填写其它小游戏的appid。
Q: user_action_set_id 是什么,如何获取?
A: 是数据源 ID,这是 DataNexus 为数据源分配的唯一ID,一个小游戏对应一个数据源,不区分环境,获取查看【接入流程】
Q: secret_key 是什么,如何获取?
A: 是SDK密钥,这是 DataNexus 为每个行为数据源生成的唯一接入密钥,在 SDK 初始化时进行使用,获取查看【接入流程】
Q: 遇到报错【请勿重复初始化SDK】?
A: 相同的 user_action_set_id 只可以初始化一个实例,需要初始化多个实例需要不同的user_action_set_id。
Q: 上报接口返回 51000:Action Set Not Exist
A: 请检查初始化参数user_action_set_id(数据源ID)是否填写正确,数据源ID可登录DataNexus平台查询。
Q: 上报接口返回51000: SecretKey Error
A: 请检查初始化参数中user_action_set_id 与 secret_key 是否匹配,可登录DataNexus平台查询。
Q:调用track方法后,没有抓到有数据上报网络请求?
A:检查是否设置了openid 或 unionid,没有设置用户ID会暂缓上报数据