跳到主要内容

腾讯广告小游戏 SDK 开发指引


腾讯广告小游戏 SDK 为广告主提供了一种新的数据接入方式,数据上报更为便捷且时效性更高,助力提升您的广告投放效果。目前支持微信原生小游戏及采用 CocosCreator、Egret、LayaAir 游戏引擎开发的微信小游戏( Unity 开发的小游戏如能支持 JS 也可使用此 SDK )。


SDK 信息

SDK名称:腾讯广告小游戏 SDK
开发者:深圳市腾讯计算机系统有限公司
版本号:1.5.3
主要功能:为开发者提供广告投放、广告归因、广告效果优化的基本功能
合规使用说明: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 合法域名。以微信小游戏后台的操作为例,具体步骤如下:

登录微信公众平台,进入【开发】 -> 【开发设置】-> 【服务器域名】。

sdk_01


首次配置点击服务器域名模块中【开始配置】按钮,追加域名点击【修改】按钮,打开【配置服务器域名】弹窗。

sdk_02


在 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 Version: 1.5.3,下载的压缩包 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_idnumber行为数据源ID100001
secret_keystring加密密钥5e853xxxxxxd57a690xxxxxxxxxx
appidstring微信小游戏 appidwx123xyz123xyz123x
auto_trackboolean是否开启自动采集,默认开启true
openidstring初始化时无需设置,请参考步骤3.2.3,调用setOpenId方法设置,openid 和 unionid 只需设置一个,优先使用openid获取openid
unionidstring初始化时无需设置,请参考步骤3.2.3,调用 setUnionId方法设置,没有 openid时才需要unionid获取unionid
user_unique_idstring非必填,业务自定义的用户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_typestring行为名称, 查看行为枚举值PURCHASE、REGISTER、CREATE_ROLE
action_paramobject为用户行为事件添加自定义属性,类型: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。

sdk_12


为保证数据安全,从v.1.4.0 开始,接口请求参数已加密,抓包将看不到明文数据。开发阶段如需查看上报数据信息,请开启调试模式查看日志信息。

// 打开调试模式, 建议仅在调试期间开启
SDK.setDebug(true);


7 兼容性测试

在接入完 SDK 正式发布小游戏之前,请在微信小游戏后台云测试服务模块完成兼容性测试。

sdk_14



8 数据对账

使用初始化 SDK 时的数据源 ID 所属账号登录 DataNexus 平台,在 DataNexus 平台日志查询页面的【用户】子菜单下,右侧输入微信小程序 APP ID 或 数据源 ID 即可实时查询SDK上报的原始数据,对比行为类型、行为参数和行为时间确认数据上报的正确性。

sdk_13



9 高级功能

9.1 多数据源上报

SDK 支持将数据上报到多个不同数据源(最多4个),初始化时使用不同的数据源 ID 创建多个 SDK 实例,然后用不同的实例分别上报数据。

import { SDK } from '@dn-sdk/minigame';
const sdk1 = new SDK({
user_action_set_id: 'your_user_action_set_id_1',
secret_key: 'your_secret_key_1',
appid: 'wx_123xyz',
openid: 'user_openid',
});

sdk1.setOpenId('user_openid');

const sdk2 = new SDK({
user_action_set_id: 'your_user_action_set_id_2',
secret_key: 'your_secret_key_2',
appid: 'wx_123xyz',
openid: 'user_openid',
});
sdk2.setOpenId('user_openid');

// 上报购买行为
sdk1.track('PURCHASE', {
value: 1000,
});

// 上报自定义行为
sdk2.track('custom_click');


9.2 设置上报请求并发数

wx.request 最大并发限制是 10 ,小游戏 SDK 默认占用的最大并发数量为 4,不会影响小游戏本身的网络请求。同时 SDK 也提供了设置最大并发数的方法,最小可设置为1。

SDK.setRequestConcurrency(5);


9.3 自动采集能力

小游戏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.onShareAppMessagewx.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会暂缓上报数据


该内容是否有帮助?