API du pont JavaScript
Publicités
Afficher une publicité interstitielle ou avec récompense à votre propre signal, et indiquer à l'application quand une navigation démarre et se termine pour qu'elle n'en interrompe pas une.
AppMintAds.appOpen assistant#
window.AppMintAds.appOpen.setEnabled(on)
Exemple
Met en pause ou reprend la publicité d'ouverture d'application, la publicité plein écran affichée au lancement et au retour de l'utilisateur depuis une autre application.
Retourne : rien. Nécessite : Contrôle des publicités → Géré par le développeur et un ID de bloc d'annonces d'ouverture d'application.
Mettez-la en pause pendant que l'utilisateur quitte volontairement l'application un court instant (une application de paiement, l'appareil photo, une feuille de partage), afin qu'une publicité ne s'affiche pas à son retour :
var ads = window.AppMintAds;
async function payWithUpi(link) {
if (ads) ads.appOpen.setEnabled(false);
try {
await openPaymentApp(link); // your own code; the user switches apps and returns
} finally {
if (ads) ads.appOpen.setEnabled(true);
}
}Vérifiez si la compilation a un bloc d'ouverture d'application :
var hasAppOpen = !!(window.AppMintAds && window.AppMintAds.config().formats.app_open);Mettez-la en pause pendant que l'utilisateur choisit une photo, car le sélecteur de photos du système le fait sortir un instant de l'application :
var ads = window.AppMintAds;
var input = document.getElementById('photo-input'); // <input type="file" accept="image/*" hidden>
var pausedForPicker = false;
document.getElementById('pick-photo').addEventListener('click', function () {
if (ads) { ads.appOpen.setEnabled(false); pausedForPicker = true; }
input.click();
});
input.addEventListener('change', function () {
if (input.files[0]) uploadPhoto(input.files[0]); // your own code
});
// Back in the app (a photo was picked or the picker was cancelled): turn it on again.
document.addEventListener('visibilitychange', function () {
if (document.hidden || !pausedForPicker) return;
pausedForPicker = false;
setTimeout(function () { ads.appOpen.setEnabled(true); }, 1000);
});Remarques : Activée par défaut. Au démarrage à froid, la publicité s'affiche quand la page est prête, ou quand elle finit de charger dans les 15 secondes ; un chargement plus tardif est gardé pour la prochaine fois. Une publicité d'ouverture d'application de plus de 4 heures n'est jamais affichée. Vous pouvez aussi en afficher une vous-même avec AppMintAds.show('app_open').
AppMintAds.banner assistant#
window.AppMintAds.banner.attach(target, opts) / .detach(slotOrElement)
Exemple
Place une bannière ou une publicité rectangle moyen 300×250 n'importe où dans votre page, au-dessus d'un élément de votre choix.
Retourne : attach retourne une Promise de {ok:true, slot, width, height} (px CSS) une fois la publicité chargée, ou {ok:false, slot?, code, message?}. detach ne retourne rien. Nécessite : Contrôle des publicités → Géré par le développeur et un ID de bloc d'annonces de bannière (ou de rectangle moyen).
L'élément ne fait que réserver l'espace. La publicité est dessinée par-dessus et le suit quand la page défile ou est redimensionnée :
<div id="ad-slot"></div>
<script>
var ads = window.AppMintAds;
var slotEl = document.getElementById('ad-slot');
if (ads) {
ads.banner.attach(slotEl, { size: 'banner' }).then(function (res) {
// On success the helper sets slotEl.style.minHeight to res.height (pass keepHeight:true to stop that).
if (!res.ok) { // no_fill, network, too_many_slots, ...
if (res.slot) ads.banner.detach(res.slot); // a failed slot still counts toward the limit of two
slotEl.hidden = true;
}
});
} else {
slotEl.hidden = true; // browser: no ads here
}
</script>Rectangle moyen (un à la fois), et retrait d'une bannière :
var box = document.querySelector('.article-end-ad');
var mrecSlot = null;
if (window.AppMintAds) {
window.AppMintAds.banner.attach(box, { size: 'medium_rectangle' }).then(function (res) {
if (res.ok) mrecSlot = res.slot;
else { if (res.slot) window.AppMintAds.banner.detach(res.slot); box.hidden = true; }
});
}
function leaveArticle() {
if (window.AppMintAds && mrecSlot) window.AppMintAds.banner.detach(mrecSlot); // or detach(box)
mrecSlot = null;
}Réessayez un emplacement plus tard quand aucune publicité n'était disponible, en libérant d'abord l'emplacement en échec pour qu'il ne compte pas parmi les deux :
function fillSlot(el, triesLeft) {
var ads = window.AppMintAds;
if (!ads) { el.hidden = true; return; } // browser: no ads here
ads.banner.attach(el, { size: 'banner' }).then(function (res) {
if (res.ok) return;
if (res.slot) ads.banner.detach(res.slot);
if ((res.code === 'no_fill' || res.code === 'network') && triesLeft > 0) {
setTimeout(function () { fillSlot(el, triesLeft - 1); }, 60000);
} else {
el.hidden = true; // ad_free, disabled, consent, ...
}
});
}
fillSlot(document.getElementById('footer-ad'), 2);Remarques : target est un élément ou un sélecteur CSS ; size vaut 'banner' (par défaut, largeur adaptative, 90 dp de haut au maximum), 'medium_rectangle' ou 'mrec'. Au plus deux emplacements à la fois, et un emplacement dont la publicité n'a pas pu se charger compte encore jusqu'à ce que vous le détachiez. detach nécessite l'élément ou l'ID d'emplacement retourné par attach, pas un sélecteur. Retirer l'élément du DOM le détache aussi. Codes : no_element, duplicate_slot, too_many_slots, detached, no_fill, network, invalid_unit, ad_free, disabled, consent, automatic_mode, internal.
AppMintAds.config assistant#
window.AppMintAds.config()
Exemple
Indique à la page quel mode de contrôle des publicités la compilation utilise et quels formats elle peut diffuser.
Retourne : un objet, de façon synchrone : {control: 'automatic' | 'developer', formats: {banner, mrec, interstitial, rewarded, rewarded_interstitial, app_open}} (chaque format true / false). En cas d'erreur interne, il retourne {control:'automatic', formats:{}}. Nécessite : rien ; window.AppMintAds n'existe que dans l'application installée.
Affichez uniquement l'interface publicitaire que cette compilation peut vraiment diffuser :
var ads = window.AppMintAds; // undefined in a browser
var cfg = ads ? ads.config() : null;
var developer = !!(cfg && cfg.control === 'developer');
document.getElementById('watch-ad').hidden = !(developer && cfg.formats.rewarded);
document.getElementById('ad-slot').hidden = !(developer && cfg.formats.banner);Choisissez le format avec récompense dont la compilation dispose pour un bouton « bonus », et masquez le bouton si elle n'en a aucun :
var ads = window.AppMintAds;
var cfg = ads ? ads.config() : null;
var bonusBtn = document.getElementById('bonus');
var bonusType = null;
if (cfg && cfg.control === 'developer') {
if (cfg.formats.rewarded) bonusType = 'rewarded';
else if (cfg.formats.rewarded_interstitial) bonusType = 'rewarded_interstitial';
}
bonusBtn.hidden = !bonusType;
bonusBtn.addEventListener('click', async function () {
var res = await ads.show(bonusType); // inside the tap: plays at once
if (res.earned) addCoins(res.reward.amount);
});Choisissez la taille de publicité pour la fin d'un article : un rectangle moyen si la compilation en a un, sinon une bannière :
var ads = window.AppMintAds;
var cfg = ads ? ads.config() : null;
var box = document.getElementById('article-end-ad');
var size = null;
if (cfg && cfg.control === 'developer') {
size = cfg.formats.mrec ? 'medium_rectangle' : (cfg.formats.banner ? 'banner' : null);
}
if (!size) box.hidden = true;
else ads.banner.attach(box, { size: size }).then(function (res) {
if (!res.ok) { if (res.slot) ads.banner.detach(res.slot); box.hidden = true; }
});Remarques : Un format vaut true lorsque les publicités sont activées et que la compilation a un ID de bloc d'annonces pour lui. En mode automatique (control: 'automatic'), chaque appel load / show / banner.attach répond code: 'automatic_mode' ; utilisez WebToApk.showRewardedAd() / showInterstitialAd() à la place. Choisissez Contrôle des publicités → Géré par le développeur dans l'assistant de compilation pour piloter les publicités depuis la page.
AppMintAds.isReady assistant#
window.AppMintAds.isReady(type)
Exemple
Indique si une publicité plein écran de ce type est chargée et peut être affichée tout de suite.
Retourne : true / false, de façon synchrone. type : 'interstitial', 'rewarded', 'rewarded_interstitial' ou 'app_open'. Nécessite : Contrôle des publicités → Géré par le développeur et un ID de bloc d'annonces pour ce type.
Gardez un bouton « Regarder la publicité » synchronisé avec la publicité grâce à l'événement d'état appmint:ad :
var ads = window.AppMintAds;
var btn = document.getElementById('watch-ad');
function refresh() { btn.disabled = !(ads && ads.isReady('rewarded')); }
if (ads) {
refresh();
window.addEventListener('appmint:ad', function (e) {
if (e.detail.type === 'rewarded') refresh(); // phases: loaded, failed, closed, ...
});
} else {
btn.hidden = true; // browser: no ads here
}Proposez « doublez vos pièces » sur l'écran de résultats uniquement lorsqu'une publicité avec récompense est déjà prête :
function showResults(coins) {
var ads = window.AppMintAds;
var offer = document.getElementById('double-coins');
renderResults(coins); // your own screen
offer.hidden = !(ads && ads.isReady('rewarded'));
offer.onclick = async function () {
offer.hidden = true;
var res = await ads.show('rewarded'); // inside the tap: plays at once
addCoins(res.earned ? coins : 0); // the bonus: the same amount again
};
}Dans un bouton d'indice, lancez le format avec récompense actuellement chargé :
document.getElementById('hint').addEventListener('click', async function () {
var ads = window.AppMintAds;
if (!ads) return; // browser: no ads here
var type = ads.isReady('rewarded') ? 'rewarded'
: ads.isReady('rewarded_interstitial') ? 'rewarded_interstitial'
: null;
if (!type) { showMessage('No hint video right now. Try again in a minute.'); return; }
var res = await ads.show(type);
if (res.earned) revealHint();
});Remarques : banner et mrec répondent toujours false (elles sont attachées, pas affichées). Une interstitielle dans son délai de 60 secondes répond false ; une publicité d'ouverture d'application de plus de 4 heures répond false. En mode automatique, c'est toujours false.
AppMintAds.load assistant#
window.AppMintAds.load(type)
Exemple
Charge une publicité plein écran pour qu'un show(type) ultérieur puisse la lancer immédiatement.
Retourne : une Promise qui se résout (sans jamais être rejetée) avec {ok:true}, {ok:true, cached:true} quand une publicité est déjà prête, ou {ok:false, code, reason, message?, adCode?}. Nécessite : Contrôle des publicités → Géré par le développeur et un ID de bloc d'annonces pour ce type (interstitial, rewarded, rewarded_interstitial, app_open).
var ads = window.AppMintAds;
var btn = document.getElementById('watch-ad');
btn.disabled = true;
async function prepareRewarded() {
if (!ads) { btn.hidden = true; return; } // browser: no ads
var res = await ads.load('rewarded');
if (res.ok) { btn.disabled = false; return; }
if (res.code === 'no_fill' || res.code === 'network') setTimeout(prepareRewarded, 30000);
else console.log('rewarded ad unavailable:', res.code, res.message);
}
prepareRewarded();Toute la vie de chaque requête est aussi diffusée sur l'événement appmint:ad :
window.addEventListener('appmint:ad', function (e) {
var a = e.detail; // {type, phase, slot?, code?, adCode?, message?, width?, height?, reward?, earned?}
// phase: loading, loaded, failed, opened, impression, clicked, closed, rewarded, show_failed, opt_in, declined
if (a.phase === 'failed') console.log(a.type, 'failed to load:', a.code, a.adCode, a.message);
});
// The same object also goes to window.onAppMintAd, if you define that function.
window.onAppMintAd = function (a) { console.log('ad', a.type, a.phase); };Chargez l'interstitielle au début d'un niveau, pour qu'elle soit prête à la fin, et arrêtez de la demander une fois que l'utilisateur a supprimé les publicités :
var ads = window.AppMintAds;
var interstitialsOff = false;
async function startLevel(n) {
runLevel(n); // your own game
if (!ads || interstitialsOff) return;
var res = await ads.load('interstitial');
if (!res.ok && (res.code === 'ad_free' || res.code === 'disabled' || res.code === 'automatic_mode')) {
interstitialsOff = true; // no interstitials in this app session
}
}
async function levelEnded() {
if (ads && !interstitialsOff && ads.isReady('interstitial')) await ads.show('interstitial');
showLevelSummary();
}Remarques : Codes : no_fill, network, invalid_unit, internal (provenant d'AdMob), automatic_mode, unknown_type, ad_free, disabled, consent, et use_slot pour banner / mrec (utilisez AppMintAds.banner.attach). L'application précharge déjà chaque type plein écran disposant d'un ID de bloc et charge le suivant après chaque affichage ; load sert donc surtout à savoir quand le bouton peut être activé.
AppMintAds.show assistant#
window.AppMintAds.show(type)
Exemple
Affiche une publicité plein écran chargée : interstitial, rewarded, rewarded_interstitial ou app_open.
Retourne : une Promise qui se résout (sans jamais être rejetée) quand la publicité s'est fermée : {ok:true, shown:true, earned, reward?} (reward = {type, amount} pour les formats avec récompense), ou {ok:false, shown:false, code, reason, message?} quand rien n'a été affiché. Nécessite : Contrôle des publicités → Géré par le développeur et un ID de bloc d'annonces pour ce type.
Avec récompense : appelez-la dans l'appui de l'utilisateur. Cet appui est le consentement de l'utilisateur, donc la publicité démarre tout de suite. N'accordez la récompense que lorsque earned est vrai :
var ads = window.AppMintAds;
document.getElementById('watch-ad').addEventListener('click', async function () {
if (!ads) return; // browser: no ads here
var res = await ads.show('rewarded');
if (res.earned) addCoins(res.reward.amount);
else if (res.reason === 'ad_free') addCoins(50); // user paid to remove ads: reward anyway
else if (res.shown) showMessage('Watch to the end to get the reward.');
else if (res.reason !== 'declined') showMessage('No ad available right now.');
});Interstitielle : à une pause naturelle. Continuez quelle que soit la réponse :
async function levelFinished() {
if (window.AppMintAds && window.AppMintAds.isReady('interstitial')) {
await window.AppMintAds.show('interstitial'); // resolves when the ad closes
}
showNextLevel();
}Interstitielle avec récompense derrière votre propre écran d'introduction avec un « Non merci » clair. L'appui sur « Regarder » est le consentement :
var ads = window.AppMintAds;
var intro = document.getElementById('free-life-intro'); // your own dialog: Watch / No thanks
function offerFreeLife() {
if (ads && ads.isReady('rewarded_interstitial')) intro.hidden = false;
else gameOver();
}
document.getElementById('free-life-watch').addEventListener('click', async function () {
intro.hidden = true;
var res = await ads.show('rewarded_interstitial');
if (res.earned) continueWithExtraLife();
else gameOver();
});
document.getElementById('free-life-skip').addEventListener('click', function () {
intro.hidden = true;
gameOver();
});Remarques : Un show() de publicité avec récompense ou interstitielle avec récompense qui ne provient PAS d'un appui de l'utilisateur (minuteur, chargement de page, changement de route) affiche d'abord un écran « Regarder une publicité ? / Non merci », et « Non merci » répond declined. Ne déclenchez jamais ainsi des formats avec récompense. Autres codes : automatic_mode, unknown_type, ad_free, disabled, consent, not_full_screen, showing, cooldown (60 s entre deux interstitielles), not_loaded (un nouveau chargement démarre pour la prochaine fois), show_failed, internal. En mode automatique, utilisez WebToApk.showRewardedAd().
adsAppOpenEnable pont#
window.WebToApk.adsAppOpenEnable(enabled: Boolean)
Permet à la page de mettre en pause/reprendre la publicité d'ouverture d'application au retour d'une autre application (activée par défaut lorsqu'un bloc est défini).
Exemple
La moitié native de AppMintAds.appOpen.setEnabled(on) : elle met en pause ou reprend la publicité d'ouverture d'application. Les pages utilisent AppMintAds.appOpen.setEnabled.
Retourne : rien. Nécessite : Contrôle des publicités → Géré par le développeur et un ID de bloc d'annonces d'ouverture d'application.
function setAppOpenAds(on) {
if (window.AppMintAds) window.AppMintAds.appOpen.setEnabled(on);
}
// Pause while the user is in the middle of something, resume afterwards.
function startCheckout() { setAppOpenAds(false); showCheckout(); }
function checkoutDone() { setAppOpenAds(true); }Choisir une photo fait quitter l'application pour le sélecteur du système, et le retour compterait comme un retour dans l'application. Mettez la publicité d'ouverture d'application en pause autour de cette action :
var input = document.getElementById('photo');
function appOpenAds(on) {
if (window.AppMintAds) window.AppMintAds.appOpen.setEnabled(on);
}
input.addEventListener('click', function () { appOpenAds(false); });
function pickerDone() { setTimeout(function () { appOpenAds(true); }, 1000); }
input.addEventListener('change', pickerDone);
input.addEventListener('cancel', pickerDone);Les membres de votre propre offre payante ne la voient jamais. Le réglage n'est pas enregistré, donc définissez-le tôt à chaque lancement :
// Runs from a <head> script: window.AppMintAds is already there at document start.
var plan = null;
try { plan = localStorage.getItem('plan'); } catch (e) {}
if (window.AppMintAds && plan === 'pro') {
window.AppMintAds.appOpen.setEnabled(false);
}Remarques : Signature brute adsAppOpenEnable(enabled). Activée par défaut lorsqu'un bloc d'ouverture d'application est défini. La publicité d'ouverture d'application s'affiche au démarrage à froid (si elle se charge dans les 15 secondes) et quand l'utilisateur revient d'une autre application ; une publicité de plus de 4 heures n'est jamais affichée.
adsConfig pont#
window.WebToApk.adsConfig(): String
`{control, formats:{banner, mrec, interstitial, rewarded, rewarded_interstitial, app_open}}` : les formats de publicité que cette compilation peut diffuser.
Exemple
Lit les formats de publicité que cette compilation peut diffuser et le mode de contrôle des publicités utilisé. Les pages appellent normalement AppMintAds.config(), qui l'analyse pour vous.
Retourne : une chaîne JSON : {"control":"automatic"|"developer","formats":{"banner":bool,"mrec":bool,"interstitial":bool,"rewarded":bool,"rewarded_interstitial":bool,"app_open":bool}}. Un format vaut true lorsque les publicités sont activées et que la compilation a un ID de bloc d'annonces pour lui. Nécessite : rien.
D'abord l'API publique :
if (window.AppMintAds) {
var cfg = window.AppMintAds.config(); // already parsed; {control:'automatic', formats:{}} on error
if (cfg.control === 'developer' && cfg.formats.rewarded) {
document.getElementById('watch-ad').hidden = false;
}
}L'appel brut, si vous n'utilisez pas AppMintAds:
var b = window.WebToApk;
if (b && typeof b.adsConfig === 'function') {
try {
var cfg = JSON.parse(b.adsConfig());
console.log(cfg.control, cfg.formats);
} catch (e) { console.log('could not read ad config', e); }
}Ne réservez de l'espace que pour les formats que cette compilation possède vraiment, et rendez la boîte vide à la page sinon :
var box = document.getElementById('sidebar-ad');
var cfg = window.AppMintAds ? window.AppMintAds.config() : { control: 'automatic', formats: {} };
if (cfg.control === 'developer' && cfg.formats.mrec) {
window.AppMintAds.banner.attach(box, { size: 'mrec' });
} else if (cfg.control === 'developer' && cfg.formats.banner) {
window.AppMintAds.banner.attach(box, { size: 'banner' });
} else {
box.remove(); // browser, Automatic mode, or no unit: no empty gap
}Remarques : En mode automatique, formats vous indique encore quels blocs existent, mais AppMintAds.load/show répondent code: 'automatic_mode' ; utilisez WebToApk.showRewardedAd() / showInterstitialAd() à la place.
adsIsReady pont#
window.WebToApk.adsIsReady(type: String): Boolean
Vrai lorsqu'une publicité plein écran de ce [type] est chargée et peut être affichée tout de suite.
Exemple
Indique si une publicité plein écran d'un type est chargée et peut s'afficher maintenant (publicités gérées par le développeur). Les pages appellent normalement AppMintAds.isReady(type).
Retourne : true / false, de façon synchrone. type vaut 'interstitial', 'rewarded', 'rewarded_interstitial' ou 'app_open' ; 'banner' / 'mrec' répondent toujours false. Nécessite : Contrôle des publicités → Géré par le développeur et un ID de bloc d'annonces pour ce type.
D'abord l'API publique :
var watchBtn = document.getElementById('watch-ad');
function refresh() {
watchBtn.disabled = !(window.AppMintAds && window.AppMintAds.isReady('rewarded'));
}
refresh();
window.addEventListener('appmint:ad', refresh); // loaded / closed / failed all change readinessL'appel brut :
var b = window.WebToApk;
var ready = !!(b && typeof b.adsIsReady === 'function' && b.adsIsReady('interstitial'));Affichez une interstitielle à la fin d'un niveau uniquement lorsqu'une est prête, et ne retenez jamais le joueur quand ce n'est pas le cas :
function onLevelComplete() {
var ads = window.AppMintAds;
if (ads && ads.isReady('interstitial')) {
// resolves after the ad closes, or at once with {ok:false, code} if it could not show
ads.show('interstitial').then(startNextLevel);
} else {
startNextLevel(); // not loaded yet, or inside the 60-second cooldown
}
}Remarques : Une interstitielle dans son délai d'attente de 60 secondes répond false. Une publicité d'ouverture d'application de plus de 4 heures répond false (Google demande de ne pas l'afficher). En mode automatique, c'est toujours false ; utilisez WebToApk.isRewardedAdReady() à la place.
adsLoad pont#
window.WebToApk.adsLoad(type: String, callbackId: String)
Charge une publicité plein écran de ce [type] ; la promesse de [callbackId] se résout avec le résultat.
Exemple
La moitié native de AppMintAds.load(type) : elle lance le chargement d'une publicité plein écran et répond au rappel du shim. Les pages utilisent AppMintAds.load(type), qui retourne une Promise ; ne l'appelez pas directement.
Retourne : (via AppMintAds.load) une Promise de {ok:true}, {ok:true, cached:true} quand une publicité est déjà chargée, ou {ok:false, code, reason, message?, adCode?}. Nécessite : Contrôle des publicités → Géré par le développeur et un ID de bloc d'annonces pour ce type.
var watchBtn = document.getElementById('watch-ad');
watchBtn.disabled = true;
if (window.AppMintAds) {
window.AppMintAds.load('rewarded').then(function (res) {
if (res.ok) watchBtn.disabled = false;
else console.log('rewarded ad not loaded:', res.code, res.message);
});
} else {
watchBtn.hidden = true; // browser: there are no ads here
}Réessayez un chargement qui a échoué pour une raison passagère, et arrêtez-vous pour les raisons qu'un nouvel essai ne peut pas corriger :
function loadWithRetry(type, attempt) {
attempt = attempt || 0;
return window.AppMintAds.load(type).then(function (res) {
if (res.ok) return res;
if ((res.code === 'no_fill' || res.code === 'network') && attempt < 3) {
return new Promise(function (wait) { setTimeout(wait, 5000 * (attempt + 1)); })
.then(function () { return loadWithRetry(type, attempt + 1); });
}
return res; // invalid_unit, consent, ad_free, disabled ...
});
}
if (window.AppMintAds) {
loadWithRetry('rewarded').then(function (res) {
document.getElementById('watch-ad').disabled = !res.ok;
});
}Préchauffez deux formats avant le début d'une session de jeu et masquez tous les boutons de publicité quand l'utilisateur n'a plus aucune publicité :
if (window.AppMintAds) {
Promise.all([
window.AppMintAds.load('interstitial'),
window.AppMintAds.load('rewarded_interstitial')
]).then(function (results) {
var noAds = results.some(function (r) { return r.code === 'ad_free' || r.code === 'disabled'; });
if (noAds) hideAllAdButtons(); // paid to remove ads, or ads are off in this build
results.forEach(function (r) {
if (!r.ok && r.adCode !== undefined) console.log('ad load failed', r.code, r.adCode, r.message);
});
});
}Remarques : Codes d'échec : no_fill, network, invalid_unit, internal (provenant d'AdMob, avec adCode), et automatic_mode, unknown_type, ad_free, disabled, consent, et use_slot pour banner / mrec (ceux-ci se chargent avec AppMintAds.banner.attach). L'application précharge déjà chaque type plein écran disposant d'un ID de bloc et recharge après chaque affichage. La signature brute est adsLoad(type, callbackId) ; sa réponse va à un résolveur interne, donc un appel direct ne vous donne aucun résultat.
adsShow pont#
window.WebToApk.adsShow(type: String, callbackId: String, userGesture: Boolean)
Affiche une publicité plein écran chargée de ce [type] ; se résout à sa fermeture, avec earned/reward pour les formats avec récompense. [userGesture] est la lecture de `navigator.userActivation` par le shim : un format avec récompense demandé sans geste utilisateur affiche d'abord l'écran d'introduction d'AdMob (voir DeveloperAds.offerRewarded).
Exemple
La moitié native de AppMintAds.show(type) : elle affiche une publicité plein écran chargée et répond à sa fermeture. Les pages utilisent AppMintAds.show(type) ; ne l'appelez pas directement.
Retourne : (via AppMintAds.show) une Promise de {ok:true, shown:true, earned, reward?} après la fermeture de la publicité (reward = {type, amount} pour les formats avec récompense), ou {ok:false, shown:false, code, reason, message?}. Nécessite : Contrôle des publicités → Géré par le développeur et un ID de bloc d'annonces pour ce type.
Appelez-la depuis l'appui de l'utilisateur. Le shim passe navigator.userActivation.isActive comme troisième argument (userGesture):
document.getElementById('watch-ad').addEventListener('click', function () {
if (!window.AppMintAds) return;
window.AppMintAds.show('rewarded').then(function (res) {
if (res.earned) addCoins(res.reward.amount);
else if (res.reason === 'ad_free') addCoins(50); // paid to remove ads: reward anyway
else if (res.reason !== 'declined') showMessage('No ad available right now.');
});
});Proposez une interstitielle avec récompense à partir de l'appui de l'utilisateur sur « Doubler mon bonus », et poursuivez quelle que soit la réponse :
document.getElementById('double-bonus').addEventListener('click', function () {
if (!window.AppMintAds) return goToNextLevel();
window.AppMintAds.show('rewarded_interstitial').then(function (res) {
if (res.earned) doubleLevelBonus();
else if (!res.shown && res.code !== 'declined') console.log('no ad:', res.code);
goToNextLevel(); // shown or not, the player keeps going
});
});Mettez la musique de votre jeu en pause tant qu'une publicité plein écran est à l'écran, avec le flux appmint:ad :
window.addEventListener('appmint:ad', function (e) {
var d = e.detail; // {type, phase, code?, adCode?, message?, earned?, reward?}
if (d.type === 'banner' || d.type === 'mrec') return;
if (d.phase === 'opened') music.pause();
if (d.phase === 'closed' || d.phase === 'show_failed') music.play();
});
function onChapterSaved() {
if (window.AppMintAds) window.AppMintAds.show('interstitial'); // a natural break
}Remarques : Signature brute adsShow(type, callbackId, userGesture). Quand userGesture vaut false pour rewarded ou rewarded_interstitial, l'application demande d'abord « Regarder une publicité ? / Non merci » et un « non » répond declined. Autres codes : automatic_mode, unknown_type, ad_free, disabled, consent, not_full_screen, showing, cooldown (interstitielle, 60 s), not_loaded (un chargement démarre pour la prochaine fois), show_failed, internal.
adsSlotAttach pont#
window.WebToApk.adsSlotAttach(slotId: String, type: String, widthCss: Int, callbackId: String)
Crée une superposition bannière/mrec pour l'emplacement [slotId] de la page, dimensionnée selon [widthCss] ; se résout avec la taille de la publicité une fois chargée.
Exemple
La moitié native de AppMintAds.banner.attach(element, {size}) : elle crée une publicité bannière ou rectangle moyen au-dessus d'un élément de la page. Les pages utilisent AppMintAds.banner.attach ; ne l'appelez pas directement.
Retourne : (via AppMintAds.banner.attach) une Promise de {ok:true, slot, width, height} en pixels CSS une fois la publicité chargée, ou {ok:false, slot, code, message?}. Nécessite : Contrôle des publicités → Géré par le développeur et un ID de bloc d'annonces de bannière (ou de rectangle moyen).
<div id="ad-slot"></div>
<script>
if (window.AppMintAds) {
window.AppMintAds.banner.attach('#ad-slot', { size: 'banner' }).then(function (res) {
if (!res.ok) console.log('no banner:', res.code); // e.g. no_fill, network, too_many_slots
});
}
</script>Un rectangle moyen sur un écran de résultats qui libère son espace quand aucune publicité n'arrive :
var box = document.getElementById('result-ad');
if (window.AppMintAds) {
window.AppMintAds.banner.attach(box, { size: 'mrec' }).then(function (res) {
if (res.ok) return; // the box now has min-height = res.height
window.AppMintAds.banner.detach(res.slot); // free the slot for another banner
box.hidden = true;
if (res.code === 'too_many_slots') console.log('detach a banner first:', res.message);
});
} else {
box.hidden = true;
}Comptez les impressions et les clics par emplacement à partir du flux appmint:ad, avec pour clé l'ID d'emplacement retourné par attach :
var slotNames = {};
if (window.AppMintAds) {
window.AppMintAds.banner.attach('#footer-ad', { size: 'banner' }).then(function (res) {
if (res.ok) slotNames[res.slot] = 'footer';
});
}
window.addEventListener('appmint:ad', function (e) {
var d = e.detail; // banner events carry {type, phase, slot}
if (d.slot && (d.phase === 'impression' || d.phase === 'clicked')) {
track('ad_' + d.phase, slotNames[d.slot] || d.slot);
}
});Remarques : Signature brute adsSlotAttach(slotId, type, widthCss, callbackId) ; type vaut 'banner' ou 'mrec'. Une WebView ne peut pas contenir une vue native dans la page, donc la publicité est dessinée au-dessus de votre élément et le suit lors du défilement et du redimensionnement (voir adsSlotRect). Au plus deux emplacements à la fois, et un seul rectangle moyen. Codes supplémentaires : duplicate_slot, too_many_slots, detached, internal, plus les codes de chargement (no_fill, network, invalid_unit, ad_free, disabled, consent, automatic_mode).
adsSlotDetach pont#
window.WebToApk.adsSlotDetach(slotId: String)
Retire une superposition de bannière.
Exemple
La moitié native de AppMintAds.banner.detach(slotOrElement) : elle retire une superposition de bannière et libère son emplacement. Les pages utilisent AppMintAds.banner.detach.
Retourne : rien. Nécessite : Contrôle des publicités → Géré par le développeur.
Retirez la bannière avant un écran où une publicité n'a pas sa place (un lecteur vidéo, un paiement) :
var slotEl = document.getElementById('ad-slot');
function openPlayer() {
if (window.AppMintAds) window.AppMintAds.banner.detach(slotEl); // the element, or the slot id from attach()
showPlayer();
}
function closePlayer() {
hidePlayer();
if (window.AppMintAds) window.AppMintAds.banner.attach(slotEl, { size: 'banner' });
}Dans une application monopage, libérez la bannière quand la route qui la contient disparaît. attach marque l'élément immédiatement, donc détacher par élément fonctionne même pendant que la publicité se charge encore :
function onRouteChange(route) {
if (!window.AppMintAds) return renderRoute(route);
var old = document.getElementById('article-ad');
if (old) window.AppMintAds.banner.detach(old);
renderRoute(route);
if (route === '/articles') {
window.AppMintAds.banner.attach('#article-ad', { size: 'banner' });
}
}Après un achat « Supprimer les publicités », les superpositions ont disparu ; détachez aussi les emplacements et rendez l'espace qu'ils réservaient :
window.addEventListener('appmint:premium', function (e) {
if (!e.detail.premium || !window.AppMintAds) return;
document.querySelectorAll('[data-appmint-ad-slot]').forEach(function (el) {
window.AppMintAds.banner.detach(el);
el.remove();
});
});Remarques : Signature brute adsSlotDetach(slotId). detach prend l'élément ou la chaîne slot retournée par attach, pas un sélecteur CSS. Une Promise attach qui attend encore sa publicité répond {ok:false, code:'detached'}. Retirer l'élément du DOM détache aussi l'emplacement.
adsSlotRect pont#
window.WebToApk.adsSlotRect(slotId: String, x: Float, y: Float, w: Float, h: Float, visible: Boolean)
Interne : le rectangle actuel de l'élément d'emplacement dans la fenêtre d'affichage (px CSS) ; déplace la superposition.
Exemple
Interne : déplace une superposition de bannière à la position actuelle de son élément. L'assistant AppMintAds.banner l'appelle pour vous au défilement, au redimensionnement, au changement de visibilité et toutes les 500 ms ; les pages utilisent AppMintAds.banner.attach et ne l'appellent jamais.
Retourne : rien. Nécessite : Contrôle des publicités → Géré par le développeur, et un emplacement créé par AppMintAds.banner.attach.
Il suffit à la page de donner à l'élément d'emplacement une place dans la mise en page. L'assistant le mesure et garde la publicité par-dessus :
<main>
<article id="story">…</article>
<div id="ad-slot" style="margin: 16px 0"></div> <!-- the ad follows this box while scrolling -->
</main>
<script>
if (window.AppMintAds) window.AppMintAds.banner.attach('#ad-slot', { size: 'banner' });
</script>Une bannière dans une liste défilante, et non dans la page : l'assistant écoute le défilement en phase de capture, donc la publicité suit aussi le conteneur interne :
<div id="feed" style="height: 100vh; overflow-y: auto">
<div class="card">…</div>
<div class="card">…</div>
<div id="feed-ad" style="margin: 12px 0"></div>
<div class="card">…</div>
</div>
<script>
if (window.AppMintAds) window.AppMintAds.banner.attach('#feed-ad', { size: 'banner' });
</script>La publicité est dessinée au-dessus de la page, donc votre propre boîte de dialogue serait en dessous. Masquez l'emplacement tant que la boîte de dialogue est ouverte :
var slotEl = document.getElementById('ad-slot');
var dialog = document.getElementById('settings-dialog');
function openSettings() {
slotEl.style.visibility = 'hidden'; // the helper hides the overlay on its next tick
dialog.showModal();
}
dialog.addEventListener('close', function () {
slotEl.style.visibility = ''; // and puts it back over the box
});Remarques : Signature brute adsSlotRect(slotId, x, y, w, h, visible), en pixels CSS relatifs à la fenêtre d'affichage. La superposition est masquée tant que l'élément est hors écran, de taille nulle, avec visibility: hidden, ou que la page est en arrière-plan. Si l'élément quitte le DOM, l'assistant détache lui-même l'emplacement.
isInterstitialAdReady pont#
window.WebToApk.isInterstitialAdReady(): Boolean
Vrai lorsqu'une interstitielle est chargée ET hors de son délai d'attente (correspond exactement à ce que showInterstitialAd() acceptera : pas de « prête » qui refuse ensuite de s'afficher).
Exemple
Indique si une publicité interstitielle est chargée ET hors de son délai d'attente de 60 secondes, de sorte que showInterstitialAd() l'afficherait maintenant (contrôle automatique des publicités).
Retourne : true / false, de façon synchrone. Nécessite : des publicités activées et Publicité plein écran → Publicité interstitielle.
function onLevelDone() {
var b = window.WebToApk;
if (b && typeof b.isInterstitialAdReady === 'function' && b.isInterstitialAdReady()) {
b.showInterstitialAd(); // wait for 'appmint:ad-closed' before continuing
} else {
startNextLevel(); // nothing ready: never block the user
}
}
window.addEventListener('appmint:ad-closed', function (e) {
if (e.detail.adType === 'interstitial') startNextLevel();
});Affichez une publicité après chaque troisième quiz terminé, et seulement lorsqu'elle s'afficherait vraiment :
var finished = 0;
function onQuizFinished() {
finished++;
var b = window.WebToApk;
var ready = !!(b && typeof b.isInterstitialAdReady === 'function' && b.isInterstitialAdReady());
if (finished % 3 === 0 && ready) b.showInterstitialAd();
showResults(); // the results are there when the ad closes
}Affichez un court avis « Publicité dans 3… » uniquement lorsqu'une publicité est prête, puis continuez quand elle se ferme ou ne peut pas s'afficher :
var afterAd = null;
function adBreakThen(next) {
var b = window.WebToApk;
if (!b || typeof b.isInterstitialAdReady !== 'function' || !b.isInterstitialAdReady()) return next();
var note = document.getElementById('ad-break'), n = 3;
note.hidden = false; note.textContent = 'Ad in 3…';
var t = setInterval(function () {
if (--n > 0) { note.textContent = 'Ad in ' + n + '…'; return; }
clearInterval(t); note.hidden = true;
afterAd = next;
b.showInterstitialAd();
}, 1000);
}
function runAfterAd(e) {
if (e.detail.adType !== 'interstitial' || !afterAd) return;
var next = afterAd; afterAd = null; next();
}
window.addEventListener('appmint:ad-closed', runAfterAd);
window.addEventListener('appmint:ad-unavailable', runAfterAd);Remarques : true signifie ici que l'affichage ne sera pas refusé pour not_loaded ou cooldown. Le consentement ou un achat « Supprimer les publicités » peut encore l'empêcher (appmint:ad-unavailable). Dans les compilations Géré par le développeur, utilisez AppMintAds.isReady('interstitial').
isRewardedAdReady pont#
window.WebToApk.isRewardedAdReady(): Boolean
Vrai lorsqu'une publicité avec récompense est chargée et peut être affichée tout de suite. Laissez la page activer/désactiver son bouton « Regarder la publicité » selon cette valeur (interrogez-la ou appelez-la avant l'affichage).
Exemple
Indique si une publicité avec récompense est chargée et peut être affichée tout de suite (contrôle automatique des publicités).
Retourne : true / false, de façon synchrone. Nécessite : des publicités activées et Publicité plein écran → Publicité avec récompense.
Activez le bouton « Regarder une publicité » uniquement lorsqu'une publicité est prête :
var btn = document.getElementById('earn');
function refreshWatchButton() {
var b = window.WebToApk;
var ready = !!(b && typeof b.isRewardedAdReady === 'function' && b.isRewardedAdReady());
btn.disabled = !ready;
btn.textContent = ready ? 'Watch an ad for 10 coins' : 'Loading ad…';
}
refreshWatchButton();
setInterval(refreshWatchButton, 2000); // an ad can finish loading at any time
window.addEventListener('appmint:ad-closed', refreshWatchButton);En fin de partie, proposez « Continuer » uniquement lorsqu'une publicité est prête, pour que le bouton ne mène jamais nulle part :
var continueBtn = document.getElementById('continue-with-ad');
function onGameOver() {
var b = window.WebToApk;
continueBtn.hidden = !(b && typeof b.isRewardedAdReady === 'function' && b.isRewardedAdReady());
showGameOverPanel(); // "Restart" is always there
}
continueBtn.addEventListener('click', function () { // the user's own tap
continueBtn.hidden = true;
window.WebToApk.showRewardedAd();
});
window.addEventListener('appmint:reward', function () { revivePlayer(); });Vérifiez au moment de l'appui et dites à l'utilisateur ce qui se passe, au lieu de lancer un affichage qui sera refusé :
document.getElementById('hint').addEventListener('click', function () {
var b = window.WebToApk;
if (!b || typeof b.isRewardedAdReady !== 'function') return showMessage('Hints need the app.');
if (typeof b.isPremium === 'function' && b.isPremium()) return revealHint(); // paid to remove ads
if (b.isRewardedAdReady()) b.showRewardedAd();
else showMessage('The ad is still loading. Try again in a few seconds.');
});
window.addEventListener('appmint:reward', function () { revealHint(); });Remarques : Retourne false dans un navigateur, lorsque les publicités ont été supprimées par un achat, et avant le chargement de la première publicité. Après l'affichage d'une publicité, la suivante se charge toute seule. Dans les compilations Géré par le développeur, utilisez AppMintAds.isReady('rewarded').
notifyUserAction pont#
window.WebToApk.notifyUserAction()
Interne (appelé par le compteur d'appuis injecté, pas par le code du créateur) : une interaction utilisateur significative a eu lieu dans la page. Compte pour la cadence « interstitielle toutes les N actions » UNIQUEMENT tant qu'aucune navigation basée sur l'URL n'a jamais été observée : les applications HTML uniques qui changent d'écran en affichant/masquant du DOM ne changent jamais d'URL ; sans cela, leur compteur de navigation restait à 0 pour toujours et les publicités configurées ne s'affichaient jamais (type de plainte TicTrek, 26/07/2026). Les applications URL/SPA ne sont pas concernées : leur première vraie navigation rebascule définitivement le comptage sur les signaux d'URL.
Exemple
Compte une action utilisateur significative pour le réglage « publicité plein écran toutes les N actions ». L'application l'appelle elle-même depuis son propre compteur d'appuis ; les pages ne l'appellent normalement jamais.
Retourne : rien. Nécessite : des publicités activées, une publicité plein écran avec Mode de déclenchement → Après les navigations, et le contrôle automatique des publicités.
Fonctionnement : une page qui change d'écran en masquant et affichant des éléments du DOM ne change jamais d'URL, donc l'application ne voit aucune « navigation ». Elle injecte donc un compteur d'appuis (au plus un comptage toutes les 2 secondes) qui appelle cette méthode. Dès que l'application voit un vrai changement d'URL (un chargement de page, pushState ou un #hash), elle compte les changements d'URL à la place et cette méthode cesse de compter.
Seulement si vos changements d'écran ne viennent pas d'un appui (par exemple un déplacement au clavier ou à la manette), signalez-les vous-même :
function goToScreen(name) {
showScreen(name); // your own DOM show/hide
var b = window.WebToApk;
if (b && typeof b.notifyUserAction === 'function') b.notifyUserAction();
}
document.addEventListener('keydown', function (e) {
if (e.key === 'Enter') goToScreen('next');
});Une application de type cartes où l'utilisateur glisse vers l'écran suivant (un balayage n'est pas un appui sur un bouton, donc le compteur d'appuis ne le voit jamais) :
var startX = null;
document.addEventListener('touchstart', function (e) { startX = e.touches[0].clientX; }, { passive: true });
document.addEventListener('touchend', function (e) {
if (startX === null) return;
var dx = e.changedTouches[0].clientX - startX;
startX = null;
if (Math.abs(dx) < 80) return; // not a swipe
showScreen(dx < 0 ? 'next' : 'previous'); // your own DOM show/hide
var b = window.WebToApk;
if (b && typeof b.notifyUserAction === 'function') b.notifyUserAction();
});Un jeu HTML5 joué avec une manette, comptant une action par niveau lancé avec le bouton A :
var aWasDown = false;
function pollPad() {
var pad = navigator.getGamepads ? navigator.getGamepads()[0] : null;
var aDown = !!(pad && pad.buttons[0] && pad.buttons[0].pressed);
if (aDown && !aWasDown && isOnLevelSelect()) { // your own game state
startSelectedLevel();
var b = window.WebToApk;
if (b && typeof b.notifyUserAction === 'function') b.notifyUserAction();
}
aWasDown = aDown;
requestAnimationFrame(pollPad);
}
window.addEventListener('gamepadconnected', function () { requestAnimationFrame(pollPad); }, { once: true });Remarques : Ne fait rien lorsque les publicités sont désactivées, supprimées par un achat, ou lorsque la compilation utilise Contrôle des publicités → Géré par le développeur (dans ce cas, vous appelez AppMintAds.show() vous-même). Une publicité avec récompense obtenue ainsi est toujours proposée avec la question « Regarder une publicité ? / Non merci », jamais imposée. Ne l'appelez pas à chaque appui : cela afficherait des publicités plus souvent que vous ne l'avez configuré.
showInterstitialAd pont#
window.WebToApk.showInterstitialAd()
Affiche une interstitielle MAINTENANT (par ex. entre deux niveaux / lors d'une action délibérée). Non affichable pour le moment → ignorée + 'appmint:ad-unavailable' avec la raison.
Exemple
Affiche tout de suite une publicité interstitielle plein écran, par exemple entre deux niveaux de jeu (contrôle automatique des publicités).
Retourne : rien. Quand la publicité se ferme, appmint:ad-closed se déclenche avec {adType:'interstitial', earned:false}. Quand elle ne peut pas s'afficher, appmint:ad-unavailable se déclenche avec {adType:'interstitial', reason}. Nécessite : des publicités activées et Publicité plein écran → Publicité interstitielle. Choisissez Mode de déclenchement → À la demande si seule votre page doit décider du moment.
var bridge = window.WebToApk;
var waitingForAd = false;
function levelFinished() {
if (bridge && typeof bridge.isInterstitialAdReady === 'function' && bridge.isInterstitialAdReady()) {
waitingForAd = true;
bridge.showInterstitialAd(); // the next level starts when the ad closes
} else {
showNextLevel(); // no ad ready: just continue
}
}
window.addEventListener('appmint:ad-closed', function (e) {
if (e.detail.adType === 'interstitial' && waitingForAd) { waitingForAd = false; showNextLevel(); }
});
window.addEventListener('appmint:ad-unavailable', function (e) {
// reason: ad_free | disabled | consent | not_loaded | cooldown | show_failed
if (e.detail.adType === 'interstitial' && waitingForAd) { waitingForAd = false; showNextLevel(); }
});Mettez le jeu et son son en pause avant la publicité, et reprenez quelle que soit la réponse :
var pausedForAd = false;
function adBetweenRounds() {
var b = window.WebToApk;
if (!b || typeof b.showInterstitialAd !== 'function') return;
pausedForAd = true;
pauseGame(); music.pause();
b.showInterstitialAd();
}
function resumeAfterAd(e) {
if (e.detail.adType !== 'interstitial' || !pausedForAd) return;
pausedForAd = false;
music.play(); resumeGame();
}
window.addEventListener('appmint:ad-closed', resumeAfterAd);
window.addEventListener('appmint:ad-unavailable', resumeAfterAd);Ouvrez un article après une publicité, sous forme d'une seule Promise qui se résout avec true si la publicité a été affichée et false si elle a été ignorée :
function interstitialThen() {
return new Promise(function (resolve) {
var b = window.WebToApk;
if (!b || typeof b.isInterstitialAdReady !== 'function' || !b.isInterstitialAdReady()) return resolve(false);
function done(e) {
if (e.detail.adType !== 'interstitial') return;
window.removeEventListener('appmint:ad-closed', done);
window.removeEventListener('appmint:ad-unavailable', done);
resolve(e.type === 'appmint:ad-closed');
}
window.addEventListener('appmint:ad-closed', done);
window.addEventListener('appmint:ad-unavailable', done);
b.showInterstitialAd();
});
}
interstitialThen().then(function () { openArticle(articleId); });Remarques : L'application garde au moins 60 secondes entre deux interstitielles ; un appel dans cet intervalle répond cooldown. isInterstitialAdReady() inclut déjà ce délai, donc le vérifier d'abord évite l'événement. Affichez les interstitielles à des pauses naturelles, jamais à chaque appui. Dans les compilations Géré par le développeur, utilisez AppMintAds.show('interstitial').
showRewardedAd pont#
window.WebToApk.showRewardedAd()
Affiche une publicité avec récompense MAINTENANT (à l'initiative de l'utilisateur : la seule façon conforme aux règles d'afficher une publicité avec récompense). Associez-la au mode de déclenchement « À la demande » dans l'assistant pour avoir des publicités avec récompense SANS aucune publicité automatique d'ouverture ou de navigation. La récompense est renvoyée à la page via deliverRewardToPage() : window.addEventListener('appmint:reward', e => { /* e.detail = {type,amount} */ }) Quand la publicité se ferme, 'appmint:ad-closed' se déclenche avec {adType:'rewarded', earned} ; earned vaut false si l'utilisateur est sorti trop tôt, donc n'accordez rien dans ce cas. Non affichable pour le moment → ignorée + 'appmint:ad-unavailable' déclenché avec la raison.
Exemple
Affiche tout de suite une publicité avec récompense, à partir de l'appui « Regarder une publicité » de l'utilisateur (contrôle automatique des publicités).
Retourne : rien. Le résultat arrive plus tard sous forme d'événements : appmint:reward {type, amount} lorsque la publicité a été regardée jusqu'au bout, appmint:ad-closed {adType:'rewarded', earned} lorsqu'elle se ferme, ou appmint:ad-unavailable {adType:'rewarded', reason} lorsque rien n'a pu s'afficher. Nécessite : des publicités activées, Publicité plein écran → Publicité avec récompense et Mode de déclenchement → À la demande pour que rien ne s'affiche tout seul.
N'accordez la récompense que dans le gestionnaire de récompense, jamais lors de l'appui :
var btn = document.getElementById('earn');
var bridge = window.WebToApk;
function refresh() {
btn.disabled = !(bridge && typeof bridge.isRewardedAdReady === 'function' && bridge.isRewardedAdReady());
}
refresh();
setInterval(refresh, 2000);
btn.addEventListener('click', function () { // a real user tap: the only place to call it
if (!bridge || typeof bridge.showRewardedAd !== 'function') return;
btn.disabled = true;
bridge.showRewardedAd();
});
// GRANT HERE ONLY: the ad was watched to the end.
window.addEventListener('appmint:reward', function (e) {
addCoins(e.detail.amount); // e.detail = {type, amount}
});
// The ad closed. earned === false means the user left early: grant nothing.
window.addEventListener('appmint:ad-closed', function (e) {
if (e.detail.adType === 'rewarded' && !e.detail.earned) showMessage('No reward: the ad was closed early.');
refresh();
});
// Nothing could be shown.
window.addEventListener('appmint:ad-unavailable', function (e) {
// e.detail = {adType, reason}; reason: ad_free | disabled | consent | not_loaded | show_failed
if (e.detail.reason === 'ad_free') addCoins(1); // the user paid to remove ads: reward anyway
else showMessage('No ad right now. Try again in a moment.');
refresh();
});Les trois mêmes moments appellent aussi des fonctions de la page, si vous préférez une fonction chacun (chacune reçoit le même objet que e.detail):
window.onAppMintReward = function (reward) { addCoins(reward.amount); }; // {type, amount}
window.onAppMintAdClosed = function (info) { console.log(info.adType, info.earned); };
window.onAppMintAdUnavailable = function (info) { console.log(info.adType, info.reason); };Enveloppez l'appel et ses événements dans une seule Promise, pour que chaque bouton « Regarder une publicité » se lise comme un appel asynchrone normal :
function watchRewardedAd() { // call it inside the user's tap
return new Promise(function (resolve) {
var b = window.WebToApk;
if (!b || typeof b.showRewardedAd !== 'function') return resolve({ earned: false, reason: 'no_app' });
function done(e) {
if (e.detail.adType !== 'rewarded') return;
window.removeEventListener('appmint:ad-closed', done);
window.removeEventListener('appmint:ad-unavailable', done);
resolve(e.type === 'appmint:ad-closed' ? { earned: e.detail.earned } : { earned: false, reason: e.detail.reason });
}
window.addEventListener('appmint:ad-closed', done);
window.addEventListener('appmint:ad-unavailable', done);
b.showRewardedAd();
});
}
document.getElementById('revive').addEventListener('click', function () {
watchRewardedAd().then(function (r) {
if (r.earned || r.reason === 'ad_free') revivePlayer();
else if (r.reason) showMessage('No ad right now.');
});
});Remarques : Appelez-la uniquement depuis un gestionnaire de clic. Ne l'appelez jamais depuis un minuteur, un chargement de page ou un changement de route, et ne placez jamais une fonction essentielle derrière elle. not_loaded lance aussi un nouveau chargement, donc l'appui suivant fonctionne généralement. Dans les compilations Contrôle des publicités → Géré par le développeur, utilisez plutôt AppMintAds.show('rewarded'), qui répond par une Promise.