API jembatan JavaScript
Iklan
Menampilkan iklan interstisial atau berhadiah pada isyarat Anda sendiri, dan memberi tahu shell kapan navigasi dimulai dan selesai agar tidak mengganggunya.
AppMintAds.appOpen helper#
window.AppMintAds.appOpen.setEnabled(on)
Contoh
Menjeda atau melanjutkan iklan app-open, iklan layar penuh yang tampil saat peluncuran dan saat pengguna kembali dari aplikasi lain.
Mengembalikan: tidak ada. Membutuhkan: Ad Control β Developer-controlled dan ID unit iklan app-open.
Jeda saat pengguna sengaja meninggalkan aplikasi sebentar (aplikasi pembayaran, kamera, lembar berbagi), agar iklan tidak muncul saat mereka kembali:
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);
}
}Periksa apakah build memiliki unit app-open sama sekali:
var hasAppOpen = !!(window.AppMintAds && window.AppMintAds.config().formats.app_open);Jeda saat pengguna memilih foto, karena pemilih foto sistem membawa mereka keluar dari aplikasi sejenak:
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);
});Catatan: Aktif secara default. Pada cold start iklan tampil saat halaman siap, atau saat selesai dimuat dalam 15 detik; pemuatan yang lebih lambat disimpan untuk lain kali. Iklan app-open yang lebih lama dari 4 jam tidak pernah ditampilkan. Anda juga bisa menampilkannya sendiri dengan AppMintAds.show('app_open').
AppMintAds.banner helper#
window.AppMintAds.banner.attach(target, opts) / .detach(slotOrElement)
Contoh
Menempatkan iklan banner atau persegi panjang sedang 300Γ250 di mana saja di halaman Anda, di atas elemen yang Anda pilih.
Mengembalikan: attach mengembalikan Promise berisi {ok:true, slot, width, height} (piksel CSS) setelah iklan dimuat, atau {ok:false, slot?, code, message?}. detach tidak mengembalikan apa pun. Membutuhkan: Ad Control β Developer-controlled dan ID unit iklan banner (atau persegi panjang sedang).
Elemen ini hanya memesan ruang. Iklan digambar di atasnya dan mengikutinya saat halaman digulir atau diubah ukurannya:
<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>Persegi panjang sedang (satu per satu), dan menghapus banner lagi:
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;
}Coba slot lagi nanti saat tidak ada iklan tersedia, bebaskan dulu slot yang gagal agar tidak memakai salah satu dari dua slot:
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);Catatan: target adalah elemen atau selector CSS; size adalah 'banner' (default, lebar adaptif, tinggi paling banyak 90 dp), 'medium_rectangle' atau 'mrec'. Paling banyak dua slot sekaligus, dan slot yang iklannya gagal dimuat tetap dihitung sampai Anda melepasnya. detach membutuhkan elemen atau ID slot dari attach, bukan selector. Menghapus elemen dari DOM juga melepasnya. Kode: no_element, duplicate_slot, too_many_slots, detached, no_fill, network, invalid_unit, ad_free, disabled, consent, automatic_mode, internal.
AppMintAds.config helper#
window.AppMintAds.config()
Contoh
Memberi tahu halaman mode kontrol iklan yang dipakai build dan format iklan apa yang bisa disajikannya.
Mengembalikan: sebuah objek, secara sinkron: {control: 'automatic' | 'developer', formats: {banner, mrec, interstitial, rewarded, rewarded_interstitial, app_open}} (setiap format true / false). Pada kesalahan internal mengembalikan {control:'automatic', formats:{}}. Membutuhkan: tidak ada; window.AppMintAds hanya ada di dalam aplikasi yang terinstal.
Tampilkan hanya UI iklan yang benar-benar bisa disajikan build ini:
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);Pilih format berhadiah yang dimiliki build untuk tombol "bonus", dan sembunyikan tombol jika tidak ada keduanya:
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);
});Pilih ukuran iklan untuk akhir artikel: persegi panjang sedang jika build memilikinya, jika tidak banner:
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; }
});Catatan: Sebuah format bernilai true saat iklan aktif dan build memiliki ID unit iklan untuknya. Dalam mode Automatic (control: 'automatic') setiap panggilan load / show / banner.attach menjawab code: 'automatic_mode'; gunakan WebToApk.showRewardedAd() / showInterstitialAd() di sana. Pilih Ad Control β Developer-controlled di wizard build untuk mengendalikan iklan dari halaman.
AppMintAds.isReady helper#
window.AppMintAds.isReady(type)
Contoh
Memberi tahu apakah iklan layar penuh bertipe ini sudah dimuat dan bisa ditampilkan sekarang juga.
Mengembalikan: true / false, secara sinkron. type: 'interstitial', 'rewarded', 'rewarded_interstitial' atau 'app_open'. Membutuhkan: Ad Control β Developer-controlled dan ID unit iklan untuk tipe tersebut.
Jaga tombol "Tonton iklan" tetap selaras dengan iklan, menggunakan event status 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
}Tawarkan "gandakan koin Anda" di layar hasil hanya saat iklan berhadiah sudah menunggu:
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
};
}Pada tombol petunjuk, putar format berhadiah mana pun yang sedang dimuat:
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();
});Catatan: banner dan mrec selalu menjawab false (keduanya dipasang, bukan ditampilkan). Interstisial dalam masa jeda 60 detiknya menjawab false; iklan app-open yang lebih lama dari 4 jam menjawab false. Dalam mode Automatic ini selalu false.
AppMintAds.load helper#
window.AppMintAds.load(type)
Contoh
Memuat iklan layar penuh agar show(type) berikutnya bisa langsung memutarnya.
Mengembalikan: Promise yang selesai (tidak pernah ditolak) dengan {ok:true}, {ok:true, cached:true} saat satu sudah menunggu, atau {ok:false, code, reason, message?, adCode?}. Membutuhkan: Ad Control β Developer-controlled dan ID unit iklan untuk tipe tersebut (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();Seluruh siklus hidup setiap permintaan juga dialirkan pada event 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); };Muat interstisial saat level dimulai, agar sudah ada saat level berakhir, dan berhenti bertanya setelah pengguna menghapus iklan:
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();
}Catatan: Kode: no_fill, network, invalid_unit, internal (dari AdMob), automatic_mode, unknown_type, ad_free, disabled, consent, dan use_slot untuk banner / mrec (gunakan AppMintAds.banner.attach). Aplikasi sudah memuat awal setiap tipe layar penuh yang punya ID unit dan memuat yang berikutnya setelah setiap tampilan, jadi load sebagian besar untuk mengetahui kapan tombol boleh diaktifkan.
AppMintAds.show helper#
window.AppMintAds.show(type)
Contoh
Menampilkan iklan layar penuh yang sudah dimuat: interstitial, rewarded, rewarded_interstitial atau app_open.
Mengembalikan: Promise yang selesai (tidak pernah ditolak) saat iklan ditutup: {ok:true, shown:true, earned, reward?} (reward = {type, amount} untuk format berhadiah), atau {ok:false, shown:false, code, reason, message?} saat tidak ada yang ditampilkan. Membutuhkan: Ad Control β Developer-controlled dan ID unit iklan untuk tipe tersebut.
Berhadiah: panggil di dalam ketukan pengguna sendiri. Ketukan itu adalah persetujuan pengguna, jadi iklan langsung diputar. Berikan hadiah hanya saat earned bernilai true:
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.');
});Interstisial: pada jeda yang wajar. Lanjutkan apa pun jawabannya:
async function levelFinished() {
if (window.AppMintAds && window.AppMintAds.isReady('interstitial')) {
await window.AppMintAds.show('interstitial'); // resolves when the ad closes
}
showNextLevel();
}Interstisial berhadiah di balik layar pengantar Anda sendiri dengan "Tidak, terima kasih" yang jelas. Ketukan pada "Tonton" adalah persetujuannya:
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();
});Catatan: show() berhadiah atau interstisial berhadiah yang TIDAK berasal dari ketukan pengguna (pengatur waktu, pemuatan halaman, perubahan rute) lebih dulu menampilkan layar "Tonton iklan? / Tidak, terima kasih", dan "Tidak, terima kasih" menghasilkan declined. Jangan pernah memicu format berhadiah dengan cara itu. Kode lainnya: automatic_mode, unknown_type, ad_free, disabled, consent, not_full_screen, showing, cooldown (60 dtk antar interstisial), not_loaded (pemuatan baru dimulai untuk lain kali), show_failed, internal. Dalam mode Automatic gunakan WebToApk.showRewardedAd().
adsAppOpenEnable jembatan#
window.WebToApk.adsAppOpenEnable(enabled: Boolean)
Memungkinkan halaman menjeda/melanjutkan iklan app-open saat kembali dari aplikasi lain (aktif secara default saat unit diatur).
Contoh
Bagian native dari AppMintAds.appOpen.setEnabled(on): menjeda atau melanjutkan iklan app-open. Halaman memakai AppMintAds.appOpen.setEnabled.
Mengembalikan: tidak ada. Membutuhkan: Ad Control β Developer-controlled dan ID unit iklan app-open.
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); }Memilih foto meninggalkan aplikasi menuju pemilih sistem, dan kembalinya dihitung sebagai kembali ke aplikasi. Jeda iklan app-open di sekitarnya:
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);Anggota paket berbayar Anda sendiri tidak pernah melihatnya. Pengaturan ini tidak disimpan, jadi atur lebih awal pada setiap peluncuran:
// 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);
}Catatan: Tanda tangan mentah adsAppOpenEnable(enabled). Aktif secara default saat unit app-open diatur. Iklan app-open tampil pada cold start (jika dimuat dalam 15 detik) dan saat pengguna kembali dari aplikasi lain; iklan yang lebih lama dari 4 jam tidak pernah ditampilkan.
adsConfig jembatan#
window.WebToApk.adsConfig(): String
`{control, formats:{banner, mrec, interstitial, rewarded, rewarded_interstitial, app_open}}` - format iklan yang bisa disajikan build ini.
Contoh
Membaca format iklan apa saja yang bisa disajikan build ini dan mode kontrol iklan yang dipakainya. Halaman biasanya memanggil AppMintAds.config(), yang mengurai ini untuk Anda.
Mengembalikan: string JSON: {"control":"automatic"|"developer","formats":{"banner":bool,"mrec":bool,"interstitial":bool,"rewarded":bool,"rewarded_interstitial":bool,"app_open":bool}}. Sebuah format bernilai true saat iklan aktif dan build memiliki ID unit iklan untuknya. Membutuhkan: tidak ada.
API publik terlebih dahulu:
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;
}
}Panggilan mentahnya, jika Anda tidak memakai 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); }
}Pesan ruang hanya untuk format yang benar-benar dimiliki build ini, dan kembalikan kotak kosong ke halaman jika tidak:
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
}Catatan: Dalam mode Automatic formats tetap memberi tahu unit mana yang ada, tetapi AppMintAds.load/show menjawab code: 'automatic_mode'; gunakan WebToApk.showRewardedAd() / showInterstitialAd() di sana.
adsIsReady jembatan#
window.WebToApk.adsIsReady(type: String): Boolean
Bernilai true jika [type] layar penuh sudah dimuat dan bisa ditampilkan sekarang juga.
Contoh
Memberi tahu apakah iklan layar penuh satu tipe sudah dimuat dan bisa tampil sekarang (iklan Developer-controlled). Halaman biasanya memanggil AppMintAds.isReady(type).
Mengembalikan: true / false, secara sinkron. type adalah 'interstitial', 'rewarded', 'rewarded_interstitial' atau 'app_open'; 'banner' / 'mrec' selalu menjawab false. Membutuhkan: Ad Control β Developer-controlled dan ID unit iklan untuk tipe itu.
API publik terlebih dahulu:
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 readinessPanggilan mentah:
var b = window.WebToApk;
var ready = !!(b && typeof b.adsIsReady === 'function' && b.adsIsReady('interstitial'));Tampilkan interstisial di akhir level hanya saat ada yang menunggu, dan jangan pernah menahan pemain saat tidak ada:
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
}
}Catatan: Interstisial dalam masa jeda 60 detiknya menghasilkan false. Iklan app-open yang lebih lama dari 4 jam menghasilkan false (Google meminta agar tidak ditampilkan). Dalam mode Automatic ini selalu false; gunakan WebToApk.isRewardedAdReady() di sana.
adsLoad jembatan#
window.WebToApk.adsLoad(type: String, callbackId: String)
Memuat [type] layar penuh; promise untuk [callbackId] selesai dengan hasilnya.
Contoh
Bagian native dari AppMintAds.load(type): memulai pemuatan iklan layar penuh dan menjawab callback shim. Halaman memakai AppMintAds.load(type), yang mengembalikan Promise; jangan memanggil ini secara langsung.
Mengembalikan: (melalui AppMintAds.load) Promise berisi {ok:true}, {ok:true, cached:true} saat satu sudah dimuat, atau {ok:false, code, reason, message?, adCode?}. Membutuhkan: Ad Control β Developer-controlled dan ID unit iklan untuk tipe tersebut.
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
}Ulangi pemuatan yang gagal karena alasan sementara, dan berhenti untuk alasan yang tidak bisa diperbaiki dengan mengulang:
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;
});
}Panaskan dua format sebelum sesi game dimulai dan sembunyikan semua tombol iklan saat pengguna tidak punya iklan sama sekali:
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);
});
});
}Catatan: Kode kegagalan: no_fill, network, invalid_unit, internal (dari AdMob, dengan adCode), dan automatic_mode, unknown_type, ad_free, disabled, consent, serta use_slot untuk banner / mrec (dimuat dengan AppMintAds.banner.attach). Aplikasi sudah memuat awal setiap tipe layar penuh yang punya ID unit, dan memuat ulang setelah setiap tampilan. Tanda tangan mentahnya adalah adsLoad(type, callbackId); jawabannya masuk ke resolver internal, jadi panggilan langsung tidak memberi Anda hasil.
adsShow jembatan#
window.WebToApk.adsShow(type: String, callbackId: String, userGesture: Boolean)
Menampilkan [type] layar penuh yang sudah dimuat; selesai saat ditutup, dengan earned/reward untuk format berhadiah. [userGesture] adalah pembacaan `navigator.userActivation` oleh shim - format berhadiah yang diminta tanpanya mendapat layar pengantar AdMob lebih dulu (lihat DeveloperAds.offerRewarded).
Contoh
Bagian native dari AppMintAds.show(type): menampilkan iklan layar penuh yang sudah dimuat dan menjawab saat ditutup. Halaman memakai AppMintAds.show(type); jangan memanggil ini secara langsung.
Mengembalikan: (melalui AppMintAds.show) Promise berisi {ok:true, shown:true, earned, reward?} setelah iklan ditutup (reward = {type, amount} untuk format berhadiah), atau {ok:false, shown:false, code, reason, message?}. Membutuhkan: Ad Control β Developer-controlled dan ID unit iklan untuk tipe tersebut.
Panggil dari ketukan pengguna. Shim meneruskan navigator.userActivation.isActive sebagai argumen ketiga (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.');
});
});Tawarkan interstisial berhadiah dari ketukan "Gandakan bonus saya" milik pengguna, dan lanjutkan apa pun jawabannya:
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
});
});Jeda musik game Anda selama iklan layar penuh apa pun tampil, menggunakan aliran 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
}Catatan: Tanda tangan mentah adsShow(type, callbackId, userGesture). Saat userGesture bernilai false untuk rewarded atau rewarded_interstitial, aplikasi lebih dulu menanyakan "Tonton iklan? / Tidak, terima kasih" dan jawaban "tidak" menghasilkan declined. Kode lainnya: automatic_mode, unknown_type, ad_free, disabled, consent, not_full_screen, showing, cooldown (interstisial, 60 dtk), not_loaded (pemuatan dimulai untuk lain kali), show_failed, internal.
adsSlotAttach jembatan#
window.WebToApk.adsSlotAttach(slotId: String, type: String, widthCss: Int, callbackId: String)
Membuat overlay banner/mrec untuk slot halaman [slotId], berukuran [widthCss]; selesai dengan ukuran iklan setelah dimuat.
Contoh
Bagian native dari AppMintAds.banner.attach(element, {size}): membuat iklan banner atau persegi panjang sedang di atas elemen halaman. Halaman memakai AppMintAds.banner.attach; jangan memanggil ini secara langsung.
Mengembalikan: (melalui AppMintAds.banner.attach) Promise berisi {ok:true, slot, width, height} dalam piksel CSS setelah iklan dimuat, atau {ok:false, slot, code, message?}. Membutuhkan: Ad Control β Developer-controlled dan ID unit iklan banner (atau persegi panjang sedang).
<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>Persegi panjang sedang di layar hasil yang mengembalikan ruangnya saat tidak ada iklan yang datang:
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;
}Hitung tayangan dan klik per slot dari aliran appmint:ad, dengan kunci ID slot yang dikembalikan 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);
}
});Catatan: Tanda tangan mentah adsSlotAttach(slotId, type, widthCss, callbackId); type adalah 'banner' atau 'mrec'. WebView tidak bisa menampung tampilan native di dalam halaman, jadi iklan digambar di atas elemen Anda dan mengikutinya saat digulir dan diubah ukurannya (lihat adsSlotRect). Paling banyak dua slot sekaligus, dan hanya satu persegi panjang sedang. Kode tambahan: duplicate_slot, too_many_slots, detached, internal, ditambah kode pemuatan (no_fill, network, invalid_unit, ad_free, disabled, consent, automatic_mode).
adsSlotDetach jembatan#
window.WebToApk.adsSlotDetach(slotId: String)
Menghapus overlay banner.
Contoh
Bagian native dari AppMintAds.banner.detach(slotOrElement): menghapus overlay banner dan membebaskan slotnya. Halaman memakai AppMintAds.banner.detach.
Mengembalikan: tidak ada. Membutuhkan: Ad Control β Developer-controlled.
Hapus banner sebelum layar yang tidak cocok untuk iklan (pemutar video, checkout):
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' });
}Dalam aplikasi satu halaman, bebaskan banner saat rute yang memuatnya hilang. attach langsung menandai elemen, jadi pelepasan berdasarkan elemen berfungsi bahkan saat iklan masih dimuat:
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' });
}
}Setelah pembelian "Remove Ads" overlay hilang; lepaskan juga slotnya dan hapus ruang yang dipesannya:
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();
});
});Catatan: Tanda tangan mentah adsSlotDetach(slotId). detach menerima elemen atau string slot yang dikembalikan attach, bukan selector CSS. Promise attach yang masih menunggu iklannya menjawab {ok:false, code:'detached'}. Menghapus elemen dari DOM juga melepas slotnya.
adsSlotRect jembatan#
window.WebToApk.adsSlotRect(slotId: String, x: Float, y: Float, w: Float, h: Float, visible: Boolean)
Internal: persegi panjang viewport elemen slot saat ini (px CSS) - memindahkan overlay.
Contoh
Internal: memindahkan overlay banner ke posisi elemennya saat ini. Helper AppMintAds.banner memanggilnya untuk Anda saat scroll, perubahan ukuran, perubahan visibilitas, dan setiap 500 ms; halaman memakai AppMintAds.banner.attach dan tidak pernah memanggil ini.
Mengembalikan: tidak ada. Membutuhkan: Ad Control β Developer-controlled, dan slot yang dibuat oleh AppMintAds.banner.attach.
Yang dilakukan halaman hanyalah memberi elemen slot tempat di tata letak. Helper mengukurnya dan menjaga iklan tetap di atasnya:
<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>Banner di dalam daftar yang bisa digulir, bukan halaman: helper mendengarkan scroll di fase capture, jadi iklan juga mengikuti kontainer dalam:
<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>Iklan digambar di atas halaman, jadi dialog Anda sendiri akan berada di bawahnya. Sembunyikan slot saat dialog terbuka:
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
});Catatan: Tanda tangan mentah adsSlotRect(slotId, x, y, w, h, visible), dalam piksel CSS relatif terhadap viewport. Overlay disembunyikan saat elemen berada di luar layar, berukuran nol, memiliki visibility: hidden, atau halaman berada di latar belakang. Jika elemen keluar dari DOM, helper melepas slot dengan sendirinya.
isInterstitialAdReady jembatan#
window.WebToApk.isInterstitialAdReady(): Boolean
Bernilai true saat interstisial sudah dimuat DAN melewati masa jedanya (sama persis dengan yang akan diterima showInterstitialAd() - tidak ada "siap" yang kemudian menolak tampil).
Contoh
Memberi tahu apakah iklan interstisial sudah dimuat DAN sudah melewati masa jeda 60 detiknya, sehingga showInterstitialAd() akan menampilkannya sekarang (Automatic ad control).
Mengembalikan: true / false, secara sinkron. Membutuhkan: Iklan aktif dan Full Screen Ad β Interstitial Ad.
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();
});Tampilkan iklan setelah setiap kuis ketiga selesai, dan hanya saat iklan benar-benar akan tampil:
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
}Tampilkan pemberitahuan singkat "Iklan dalam 3β¦" hanya saat iklan siap, lalu lanjutkan saat ditutup atau tidak bisa tampil:
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);Catatan: true di sini berarti tampilan tidak akan ditolak karena not_loaded atau cooldown. Persetujuan atau pembelian "Remove Ads" tetap bisa menghentikannya (appmint:ad-unavailable). Pada build Developer-controlled gunakan AppMintAds.isReady('interstitial').
isRewardedAdReady jembatan#
window.WebToApk.isRewardedAdReady(): Boolean
Bernilai true saat iklan berhadiah sudah dimuat dan bisa ditampilkan sekarang juga. Biarkan halaman mengaktifkan/menonaktifkan tombol "Tonton iklan" berdasarkan ini (polling atau panggil sebelum menampilkan).
Contoh
Memberi tahu apakah iklan berhadiah sudah dimuat dan bisa ditampilkan sekarang juga (Automatic ad control).
Mengembalikan: true / false, secara sinkron. Membutuhkan: Iklan aktif dan Full Screen Ad β Rewarded Ad.
Aktifkan tombol "Tonton iklan" hanya saat ada iklan yang menunggu:
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);Saat game over, tawarkan "Lanjutkan" hanya saat ada iklan yang menunggu, agar tombol tidak pernah mengarah ke mana-mana:
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(); });Periksa saat ketukan terjadi dan beri tahu pengguna apa yang sedang terjadi, alih-alih memicu tampilan yang akan ditolak:
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(); });Catatan: Mengembalikan false di browser, saat iklan dihapus lewat pembelian, dan sebelum iklan pertama dimuat. Setelah iklan ditampilkan, iklan berikutnya dimuat sendiri. Pada build Developer-controlled gunakan AppMintAds.isReady('rewarded').
notifyUserAction jembatan#
window.WebToApk.notifyUserAction()
Internal (dipanggil oleh penghitung ketukan yang disuntikkan, bukan kode kreator): satu interaksi pengguna yang berarti terjadi di halaman. Dihitung untuk irama "interstisial setiap N aksi" HANYA selama belum pernah ada navigasi berbasis URL yang teramati - aplikasi HTML tunggal yang berpindah layar lewat tampil/sembunyi DOM tidak pernah mengubah URL, sehingga tanpa ini penghitung navigasi mereka tetap 0 selamanya dan iklan yang dikonfigurasi tidak pernah tampil (kelas keluhan TicTrek, 2026-07-26). Aplikasi URL/SPA tidak terpengaruh: navigasi nyata pertama mereka mengalihkan penghitungan kembali ke sinyal URL secara permanen.
Contoh
Menghitung satu aksi pengguna yang berarti untuk pengaturan "iklan layar penuh setiap N aksi". Aplikasi memanggil ini sendiri dari penghitung ketukannya; halaman biasanya tidak pernah memanggilnya.
Mengembalikan: tidak ada. Membutuhkan: Iklan aktif, sebuah Full Screen Ad dengan Trigger Mode β After Navigations, dan Automatic ad control.
Cara kerjanya: halaman yang berpindah layar dengan menyembunyikan dan menampilkan elemen DOM tidak pernah mengubah URL-nya, sehingga aplikasi tidak bisa melihat "navigasi". Karena itu aplikasi menyuntikkan penghitung ketukan (paling banyak satu hitungan per 2 detik) yang memanggil metode ini. Begitu aplikasi melihat satu perubahan URL nyata (pemuatan halaman, pushState atau #hash), aplikasi menghitung perubahan URL sebagai gantinya dan metode ini berhenti menghitung.
Hanya jika perubahan layar Anda tidak berasal dari ketukan (misalnya gerakan keyboard atau gamepad), laporkan sendiri:
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');
});Aplikasi bergaya kartu di mana pengguna menggeser ke layar berikutnya (geseran bukan ketukan pada tombol, jadi penghitung ketukan tidak pernah melihatnya):
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();
});Game HTML5 yang dimainkan dengan gamepad, menghitung satu aksi per level yang dimulai pemain dengan tombol 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 });Catatan: Tidak melakukan apa pun saat iklan nonaktif, dihapus lewat pembelian, atau saat build memakai Ad Control β Developer-controlled (di sana Anda memanggil AppMintAds.show() sendiri). Iklan berhadiah yang dicapai dengan cara ini selalu ditawarkan dengan pertanyaan "Tonton iklan? / Tidak, terima kasih", tidak pernah dipaksakan. Jangan memanggilnya pada setiap ketukan; itu akan menampilkan iklan lebih sering daripada yang Anda atur.
showInterstitialAd jembatan#
window.WebToApk.showInterstitialAd()
Tampilkan interstisial SEKARANG (misalnya di antara level / pada aksi yang disengaja). Tidak bisa ditampilkan sekarang β dilewati + 'appmint:ad-unavailable' dengan alasannya.
Contoh
Menampilkan iklan interstisial layar penuh sekarang juga, misalnya di antara dua level game (Automatic ad control).
Mengembalikan: tidak ada. Saat iklan ditutup, appmint:ad-closed dipicu dengan {adType:'interstitial', earned:false}. Saat tidak bisa tampil, appmint:ad-unavailable dipicu dengan {adType:'interstitial', reason}. Membutuhkan: Iklan aktif dan Full Screen Ad β Interstitial Ad. Pilih Trigger Mode β On Demand jika hanya halaman Anda yang boleh memutuskan kapan.
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(); }
});Jeda game dan suaranya sebelum iklan, dan lanjutkan pada jawaban apa pun:
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);Buka artikel setelah iklan, sebagai satu Promise yang selesai dengan true saat iklan ditampilkan dan false saat dilewati:
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); });Catatan: Aplikasi menjaga minimal 60 detik di antara dua interstisial; panggilan dalam jeda itu menjawab cooldown. isInterstitialAdReady() sudah memperhitungkan masa jeda, jadi memeriksanya lebih dulu menghindari event tersebut. Tampilkan interstisial pada jeda yang wajar, jangan pada setiap ketukan. Pada build Developer-controlled gunakan AppMintAds.show('interstitial').
showRewardedAd jembatan#
window.WebToApk.showRewardedAd()
Tampilkan iklan berhadiah SEKARANG (dimulai pengguna - satu-satunya cara yang sesuai kebijakan untuk menampilkan iklan berhadiah). Pasangkan dengan trigger mode "On Demand" di wizard untuk mendapatkan iklan berhadiah TANPA iklan app-open/navigasi otomatis sama sekali. Hadiah dikirim kembali ke halaman melalui deliverRewardToPage(): window.addEventListener('appmint:reward', e => { /* e.detail = {type,amount} */ }) Saat iklan ditutup, 'appmint:ad-closed' dipicu dengan {adType:'rewarded', earned} - earned bernilai false jika pengguna keluar lebih awal, jadi jangan berikan apa pun dalam kasus itu. Tidak bisa ditampilkan sekarang β dilewati + 'appmint:ad-unavailable' dipicu dengan alasannya.
Contoh
Menampilkan iklan berhadiah sekarang juga, dari ketukan "Tonton iklan" milik pengguna sendiri (Automatic ad control).
Mengembalikan: tidak ada. Hasilnya datang kemudian sebagai event: appmint:reward {type, amount} saat iklan ditonton sampai selesai, appmint:ad-closed {adType:'rewarded', earned} saat ditutup, atau appmint:ad-unavailable {adType:'rewarded', reason} saat tidak ada yang bisa ditampilkan. Membutuhkan: Iklan aktif, Full Screen Ad β Rewarded Ad, dan Trigger Mode β On Demand agar tidak ada yang tampil dengan sendirinya.
Berikan hadiah hanya di penangan hadiah, jangan pernah saat ketukan:
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();
});Tiga momen yang sama juga memanggil hook halaman, jika Anda lebih suka satu fungsi untuk masing-masing (masing-masing mendapat objek yang sama dengan 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); };Bungkus panggilan dan event-nya dalam satu Promise, agar setiap tombol "Tonton iklan" terbaca seperti panggilan async biasa:
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.');
});
});Catatan: Panggil hanya dari penangan klik. Jangan pernah memanggilnya dari pengatur waktu, pemuatan halaman, atau perubahan rute, dan jangan pernah menaruh fitur inti di baliknya. not_loaded juga memulai pemuatan baru, jadi ketukan berikutnya biasanya berhasil. Pada build Ad Control β Developer-controlled gunakan AppMintAds.show('rewarded') sebagai gantinya, yang menjawab dengan Promise.