@akross/artemis-ads-sdk
v3.7.13
Published
SDK JavaScript do AdServer Akross Artemis
Readme
@akross/artemis-ads-sdk
SDK JavaScript para o AdServer Akross Artemis - Carregamento de banners e mídias publicitárias.
🚀 Características
- TypeScript Vanilla: Sem dependências de frameworks
- Múltiplos Builds: UMD (NPM), IIFE (CDN) e ESM (sites modernos)
- API Global:
window.AkrossAdspara uso em Flutter Web/WebView - Banner Loader: Carregamento otimizado de banners com fit inteligente
- VAST Fallback: Reprodução VAST via
@dailymotion/vast-clientquando não há conectividade para carregar o IMA SDK - Sample Interativa: Interface web para testes locais
📦 Instalação
npm install @akross/artemis-ads-sdk🎯 Uso Básico
Inicialização do SDK
import { init, ArtemisAdsBannerLoader } from '@akross/artemis-ads-sdk';
const SDK_CONFIG = {
baseUrl: 'https://ads.timfun.com.br/adserver/',
debug: true,
timeout: 10000,
appId: 'com.example.myapp', // ID da aplicação (equivalente ao package name do Android)
appVersion: '1.0.0', // Versão da aplicação
artemisAdsAppId: 'akross-app-123', // ID do app Artemis Ads
primaryColor: '#ff0000', // Cor primária do projeto (formato hexadecimal)
luminaToken: 'QQDCYMdFh2AJqwP' // Token do Lumina SDK (opcional - usa valor padrão se não fornecido)
};
const sdk = await init(SDK_CONFIG);Carregamento de Banner
// Criar instância do banner loader
const bannerLoader = new ArtemisAdsBannerLoader('#banner-container');
// Configurar listeners
bannerLoader.setSuccessListener({
onSuccess: (analyticsTag) => {
console.log('Banner carregado:', analyticsTag);
}
});
bannerLoader.setErrorListener({
onError: (message) => {
// `message` é uma string descritiva e auto-suficiente
// (carrega URL, status HTTP da CDN, causa de rede, etc.)
console.error('Erro ao carregar banner:', message);
}
});
bannerLoader.setClickListener({
onClick: (analyticsTag) => {
console.log('Banner clicado:', analyticsTag);
}
});
// Carregar banner por Zone ID
await bannerLoader.loadZone('sua-zone-id');
// Ou carregar com dados de mídia específicos
await bannerLoader.loadBanner(mediaData);🎯 Exemplos
React/Next.js
import { useEffect, useRef } from 'react';
import { ArtemisAdsBannerLoader } from '@akross/artemis-ads-sdk';
export default function BannerAd({ zoneId }) {
const bannerRef = useRef(null);
useEffect(() => {
if (bannerRef.current) {
const loader = new ArtemisAdsBannerLoader(bannerRef.current);
loader.loadZone(zoneId);
}
}, [zoneId]);
return <div ref={bannerRef} style={{ width: '300px', height: '250px' }} />;
}Vanilla JavaScript
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/@akross/artemis-ads-sdk/dist/akross-ads-sdk.umd.js"></script>
</head>
<body>
<div id="banner-container" style="width: 300px; height: 250px;"></div>
<script>
const bannerLoader = new window.AkrossAds.ArtemisAdsBannerLoader('#banner-container');
bannerLoader.loadZone('sua-zone-id');
</script>
</body>
</html>Via Script Tag (IIFE)
<script src="https://cdn.akross.com/sdk/akross-ads-sdk.iife.js"></script>
<script>
(async function() {
const SDK_CONFIG = {
baseUrl: 'https://ads.timfun.com.br/adserver/',
debug: true,
timeout: 10000,
appId: 'com.example.myapp',
appVersion: '1.0.0',
artemisAdsAppId: 'akross-app-123',
primaryColor: '#ff0000',
luminaToken: 'QQDCYMdFh2AJqwP'
};
const sdk = await window.AkrossAds.init(SDK_CONFIG);
// Banner: usar ArtemisAdsBannerLoader
const bannerLoader = new window.AkrossAds.ArtemisAdsBannerLoader('#ad-container');
await bannerLoader.loadZone('sua-zone-id');
})();
</script>Via ES Modules
import { init } from '@akross/artemis-ads-sdk';
const SDK_CONFIG = {
baseUrl: 'https://ads.timfun.com.br/adserver/',
debug: true,
timeout: 10000,
appId: 'com.example.myapp',
appVersion: '1.0.0',
artemisAdsAppId: 'akross-app-123',
primaryColor: '#ff0000',
luminaToken: 'QQDCYMdFh2AJqwP'
};
const sdk = await init(SDK_CONFIG);Via CommonJS/UMD
const { init } = require('@akross/artemis-ads-sdk');
const SDK_CONFIG = {
baseUrl: 'https://ads.timfun.com.br/adserver/',
debug: true,
timeout: 10000,
appId: 'com.example.myapp',
appVersion: '1.0.0',
artemisAdsAppId: 'akross-app-123',
primaryColor: '#ff0000',
luminaToken: 'QQDCYMdFh2AJqwP'
};
const sdk = await init(SDK_CONFIG);📚 API Reference
ArtemisAdsBannerLoader
Métodos
loadZone(zoneId: string, userKeyType?: string): Carrega banner por Zone IDloadBanner(media: any): Carrega banner com dados de mídia específicossetSuccessListener(listener): Define callback de sucessosetErrorListener(listener): Define callback de errosetClickListener(listener): Define callback de cliquedestroy(): Destrói a instância e limpa recursos
Listeners
interface ArtemisAdsBannerLoaderSuccessListener {
onSuccess(analyticsTag?: string): void;
}
interface ArtemisAdsBannerLoaderErrorListener {
onError(message: string): void;
}
interface ArtemisAdsBannerLoaderClickListener {
onClick(analyticsTag?: string): void;
}API Principal
Inicialização
const SDK_CONFIG = {
baseUrl: 'https://ads.timfun.com.br/adserver/',
debug: true,
timeout: 10000,
appId: 'com.example.myapp', // ID da aplicação (equivalente ao package name do Android)
appVersion: '1.0.0', // Versão da aplicação
artemisAdsAppId: 'akross-app-123', // ID do app Artemis Ads
primaryColor: '#ff0000', // Cor primária do projeto (formato hexadecimal)
luminaToken: 'QQDCYMdFh2AJqwP' // Token do Lumina SDK (opcional - usa valor padrão se não fornecido)
};
const sdk = await window.AkrossAds.init(SDK_CONFIG);Campanhas e Banner
// Solicitar campanhas por zone
const response = await sdk.requestCampaign('sua-zone-id', 1);
// Banner: usar ArtemisAdsBannerLoader
const bannerLoader = new window.AkrossAds.ArtemisAdsBannerLoader('#container');
await bannerLoader.loadZone('sua-zone-id');Rewarded Video e mídias
// Mídias (VAST, programático, survey, etc.) são executadas via AAMedia.click()
// O fluxo típico: requestCampaign -> escolher mídia -> media.click()
const campaigns = await sdk.requestCampaign('zone-rv', 1);
const media = campaigns?.zones?.[0]?.campaigns?.[0]?.content;
if (media) {
const result = await media.click();
}Tratamento de Erros
A partir da 3.7.13, os três pontos públicos da SDK (init, requestCampaign e banner) propagam falhas com mensagens descritivas e auto-suficientes — prontas para envio direto ao Sentry, Crashlytics ou analytics. Toda mensagem carrega causa, status HTTP, zoneId e URL quando aplicável, então o host não precisa inspecionar campos estruturados.
Veículos por entry point:
| Entry point | Como o erro chega |
|---------------------|----------------------------------------------------------|
| AkrossAds.init | Promise rejeita com Error nativo (error.message) |
| requestCampaign | result.error: string \| null no objeto retornado |
| Banner | errorListener.onError(message: string) |
init — Promise<AkrossAdsSDK> rejeita em falha:
try {
const sdk = await window.AkrossAds.init(SDK_CONFIG);
} catch (error) {
// error.message ex.: "Artemis Ads SDK initialization failed: disk full"
Sentry.captureException(error);
}requestCampaign — verificar result.error:
const result = await sdk.requestCampaign('zone-abc', 1);
if (result.error) {
// Mensagem completa, carregando causa e zoneId:
// "Artemis Ads SDK HTTP error 500 for zone zone-abc."
// "Artemis Ads SDK network error for zone zone-abc: Failed to fetch"
Sentry.captureMessage(result.error);
return;
}
// Caminho feliz: result.campaignResponse?.campaignsBanner — onError(message) recebe a mensagem direto:
bannerLoader.setErrorListener({
onError: (message) => {
// ex.: "Artemis Ads SDK failed to load image from https://cdn.example.com/x.jpg: Failed to fetch"
Sentry.captureMessage(message);
}
});Catálogo de mensagens (paridade textual com Android 3.7.13):
| Cenário | Substring estável |
|--------------------------------------------------------|-------------------------------------------------|
| SDK chamada antes do init concluir | was not initialized |
| init lançou em algum passo interno | initialization failed |
| requestCampaign sem setUserId prévio | userId is not set |
| Adserver respondeu HTTP fora de 2xx | HTTP error <code> + for zone <zoneId> |
| Falha de rede / CORS / DNS em requestCampaign | network error |
| Banner falhou ao baixar/decodificar a imagem | failed to load image (+ a URL) |
| Exceção inesperada não coberta acima | unexpected error |
Hosts que precisam filtrar erros no Crashlytics/Sentry devem usar message.includes('<substring>') — as substrings são estáveis entre versões.
Publisher Provided ID (PPID)
Quando enableGPTPpid: true, o SDK envia automaticamente um PPID ao Google Ad Manager via GPT para frequency capping, segmentação de audiência e targeting.
O Google Ad Manager exige PPIDs com 32–150 caracteres. Como userIds internos geralmente não atingem 32 chars, o SDK deriva o PPID via SHA-256 do userId (hex de 64 chars), garantindo conformidade. O hash é determinístico: o mesmo userId sempre gera o mesmo PPID, preservando frequency capping entre sessões.
// Uso automático — basta ligar enableGPTPpid na config
const sdk = await init({
baseUrl: 'https://ads.timfun.com.br/adserver/',
enableGPTPpid: true,
// ...
});
await sdk.setUserId('user_12345');
// PPID derivado automaticamente: SHA-256("user_12345") = "d04c992200c84b44..."Se você já possui um PPID canônico de 32–150 chars, use o escape hatch:
sdk.setPublisherProvidedId('seu-ppid-canonico-com-32-ou-mais-chars');O PPID também é restaurado automaticamente entre sessões: se o userId já está persistido e enableGPTPpid está ligado, o SDK aplica o PPID no GPT durante o initialize(), sem necessidade de chamar setUserId novamente.
🔧 Configuração
Configuração do SDK
Exemplo de configuração (como no sample e na inicialização real):
const SDK_CONFIG = {
baseUrl: 'https://ads.timfun.com.br/adserver/',
debug: true,
timeout: 10000,
appId: 'com.example.myapp', // ID da aplicação (equivalente ao package name do Android)
appVersion: '1.0.0', // Versão da aplicação
artemisAdsAppId: 'akross-app-123', // ID do app Artemis Ads
primaryColor: '#ff0000', // Cor primária do projeto (formato hexadecimal)
luminaToken: 'QQDCYMdFh2AJqwP', // Token do Lumina SDK (opcional - usa valor padrão se não fornecido)
proxyExternalScripts: false, // Carregar scripts externos (GPT, IMA, Lumina) via proxy (opcional)
enableGPTPpid: true // Enviar SHA-256 do userId como PPID para Google Ads via GPT (opcional)
};Interface TypeScript:
interface SDKConfig {
baseUrl: string;
timeout?: number;
debug?: boolean;
appId?: string;
appVersion?: string;
artemisAdsAppId?: string;
primaryColor?: string;
luminaToken?: string;
proxyExternalScripts?: boolean;
enableGPTPpid?: boolean; // Envia SHA-256 do userId como PPID para Google Ads via GPT
cdnBaseUrl?: string;
}Configuração de Mídia
interface MediaData {
uuid: string;
type: 'image' | 'video_v2' | 'programatica_v2' | 'survey_v2' | 'external_redirect';
title: string;
content: {
url?: string;
// Para external_redirect:
externalRedirect?: {
link: string;
infoPrimary?: string;
infoSecondary?: string;
actionButtonLabel?: string;
thumbnail?: string;
};
// Ou formato antigo (compatibilidade temporária):
link?: string;
infoPrimary?: string;
infoSecondary?: string;
actionButtonLabel?: string;
thumbnail?: string;
};
externalUrl?: {
url: string;
};
analytics?: {
impression: string;
click: string;
};
}📱 Tipos de Mídia Suportados
O SDK suporta os seguintes tipos de mídia:
1. Banner (image)
Exibe banners de imagem estática.
const media = new AAMedia({
type: 'image',
content: { url: 'https://example.com/banner.png' }
});
await bannerLoader.loadBanner(media);2. Video V2 (video_v2)
Reproduz vídeos VAST, VPAID ou IN_HOUSE com suporte a pesquisa. Sem conectividade ou quando o IMA SDK não carrega, o player usa fallback com @dailymotion/vast-client (apenas mídia linear em <video>).
const media = new AAMedia({
type: 'video_v2',
content: {
video: { type: 'VAST', url: 'https://example.com/vast.xml' }
}
});
const result = await media.click();3. Programático V2 (programatica_v2)
Anúncios programáticos com waterfall (GAM, MAX, etc.).
const media = new AAMedia({
type: 'programatica_v2',
content: {
programmatic: {
waterfall: [{ type: 'GAM_RV', params: [...] }]
}
}
});
const result = await media.click();4. Survey V2 (survey_v2)
Pesquisas e surveys interativas.
const media = new AAMedia({
type: 'survey_v2',
content: {
survey: { url: 'https://example.com/survey' }
}
});
const result = await media.click();5. External Redirect (external_redirect) ⭐ Novo
Redirecionamento externo sem interface. O SDK retorna um resultado indicando que o cliente deve redirecionar o usuário.
const media = new AAMedia({
type: 'external_redirect',
content: {
externalRedirect: {
link: 'https://example.com/redirect',
infoPrimary: 'Instalação do aplicativo',
infoSecondary: 'Instale e ganhe recompensas!',
actionButtonLabel: 'Instalar',
thumbnail: 'https://example.com/thumbnail.png'
}
}
});
const result = await media.click();
if (result.result === AAMediaPlayResult.EXTERNAL_REDIRECT) {
// Buscar URL de redirecionamento do objeto media
const redirectUrl = result.media.content?.externalRedirect?.link
|| result.media.content?.link; // Formato antigo
// O cliente decide como fazer o redirecionamento
window.open(redirectUrl, '_blank', 'noopener,noreferrer');
// ou
window.location.href = redirectUrl;
}Características do External Redirect:
- ✅ Não exibe interface própria
- ✅ Envia apenas evento de clique (sem impressão)
- ✅ Retorna
AAMediaPlayResult.EXTERNAL_REDIRECT(26) - ✅ Cliente é responsável por implementar o redirecionamento
- ✅ Suporta formato antigo (campos diretamente em
content) e novo (content.externalRedirect)
Formato do objeto (novo):
{
"type": "external_redirect",
"content": {
"externalRedirect": {
"link": "https://example.com/redirect",
"infoPrimary": "Título",
"infoSecondary": "Descrição",
"actionButtonLabel": "Instalar",
"thumbnail": "https://example.com/image.png"
}
}
}Formato antigo (compatibilidade temporária):
{
"type": "external_redirect",
"content": {
"link": "https://example.com/redirect",
"infoPrimary": "Título",
"infoSecondary": "Descrição",
"actionButtonLabel": "Instalar",
"thumbnail": "https://example.com/image.png"
}
}🏗️ Builds Disponíveis
📦 Formatos de Build
Após executar npm run build:release, os seguintes arquivos serão gerados em dist/:
1. UMD (akross-ads-sdk.umd.js)
- Uso: NPM, Node.js, bundlers
- Tamanho: ~70KB (minificado)
- Sourcemap: ❌ (release)
2. IIFE (akross-ads-sdk.iife.js)
- Uso: CDN, HTML direto
- Tamanho: ~69KB (minificado)
- Sourcemap: ❌ (release)
3. ESM (akross-ads-sdk.esm.js)
- Uso: Sites modernos, import/export
- Tamanho: ~67KB (minificado)
- Sourcemap: ❌ (release)
4. Min (akross-ads-sdk.min.js) - RELEASE ONLY
- Uso: CDN público, máxima performance
- Tamanho: ~69KB (ultra-minificado)
- Sourcemap: ❌
- Otimizações: Máxima compressão, sem console.log
5. Types (index.d.ts)
- Uso: TypeScript definitions
- Tamanho: ~1KB
📊 Comparação de Tamanhos
| Build | Tamanho | Sourcemap | Console | Uso | |-------|---------|-----------|---------|-----| | Dev | ~500KB | ✅ | ✅ | Desenvolvimento | | Prod | ~150KB | ❌ | ❌ | Teste | | Release | ~70KB | ❌ | ❌ | Produção |
⚡ Otimizações de Release
✅ Otimizações Aplicadas
- Minificação: Terser com 2-3 passadas
- Console: Removido em produção (
drop_console: true) - Comentários: Removidos (
removeComments: true) - Sourcemaps: Desabilitados para release
- Mangle: Variáveis e propriedades privadas
- Dead Code: Eliminação de código não utilizado
- Tree Shaking: Automático via Rollup
🎯 Performance
- Tamanho: ~70KB gzipped
- Load time: <100ms
- Memory: <2MB
- Compatibility: IE11+
🧪 Sample
🚀 Como executar o Sample
1. Desenvolvimento com Live Reload
# Executa build em watch mode + live-server
npm run dev
# Acesse: http://localhost:30002. Build Automático do Sample
# Build automático (recomendado)
npm run build:sample
# Servir sample localmente
cd sample
python -m http.server 8000
# ou
npx serve sample
# Acesse: http://localhost:80003. Build Manual do Sample
# 1. Gerar build do SDK
npm run build:release
# 2. Copiar build para sample
cp dist/akross-ads-sdk.iife.js sample/
# 3. Servir sample localmente
cd sample
python -m http.server 8000
# ou
npx serve sample
# Acesse: http://localhost:80004. Sample com Build de Desenvolvimento
# Build com sourcemaps (para debug)
npm run build:dev
# Copiar para sample
cp dist/akross-ads-sdk.iife.js sample/
# Servir sample
npx serve sample🎯 Funcionalidades do Sample
A sample inclui:
- Gerenciamento de Usuário: Definir userId, headers customizados
- Gerenciamento de Anúncios: Solicitar campanhas, testar mídias
- Testes de Mídias: VAST, VPAID, Programático, Banner, Survey V2, External Redirect
- Banner Loader: Teste de diferentes tamanhos de banner
- Interface Interativa: Botões para testar todas as funcionalidades
- Logs em Tempo Real: Console com logs detalhados
- Configurações Dinâmicas: Alterar parâmetros em tempo real
📁 Estrutura do Sample
sample/
├── index.html # Interface principal
├── demo.js # Lógica da sample
├── akross-ads-sdk.iife.js # SDK build (copiado do dist/)
└── styles/ # CSS (se houver)🔧 Configuração do Sample
O sample usa configurações padrão que podem ser alteradas em demo.js:
const SDK_CONFIG = {
baseUrl: 'https://ads.timfun.com.br/adserver/',
debug: true,
timeout: 10000,
appId: 'com.example.myapp', // ID da aplicação (equivalente ao package name do Android)
appVersion: '1.0.0', // Versão da aplicação
artemisAdsAppId: 'akross-app-123', // ID do app Artemis Ads
primaryColor: '#ff0000', // Cor primária do projeto (formato hexadecimal)
luminaToken: 'QQDCYMdFh2AJqwP' // Token do Lumina SDK (opcional - usa valor padrão se não fornecido)
};🛠️ Desenvolvimento
📋 Scripts Disponíveis
🔧 Desenvolvimento
# Instalar dependências
npm install
# Build de desenvolvimento (com sourcemaps e logs)
npm run build:dev
# Build em modo watch
npm run build:watch
# Desenvolvimento com live-server
npm run dev
# Limpar build
npm run clean
# Verificar tipos
npm run type-check
# Linting
npm run lint
npm run lint:fix🏭 Produção
# Build de produção (minificado, sem sourcemaps)
npm run build:prod
# Build de release (ultra-otimizado)
npm run build:release
# Testar build
npm run test:build
# Build completo (limpeza + build + verificação)
npm run prepublishOnly📦 Publicação NPM
# Publicar patch (3.4.0.1 -> 3.4.0.2)
npm run publish:patch
# Publicar minor (3.4.0.1 -> 3.4.1.0)
npm run publish:minor
# Publicar major (3.4.0.1 -> 4.0.0.0)
npm run publish:major
# Testar pacote localmente
npm pack🛠️ Estrutura do Projeto
📁 Estrutura Principal
src/
├── ads-core/ # Core do sistema de anúncios
│ ├── AdsManager.ts # Gerenciador principal de anúncios
│ ├── index.ts
│ └── util/ # Utilitários do core
│ ├── AADeviceContextHelper.ts
│ └── index.ts
├── core/
│ ├── AAManager.ts # Gerenciador principal do SDK
│ └── network/ # Camada de rede
│ ├── ApiFactory.ts # Factory para APIs
│ ├── ServicesAds.ts # Serviços de anúncios
│ └── interceptor/ # Interceptadores HTTP
├── events/
│ └── AAEventsCallbackHelper.ts # Helper para eventos
├── modules/ # Módulos específicos
│ ├── image/ # Banner Loader
│ │ └── ArtemisAdsBannerLoader.ts
│ ├── rv/ # Rewarded Video
│ │ ├── programmatic/ # Anúncios programáticos (waterfall)
│ │ │ ├── AARewardedVideo.ts
│ │ │ ├── GAMRewardedVideoWrapper.ts
│ │ │ ├── LuminaRewardedVideoWrapper.ts # Kwai Lumina RV
│ │ │ └── utils/
│ │ │ └── WaterfallResultHelper.ts
│ │ └── vast/ # Player VAST
│ │ ├── AAVastPlayer.ts
│ │ ├── AAVastPlayerUI.ts
│ │ └── VastFallbackPlayer.ts # Fallback VAST (vast-client) sem IMA
│ ├── poll/ # Survey V2
│ │ └── AASurveyOverlay.ts
│ └── external_redirect/ # External Redirect
│ └── AAExternalRedirect.ts
├── types/ # Definições TypeScript
│ ├── ArtemisSdkConfig.ts # Configurações do SDK
│ └── models/ # Modelos de dados
│ ├── AAMedia.ts
│ ├── AACampaign.ts
│ └── ... (outros modelos)
├── utils/ # Utilitários gerais
│ ├── AAMediaResultHelper.ts # Helper para resultados
│ ├── DeviceUtil.ts
│ ├── ExternalJsLoader.ts # Carregamento de scripts (GPT, IMA, Lumina)
│ ├── GlobalLoadingOverlay.ts
│ ├── GPTPublisherProvidedId.ts # PPID: derivação, persistência e envio ao GPT
│ ├── logger.ts # Sistema de logging
│ ├── PreferencesUtil.ts
│ ├── sha256.ts # SHA-256 puro-JS (para derivação de PPID)
│ ├── version.ts
│ └── index.ts
└── index.ts # Ponto de entrada principal📁 Build Output
dist/
├── akross-ads-sdk.umd.js # UMD (NPM)
├── akross-ads-sdk.iife.js # IIFE (CDN)
├── akross-ads-sdk.esm.js # ESM (moderno)
├── akross-ads-sdk.min.js # Ultra-min (release)
├── index.d.ts # TypeScript definitions
├── ads-core/ # Definições do core
├── core/ # Definições do core
├── events/ # Definições de eventos
├── modules/ # Definições dos módulos
├── types/ # Definições de tipos
└── utils/ # Definições de utilitários📁 Sample
sample/
├── index.html # Interface da sample
├── demo.js # Lógica da sample
├── akross-ads-sdk.iife.js # SDK build (copiado)
└── styles/ # CSS (se houver)🔧 Configurações de Build
rollup.config.js # Configuração principal
rollup.simple.release.config.js # Configuração de release
tsconfig.json # Configuração TypeScript
package.json # Dependências e scripts
.npmignore # Arquivos ignorados no NPM
setup-npm.js # Script de configuração NPM📋 Tipos TypeScript
interface AdConfig {
adId: string;
slotId: string;
adServerUrl: string;
dimensions?: { width: number; height: number };
options?: Record<string, any>;
}
interface AdResponse {
success: boolean;
html?: string;
imageUrl?: string;
clickUrl?: string;
dimensions?: { width: number; height: number };
error?: string;
}
interface SDKConfig {
baseUrl: string;
timeout?: number;
debug?: boolean;
appId?: string;
appVersion?: string;
artemisAdsAppId?: string;
primaryColor?: string;
luminaToken?: string;
proxyExternalScripts?: boolean;
enableGPTPpid?: boolean; // Envia SHA-256 do userId como PPID para Google Ads via GPT
cdnBaseUrl?: string;
}🚀 Deploy
NPM
npm run build:release
npm publishCDN
npm run build:release
# Usar: dist/akross-ads-sdk.min.jsSites
npm run build:prod
# Usar: dist/akross-ads-sdk.iife.js📄 Licença
MIT License - veja o arquivo LICENSE para detalhes.
🤝 Contribuição
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/AmazingFeature) - Commit suas mudanças (
git commit -m 'Add some AmazingFeature') - Push para a branch (
git push origin feature/AmazingFeature) - Abra um Pull Request
