@gabagool-sdk/react-native 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +9 -1
- package/dist/adapter.d.ts +2 -2
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +10 -6
- package/dist/facade.d.ts +16 -1
- package/dist/facade.d.ts.map +1 -1
- package/dist/facade.js +20 -0
- package/package.json +2 -2
- package/src/adapter.ts +16 -7
- package/src/facade.ts +26 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 0.2.1
|
|
2
|
+
|
|
3
|
+
* `GabagoolAds.setRewardedSsv({ userId?, customData? })`: SSV do rewarded, mesma semântica do Dart e do core (antes ou depois do `init`; `userId` > `identify`; `customData` ≤ 1024). O adapter aplica `serverSideVerificationOptions` (`react-native-google-mobile-ads` 17.x) no `RewardedAd.createForAdRequest`. Não testado em aparelho. Requer `@gabagool-sdk/core` ^0.2.1.
|
|
4
|
+
|
|
5
|
+
## 0.2.0
|
|
6
|
+
|
|
7
|
+
* `GabagoolAds.onPaidEvent` (e opção `onPaidEvent` no `init`): receita de toda impressão, repassada do core. O lado nativo do RN continua parcial (API presente; emissão coberta pelos testes do core). Requer `@gabagool-sdk/core` ^0.2.0.
|
|
8
|
+
|
|
1
9
|
## 0.1.1
|
|
2
10
|
|
|
3
11
|
* First release published through GitHub Actions trusted publishing (no functional changes).
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ O servidor Gabagool decide segmento, ad units e pisos a cada `init`; o piso vai
|
|
|
5
5
|
**key-value de targeting** (a key de piso é configurada no painel Gabagool, com a grafia exata do
|
|
6
6
|
valor do piso). Sem configuração do servidor, o SDK não exibe anúncios.
|
|
7
7
|
|
|
8
|
-
**Limitação da versão 0.
|
|
8
|
+
**Limitação da versão 0.2.0:** o formato **native** ainda não é suportado neste pacote
|
|
9
9
|
(interstitial, rewarded, banner e app open já funcionam). Android é o alvo testado;
|
|
10
10
|
no iOS, passe `installInfoProvider` no `init` (o plugin de Play Install Referrer é Android-only).
|
|
11
11
|
|
|
@@ -62,6 +62,14 @@ const result = await GabagoolAds.showInterstitial('home');
|
|
|
62
62
|
const reward = await GabagoolAds.showRewarded('bonus');
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
+
**SSV (Server-Side Verification)**: para validar a recompensa no seu backend, defina `userId`/`customData` (antes ou depois do `init`; sem `userId`, vale o do `identify`):
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
GabagoolAds.setRewardedSsv({ userId: 'user-123', customData: '{"pack":"coins_50"}' });
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Vira `serverSideVerificationOptions` do `react-native-google-mobile-ads` no load do rewarded (`customData` até 1024 chars). Callback, assinatura e limites: `docs/SSV-REWARDED.md`. Não testado em aparelho nem contra o callback real do Google.
|
|
72
|
+
|
|
65
73
|
### Banner
|
|
66
74
|
|
|
67
75
|
```tsx
|
package/dist/adapter.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AdHandle, type AdNetworkAdapter, type FloorKV, type LoadResult, type ShowResult } from '@gabagool-sdk/core';
|
|
1
|
+
import { type AdHandle, type AdNetworkAdapter, type FloorKV, type LoadResult, type RewardedLoadOptions, type ShowResult } from '@gabagool-sdk/core';
|
|
2
2
|
/** Adapter do core para a API estável do Invertase 17.x. */
|
|
3
3
|
export declare class ReactNativeGmaAdapter implements AdNetworkAdapter {
|
|
4
4
|
private sequence;
|
|
@@ -9,7 +9,7 @@ export declare class ReactNativeGmaAdapter implements AdNetworkAdapter {
|
|
|
9
9
|
/** Falha do initialize() não trava o app (como a Dart): segue e os loads reportam seus próprios erros. */
|
|
10
10
|
initialize(): Promise<void>;
|
|
11
11
|
loadInterstitial(adUnit: string, floorKV?: FloorKV): Promise<LoadResult>;
|
|
12
|
-
loadRewarded(adUnit: string, floorKV?: FloorKV): Promise<LoadResult>;
|
|
12
|
+
loadRewarded(adUnit: string, floorKV?: FloorKV, opts?: RewardedLoadOptions): Promise<LoadResult>;
|
|
13
13
|
loadAppOpen(adUnit: string, floorKV?: FloorKV): Promise<LoadResult>;
|
|
14
14
|
loadBanner(adUnit: string, _floorKV?: FloorKV): Promise<LoadResult>;
|
|
15
15
|
/** Native ainda não portado para RN (Invertase NativeAd): reporta erro explícito, nunca fill falso. */
|
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,mBAAmB,EAExB,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AA+B5B,4DAA4D;AAC5D,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAE5D,0GAA0G;IAC1G,QAAQ,CAAC,6BAA6B,QAAQ;IAE9C,0GAA0G;IACpG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAGxE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAGhG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAWzE,uGAAuG;IACjG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAI1E,gBAAgB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI;IAI9B,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,OAAO,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI;IAM3B,IAAI,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAuCvC,OAAO,CAAC,cAAc;IAyCtB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,MAAM;CAGf"}
|
package/dist/adapter.js
CHANGED
|
@@ -24,8 +24,8 @@ export class ReactNativeGmaAdapter {
|
|
|
24
24
|
loadInterstitial(adUnit, floorKV) {
|
|
25
25
|
return this.loadFullscreen('interstitial', adUnit, floorKV);
|
|
26
26
|
}
|
|
27
|
-
loadRewarded(adUnit, floorKV) {
|
|
28
|
-
return this.loadFullscreen('rewarded', adUnit, floorKV);
|
|
27
|
+
loadRewarded(adUnit, floorKV, opts) {
|
|
28
|
+
return this.loadFullscreen('rewarded', adUnit, floorKV, opts?.ssv);
|
|
29
29
|
}
|
|
30
30
|
loadAppOpen(adUnit, floorKV) {
|
|
31
31
|
return this.loadFullscreen('app_open', adUnit, floorKV);
|
|
@@ -99,11 +99,11 @@ export class ReactNativeGmaAdapter {
|
|
|
99
99
|
}
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
|
-
loadFullscreen(format, adUnit, floorKV) {
|
|
102
|
+
loadFullscreen(format, adUnit, floorKV, ssv) {
|
|
103
103
|
return new Promise((resolve) => {
|
|
104
104
|
let native;
|
|
105
105
|
try {
|
|
106
|
-
const request = this.requestOptions(adUnit, floorKV);
|
|
106
|
+
const request = this.requestOptions(adUnit, floorKV, format === 'rewarded' ? ssv : undefined);
|
|
107
107
|
const created = format === 'app_open'
|
|
108
108
|
? AppOpenAd.createForAdRequest(adUnit, request)
|
|
109
109
|
: format === 'rewarded'
|
|
@@ -149,9 +149,13 @@ export class ReactNativeGmaAdapter {
|
|
|
149
149
|
}
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
|
-
requestOptions(adUnit, floorKV) {
|
|
152
|
+
requestOptions(adUnit, floorKV, ssv) {
|
|
153
153
|
const kv = this.requestFloor(adUnit, floorKV);
|
|
154
|
-
|
|
154
|
+
// Invertase: RequestOptions.serverSideVerificationOptions { userId, customData } (só no RewardedAd; vazio => omitido)
|
|
155
|
+
const ssvOptions = ssv && (ssv.userId !== undefined || ssv.customData !== undefined)
|
|
156
|
+
? { serverSideVerificationOptions: { ...(ssv.userId !== undefined ? { userId: ssv.userId } : {}), ...(ssv.customData !== undefined ? { customData: ssv.customData } : {}) } }
|
|
157
|
+
: {};
|
|
158
|
+
return kv || ssvOptions.serverSideVerificationOptions ? { ...(kv ? { customTargeting: kv } : {}), ...ssvOptions } : undefined;
|
|
155
159
|
}
|
|
156
160
|
requestFloor(adUnit, floorKV) {
|
|
157
161
|
return networkOf(adUnit) === 'gam' && floorKV && Object.keys(floorKV).length > 0 ? { ...floorKV } : undefined;
|
package/dist/facade.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AdHandle, type AdNetworkAdapter, type BootAdResult, type FetchLike, type Gabagool, type GateResult, type InterstitialShowResult, type KVStorage, type RewardedResult, type TelemetryTransport, type WrapperConfig } from '@gabagool-sdk/core';
|
|
1
|
+
import { type AdHandle, type AdNetworkAdapter, type BootAdResult, type FetchLike, type Gabagool, type GateResult, type InterstitialShowResult, type KVStorage, type OnPaidEvent, type RewardedResult, type RewardedSsv, type TelemetryTransport, type WrapperConfig } from '@gabagool-sdk/core';
|
|
2
2
|
import { ReactNativeGmaAdapter } from './adapter.js';
|
|
3
3
|
import { type InstallInfoProvider } from './installInfo.js';
|
|
4
4
|
export interface GabagoolInitOptions {
|
|
@@ -20,6 +20,8 @@ export interface GabagoolInitOptions {
|
|
|
20
20
|
advertisingId?: string;
|
|
21
21
|
debug?: boolean;
|
|
22
22
|
context?: Record<string, unknown>;
|
|
23
|
+
/** atalho para `GabagoolAds.onPaidEvent` */
|
|
24
|
+
onPaidEvent?: OnPaidEvent;
|
|
23
25
|
}
|
|
24
26
|
/** Fachada singleton equivalente à fachada Dart. */
|
|
25
27
|
export declare class GabagoolAds {
|
|
@@ -31,6 +33,19 @@ export declare class GabagoolAds {
|
|
|
31
33
|
/** Resolve quando o `init` terminou (Banner pode montar antes; ver BannerFlow). Nunca rejeita. */
|
|
32
34
|
static whenReady(): Promise<void>;
|
|
33
35
|
private static resetReady;
|
|
36
|
+
/**
|
|
37
|
+
* Receita de TODA impressão (fullscreen, banner e native), para o app repassar a Firebase/Meta/MMP. Disparado além da
|
|
38
|
+
* telemetria; exceção do callback é engolida. Pode ser atribuído antes ou depois do `init`.
|
|
39
|
+
*/
|
|
40
|
+
static onPaidEvent: OnPaidEvent | null;
|
|
41
|
+
/** SSV guardado aqui: setRewardedSsv antes do init sobrevive à recriação do core. */
|
|
42
|
+
private static ssv;
|
|
43
|
+
/**
|
|
44
|
+
* SSV do rewarded (Server-Side Verification): `userId`/`customData` chegam no callback do Google ao seu backend.
|
|
45
|
+
* Vale antes ou depois do `init` (próximos loads; um rewarded já carregado mantém o que tinha). Sem `userId`, usa o do
|
|
46
|
+
* `identify`. Sem argumentos limpa. `customData` acima de 1024 chars é cortado (com aviso). Ver docs/SSV-REWARDED.md.
|
|
47
|
+
*/
|
|
48
|
+
static setRewardedSsv(ssv?: RewardedSsv): void;
|
|
34
49
|
static get core(): Gabagool;
|
|
35
50
|
static init(apiKey: string, baseUrl: string, appId: string, options?: GabagoolInitOptions): Promise<void>;
|
|
36
51
|
static showInterstitial(screen?: string): Promise<InterstitialShowResult>;
|
package/dist/facade.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,sBAAsB,EAC3B,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAkC,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAK5F,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"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"}
|
package/dist/facade.js
CHANGED
|
@@ -23,12 +23,31 @@ export class GabagoolAds {
|
|
|
23
23
|
if (this.readyState.done)
|
|
24
24
|
this.readyState = this.newReady();
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Receita de TODA impressão (fullscreen, banner e native), para o app repassar a Firebase/Meta/MMP. Disparado além da
|
|
28
|
+
* telemetria; exceção do callback é engolida. Pode ser atribuído antes ou depois do `init`.
|
|
29
|
+
*/
|
|
30
|
+
static onPaidEvent = null;
|
|
31
|
+
/** SSV guardado aqui: setRewardedSsv antes do init sobrevive à recriação do core. */
|
|
32
|
+
static ssv;
|
|
33
|
+
/**
|
|
34
|
+
* SSV do rewarded (Server-Side Verification): `userId`/`customData` chegam no callback do Google ao seu backend.
|
|
35
|
+
* Vale antes ou depois do `init` (próximos loads; um rewarded já carregado mantém o que tinha). Sem `userId`, usa o do
|
|
36
|
+
* `identify`. Sem argumentos limpa. `customData` acima de 1024 chars é cortado (com aviso). Ver docs/SSV-REWARDED.md.
|
|
37
|
+
*/
|
|
38
|
+
static setRewardedSsv(ssv) {
|
|
39
|
+
this.ssv = ssv;
|
|
40
|
+
this.instance.setRewardedSsv(ssv);
|
|
41
|
+
}
|
|
26
42
|
static get core() { return this.instance; }
|
|
27
43
|
static async init(apiKey, baseUrl, appId, options = {}) {
|
|
44
|
+
if (options.onPaidEvent)
|
|
45
|
+
this.onPaidEvent = options.onPaidEvent;
|
|
28
46
|
this.lifecycle?.stop();
|
|
29
47
|
this.instance.dispose();
|
|
30
48
|
this.resetReady();
|
|
31
49
|
this.instance = createGabagool();
|
|
50
|
+
this.instance.setRewardedSsv(this.ssv);
|
|
32
51
|
const adapter = options.adapter ?? new ReactNativeGmaAdapter();
|
|
33
52
|
this.gmaAdapter = adapter instanceof ReactNativeGmaAdapter ? adapter : null;
|
|
34
53
|
if (this.gmaAdapter)
|
|
@@ -71,6 +90,7 @@ export class GabagoolAds {
|
|
|
71
90
|
...(options.context ?? {}),
|
|
72
91
|
},
|
|
73
92
|
debug: options.debug === true,
|
|
93
|
+
onPaidEvent: (e) => GabagoolAds.onPaidEvent?.(e),
|
|
74
94
|
});
|
|
75
95
|
this.lifecycle = new AppStateLifecycle(this.instance);
|
|
76
96
|
this.lifecycle.start();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gabagool-sdk/react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "React Native SDK for Gabagool Apps monetization: interstitial, rewarded and banner ads with server-side config, price floors and gating, on top of Google Mobile Ads (Ad Manager / AdMob).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"prepack": "npm run build"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@gabagool-sdk/core": "^0.1
|
|
26
|
+
"@gabagool-sdk/core": "^0.2.1"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"@react-native-async-storage/async-storage": "^3.1.1",
|
package/src/adapter.ts
CHANGED
|
@@ -15,9 +15,14 @@ import {
|
|
|
15
15
|
type AdNetworkAdapter,
|
|
16
16
|
type FloorKV,
|
|
17
17
|
type LoadResult,
|
|
18
|
+
type RewardedLoadOptions,
|
|
19
|
+
type RewardedSsv,
|
|
18
20
|
type ShowResult,
|
|
19
21
|
} from '@gabagool-sdk/core';
|
|
20
|
-
type RequestOptions = {
|
|
22
|
+
type RequestOptions = {
|
|
23
|
+
customTargeting?: Record<string, string | number | (string | number)[]>;
|
|
24
|
+
serverSideVerificationOptions?: { userId?: string; customData?: string };
|
|
25
|
+
};
|
|
21
26
|
|
|
22
27
|
type Remove = () => void;
|
|
23
28
|
type EventPayload = Error & { code?: string; reason?: string; phase?: 'load' | 'show' };
|
|
@@ -61,8 +66,8 @@ export class ReactNativeGmaAdapter implements AdNetworkAdapter {
|
|
|
61
66
|
loadInterstitial(adUnit: string, floorKV?: FloorKV): Promise<LoadResult> {
|
|
62
67
|
return this.loadFullscreen('interstitial', adUnit, floorKV);
|
|
63
68
|
}
|
|
64
|
-
loadRewarded(adUnit: string, floorKV?: FloorKV): Promise<LoadResult> {
|
|
65
|
-
return this.loadFullscreen('rewarded', adUnit, floorKV);
|
|
69
|
+
loadRewarded(adUnit: string, floorKV?: FloorKV, opts?: RewardedLoadOptions): Promise<LoadResult> {
|
|
70
|
+
return this.loadFullscreen('rewarded', adUnit, floorKV, opts?.ssv);
|
|
66
71
|
}
|
|
67
72
|
loadAppOpen(adUnit: string, floorKV?: FloorKV): Promise<LoadResult> {
|
|
68
73
|
return this.loadFullscreen('app_open', adUnit, floorKV);
|
|
@@ -137,11 +142,11 @@ export class ReactNativeGmaAdapter implements AdNetworkAdapter {
|
|
|
137
142
|
});
|
|
138
143
|
}
|
|
139
144
|
|
|
140
|
-
private loadFullscreen(format: Exclude<AdFormat, 'banner'>, adUnit: string, floorKV?: FloorKV): Promise<LoadResult> {
|
|
145
|
+
private loadFullscreen(format: Exclude<AdFormat, 'banner'>, adUnit: string, floorKV?: FloorKV, ssv?: RewardedSsv): Promise<LoadResult> {
|
|
141
146
|
return new Promise((resolve) => {
|
|
142
147
|
let native: NativeFullscreen;
|
|
143
148
|
try {
|
|
144
|
-
const request = this.requestOptions(adUnit, floorKV);
|
|
149
|
+
const request = this.requestOptions(adUnit, floorKV, format === 'rewarded' ? ssv : undefined);
|
|
145
150
|
const created = format === 'app_open'
|
|
146
151
|
? AppOpenAd.createForAdRequest(adUnit, request)
|
|
147
152
|
: format === 'rewarded'
|
|
@@ -178,9 +183,13 @@ export class ReactNativeGmaAdapter implements AdNetworkAdapter {
|
|
|
178
183
|
});
|
|
179
184
|
}
|
|
180
185
|
|
|
181
|
-
private requestOptions(adUnit: string, floorKV?: FloorKV): RequestOptions | undefined {
|
|
186
|
+
private requestOptions(adUnit: string, floorKV?: FloorKV, ssv?: RewardedSsv): RequestOptions | undefined {
|
|
182
187
|
const kv = this.requestFloor(adUnit, floorKV);
|
|
183
|
-
|
|
188
|
+
// Invertase: RequestOptions.serverSideVerificationOptions { userId, customData } (só no RewardedAd; vazio => omitido)
|
|
189
|
+
const ssvOptions = ssv && (ssv.userId !== undefined || ssv.customData !== undefined)
|
|
190
|
+
? { serverSideVerificationOptions: { ...(ssv.userId !== undefined ? { userId: ssv.userId } : {}), ...(ssv.customData !== undefined ? { customData: ssv.customData } : {}) } }
|
|
191
|
+
: {};
|
|
192
|
+
return kv || ssvOptions.serverSideVerificationOptions ? { ...(kv ? { customTargeting: kv } : {}), ...ssvOptions } : undefined;
|
|
184
193
|
}
|
|
185
194
|
|
|
186
195
|
private requestFloor(adUnit: string, floorKV?: FloorKV): FloorKV | undefined {
|
package/src/facade.ts
CHANGED
|
@@ -11,7 +11,9 @@ import {
|
|
|
11
11
|
type GateResult,
|
|
12
12
|
type InterstitialShowResult,
|
|
13
13
|
type KVStorage,
|
|
14
|
+
type OnPaidEvent,
|
|
14
15
|
type RewardedResult,
|
|
16
|
+
type RewardedSsv,
|
|
15
17
|
type TelemetryTransport,
|
|
16
18
|
type WrapperConfig,
|
|
17
19
|
} from '@gabagool-sdk/core';
|
|
@@ -40,6 +42,8 @@ export interface GabagoolInitOptions {
|
|
|
40
42
|
advertisingId?: string;
|
|
41
43
|
debug?: boolean;
|
|
42
44
|
context?: Record<string, unknown>;
|
|
45
|
+
/** atalho para `GabagoolAds.onPaidEvent` */
|
|
46
|
+
onPaidEvent?: OnPaidEvent;
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
/** Fachada singleton equivalente à fachada Dart. */
|
|
@@ -62,13 +66,34 @@ export class GabagoolAds {
|
|
|
62
66
|
if (this.readyState.done) this.readyState = this.newReady();
|
|
63
67
|
}
|
|
64
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Receita de TODA impressão (fullscreen, banner e native), para o app repassar a Firebase/Meta/MMP. Disparado além da
|
|
71
|
+
* telemetria; exceção do callback é engolida. Pode ser atribuído antes ou depois do `init`.
|
|
72
|
+
*/
|
|
73
|
+
static onPaidEvent: OnPaidEvent | null = null;
|
|
74
|
+
|
|
75
|
+
/** SSV guardado aqui: setRewardedSsv antes do init sobrevive à recriação do core. */
|
|
76
|
+
private static ssv: RewardedSsv | undefined;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* SSV do rewarded (Server-Side Verification): `userId`/`customData` chegam no callback do Google ao seu backend.
|
|
80
|
+
* Vale antes ou depois do `init` (próximos loads; um rewarded já carregado mantém o que tinha). Sem `userId`, usa o do
|
|
81
|
+
* `identify`. Sem argumentos limpa. `customData` acima de 1024 chars é cortado (com aviso). Ver docs/SSV-REWARDED.md.
|
|
82
|
+
*/
|
|
83
|
+
static setRewardedSsv(ssv?: RewardedSsv): void {
|
|
84
|
+
this.ssv = ssv;
|
|
85
|
+
this.instance.setRewardedSsv(ssv);
|
|
86
|
+
}
|
|
87
|
+
|
|
65
88
|
static get core(): Gabagool { return this.instance; }
|
|
66
89
|
|
|
67
90
|
static async init(apiKey: string, baseUrl: string, appId: string, options: GabagoolInitOptions = {}): Promise<void> {
|
|
91
|
+
if (options.onPaidEvent) this.onPaidEvent = options.onPaidEvent;
|
|
68
92
|
this.lifecycle?.stop();
|
|
69
93
|
this.instance.dispose();
|
|
70
94
|
this.resetReady();
|
|
71
95
|
this.instance = createGabagool();
|
|
96
|
+
this.instance.setRewardedSsv(this.ssv);
|
|
72
97
|
|
|
73
98
|
const adapter = options.adapter ?? new ReactNativeGmaAdapter();
|
|
74
99
|
this.gmaAdapter = adapter instanceof ReactNativeGmaAdapter ? adapter : null;
|
|
@@ -114,6 +139,7 @@ export class GabagoolAds {
|
|
|
114
139
|
...(options.context ?? {}),
|
|
115
140
|
},
|
|
116
141
|
debug: options.debug === true,
|
|
142
|
+
onPaidEvent: (e) => GabagoolAds.onPaidEvent?.(e),
|
|
117
143
|
});
|
|
118
144
|
|
|
119
145
|
this.lifecycle = new AppStateLifecycle(this.instance);
|