@gabagool-sdk/react-native 0.2.0 → 0.3.0
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 +9 -0
- package/README.md +31 -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 +9 -1
- package/dist/facade.d.ts.map +1 -1
- package/dist/facade.js +12 -0
- package/package.json +3 -3
- package/src/adapter.ts +16 -7
- package/src/facade.ts +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## 0.3.0
|
|
2
|
+
|
|
3
|
+
* **Funciona sem polyfill de crypto**: o core não exige mais `crypto.getRandomValues` (ver `@gabagool-sdk/core` 0.3.0); `react-native-get-random-values` passa de obrigatório (0.2.x) a recomendado: se o app tiver, é usado e os ids ganham aleatoriedade criptográfica; sem ele os ids saem de `Math.random`. Requer `@gabagool-sdk/core` ^0.3.0.
|
|
4
|
+
* **Fix do Metro**: o campo `"react-native"` do `package.json` apontava para `src/index.ts`, e o Metro resolvia o fonte TS com imports `./x.js` e quebrava. Agora aponta para o JS compilado (`dist/index.js`, o mesmo do `main`), que já vai no pacote (`files`).
|
|
5
|
+
|
|
6
|
+
## 0.2.1
|
|
7
|
+
|
|
8
|
+
* `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.
|
|
9
|
+
|
|
1
10
|
## 0.2.0
|
|
2
11
|
|
|
3
12
|
* `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.
|
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.2.
|
|
8
|
+
**Limitação da versão 0.2.x:** 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
|
|
|
@@ -15,6 +15,27 @@ Mais detalhes: https://gabagool.com.br
|
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
17
|
npm install @gabagool-sdk/react-native react-native-google-mobile-ads @react-native-async-storage/async-storage react-native-play-install-referrer
|
|
18
|
+
# recomendado (opcional a partir da 0.3.0):
|
|
19
|
+
npm install react-native-get-random-values
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Polyfill de `crypto.getRandomValues`: recomendado a partir da 0.3.0, obrigatório na 0.2.x.**
|
|
23
|
+
- **0.3.0 ou mais nova**: o SDK funciona sem o polyfill. Se faltar `crypto.getRandomValues`, os ids de evento e de
|
|
24
|
+
instalação saem de `Math.random` (servem como id, não como segredo). Com o polyfill instalado, ele é usado sozinho e
|
|
25
|
+
os ids ganham aleatoriedade criptográfica, por isso é o recomendado.
|
|
26
|
+
- **0.2.x**: sem o polyfill o `init` falha com `crypto.getRandomValues() not supported` e nenhum anúncio aparece
|
|
27
|
+
(confirmado em aparelho em 14/11/2026). Atualize para a 0.3.0 ou instale o polyfill.
|
|
28
|
+
|
|
29
|
+
Se instalar, importe na **primeira linha do arquivo de entrada** do app, antes de qualquer import do SDK:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
// index.js — primeira linha, antes de qualquer import do @gabagool-sdk
|
|
33
|
+
import 'react-native-get-random-values';
|
|
34
|
+
import { AppRegistry } from 'react-native';
|
|
35
|
+
import App from './App';
|
|
36
|
+
import { name as appName } from './app.json';
|
|
37
|
+
|
|
38
|
+
AppRegistry.registerComponent(appName, () => App);
|
|
18
39
|
```
|
|
19
40
|
|
|
20
41
|
Você precisa de uma **chave de API** (`x-api-key`) do seu app, gerada no painel Gabagool.
|
|
@@ -36,6 +57,7 @@ no `Info.plist` conforme a documentação do `react-native-google-mobile-ads`.
|
|
|
36
57
|
## 3. Init
|
|
37
58
|
|
|
38
59
|
```tsx
|
|
60
|
+
// se instalou o polyfill recomendado, ele já foi importado na 1ª linha do index.js (seção 1)
|
|
39
61
|
import { GabagoolAds } from '@gabagool-sdk/react-native';
|
|
40
62
|
|
|
41
63
|
await GabagoolAds.init('SUA_API_KEY', 'https://apps.gabagool.com.br', 'com.seu.app', {
|
|
@@ -62,6 +84,14 @@ const result = await GabagoolAds.showInterstitial('home');
|
|
|
62
84
|
const reward = await GabagoolAds.showRewarded('bonus');
|
|
63
85
|
```
|
|
64
86
|
|
|
87
|
+
**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`):
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
GabagoolAds.setRewardedSsv({ userId: 'user-123', customData: '{"pack":"coins_50"}' });
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
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.
|
|
94
|
+
|
|
65
95
|
### Banner
|
|
66
96
|
|
|
67
97
|
```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 OnPaidEvent, 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 {
|
|
@@ -38,6 +38,14 @@ export declare class GabagoolAds {
|
|
|
38
38
|
* telemetria; exceção do callback é engolida. Pode ser atribuído antes ou depois do `init`.
|
|
39
39
|
*/
|
|
40
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;
|
|
41
49
|
static get core(): Gabagool;
|
|
42
50
|
static init(apiKey: string, baseUrl: string, appId: string, options?: GabagoolInitOptions): Promise<void>;
|
|
43
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,WAAW,EAChB,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;IAClC,4CAA4C;IAC5C,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,oDAAoD;AACpD,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA8B;IACrD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAkC;IAC1D,OAAO,CAAC,MAAM,CAAC,UAAU,CAAsC;IAC/D,OAAO,CAAC,MAAM,CAAC,UAAU,CAA0B;IAEnD,OAAO,CAAC,MAAM,CAAC,QAAQ;IAMvB,kGAAkG;IAClG,MAAM,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAEjC,OAAO,CAAC,MAAM,CAAC,UAAU;IAIzB;;;OAGG;IACH,MAAM,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAAQ;IAE9C,MAAM,KAAK,IAAI,IAAI,QAAQ,CAA0B;WAExC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"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"}
|
package/dist/facade.js
CHANGED
|
@@ -28,6 +28,17 @@ export class GabagoolAds {
|
|
|
28
28
|
* telemetria; exceção do callback é engolida. Pode ser atribuído antes ou depois do `init`.
|
|
29
29
|
*/
|
|
30
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
|
+
}
|
|
31
42
|
static get core() { return this.instance; }
|
|
32
43
|
static async init(apiKey, baseUrl, appId, options = {}) {
|
|
33
44
|
if (options.onPaidEvent)
|
|
@@ -36,6 +47,7 @@ export class GabagoolAds {
|
|
|
36
47
|
this.instance.dispose();
|
|
37
48
|
this.resetReady();
|
|
38
49
|
this.instance = createGabagool();
|
|
50
|
+
this.instance.setRewardedSsv(this.ssv);
|
|
39
51
|
const adapter = options.adapter ?? new ReactNativeGmaAdapter();
|
|
40
52
|
this.gmaAdapter = adapter instanceof ReactNativeGmaAdapter ? adapter : null;
|
|
41
53
|
if (this.gmaAdapter)
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gabagool-sdk/react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
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",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
-
"react-native": "
|
|
8
|
+
"react-native": "dist/index.js",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
11
|
"src",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"prepack": "npm run build"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@gabagool-sdk/core": "^0.
|
|
26
|
+
"@gabagool-sdk/core": "^0.3.0"
|
|
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
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
type KVStorage,
|
|
14
14
|
type OnPaidEvent,
|
|
15
15
|
type RewardedResult,
|
|
16
|
+
type RewardedSsv,
|
|
16
17
|
type TelemetryTransport,
|
|
17
18
|
type WrapperConfig,
|
|
18
19
|
} from '@gabagool-sdk/core';
|
|
@@ -71,6 +72,19 @@ export class GabagoolAds {
|
|
|
71
72
|
*/
|
|
72
73
|
static onPaidEvent: OnPaidEvent | null = null;
|
|
73
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
|
+
|
|
74
88
|
static get core(): Gabagool { return this.instance; }
|
|
75
89
|
|
|
76
90
|
static async init(apiKey: string, baseUrl: string, appId: string, options: GabagoolInitOptions = {}): Promise<void> {
|
|
@@ -79,6 +93,7 @@ export class GabagoolAds {
|
|
|
79
93
|
this.instance.dispose();
|
|
80
94
|
this.resetReady();
|
|
81
95
|
this.instance = createGabagool();
|
|
96
|
+
this.instance.setRewardedSsv(this.ssv);
|
|
82
97
|
|
|
83
98
|
const adapter = options.adapter ?? new ReactNativeGmaAdapter();
|
|
84
99
|
this.gmaAdapter = adapter instanceof ReactNativeGmaAdapter ? adapter : null;
|