Crea APK gratis

API del bridge JavaScript

La posta in arrivo push e il pubblico

Messaggi inviati dal creatore da una dashboard, conservati sul dispositivo così la pagina può mostrare una cronologia e non solo un pop-up nella barra delle notifiche; inoltre l'ID utente con accesso effettuato e i tag che permettono al centro di invio di puntare a un singolo utente o a un tag e di avviare automazioni come un promemoria per il carrello abbandonato.

AppMint.trackEvent helper#

window.AppMint.trackEvent

Esempio

Documentato insieme a WebToApk.trackEvent - l'esempio lì mostra anche questo.

Dice all'app che è successo qualcosa ("signed_up", "checkout_done", "level:3"). Un messaggio in-app creato nel centro di invio di AppMint Push con il trigger "Quando accade un evento" e lo stesso nome viene mostrato subito (o dopo l'attesa scelta dal creatore).

Restituisce: true quando l'evento è stato accettato; false per un nome fuori da lettere, cifre e _ . : - (fino a 64), e in un'app creata senza AppMint Push. AppMint.trackEvent(name, props) è la stessa chiamata con props come oggetto. Richiede: AppMint Push attivato nel passaggio Integrazione (Passaggio 3) quando crei l'app. propsJson è facoltativo ('') e non viene salvato.

// After a purchase: the creator's "Thanks, rate us?" message is set to trigger on "purchase_done".
function onPurchaseDone(order) {
  if (window.AppMint && AppMint.trackEvent) {
    AppMint.trackEvent('purchase_done', { total: order.total });
  }
}

Il bridge grezzo accetta le proprietà come stringa JSON (passa '' per nessuna):

function track(name, props) {
  if (!(window.WebToApk && window.WebToApk.trackEvent)) return false;   // a browser: nothing to show
  return WebToApk.trackEvent(name, props ? JSON.stringify(props) : '');
}
track('level:3');
track('tutorial_skipped', { step: 2 });

Un cambio di schermata che l'indirizzo non mostra (schede, una procedura guidata, una "pagina" modale) può essere segnalato come percorso, così i messaggi "In una pagina" del creatore lo vedono. La pagina può anche inviare l'evento appmint:route con il percorso; l'app lo ascolta:

function showTab(name) {
  document.querySelectorAll('.tab').forEach(function (t) { t.hidden = t.id !== name; });
  if (window.AppMint && AppMint.trackEvent) AppMint.trackEvent('appmint:route', { path: '/' + name });
}

// Same thing, without touching the bridge at all:
window.dispatchEvent(new CustomEvent('appmint:route', { detail: { path: '/cart' } }));

Note: i messaggi per percorso seguono già da soli le vere modifiche di URL (caricamenti di pagina, percorsi history.pushState, #/hash); segnala un percorso solo per le viste in cui l'indirizzo non cambia. Gli eventi non vengono contati né salvati da nessuna parte; servono solo a decidere se un messaggio viene mostrato.

clearPushInbox bridge#

window.WebToApk.clearPushInbox(): Boolean

Svuota la casella push (la barra delle notifiche e la cronologia sul server restano intatte).

Esempio

Svuota la casella push su questo telefono.

Restituisce: true quando è fatto; false in caso di errore interno. Richiede: attiva AppMint Push nel passaggio Integra (Passaggio 3) quando crei l'app.

document.getElementById('clear-inbox').addEventListener('click', function () {
  if (!(window.WebToApk && window.WebToApk.clearPushInbox)) return;
  if (!confirm('Delete all messages? This cannot be undone.')) return;
  if (WebToApk.clearPushInbox()) renderInbox();
});

Svuota la casella quando l'utente esce dall'account, così la persona successiva su questo telefono non vede i suoi messaggi:

async function signOut() {
  await myAuth.signOut();
  if (window.WebToApk && window.WebToApk.clearPushInbox) {
    WebToApk.clearPushInbox();
  }
  document.getElementById('bell-count').textContent = '';
  showLoginScreen();
}

Mostra una riga delle impostazioni con quanti messaggi sono archiviati, disattivata quando non c'è nulla da eliminare:

function paintClearRow() {
  const btn = document.getElementById('clear-inbox');
  if (!(window.WebToApk && window.WebToApk.clearPushInbox)) { btn.hidden = true; return; }
  const count = JSON.parse(WebToApk.getPushInbox() || '[]').length;
  btn.textContent = count ? 'Delete ' + count + ' messages' : 'No messages';
  btn.disabled = count === 0;
}

document.getElementById('clear-inbox').addEventListener('click', function () {
  if (WebToApk.clearPushInbox()) paintClearRow();
  else alert('Could not delete the messages. Please try again.');
});

paintClearRow();

Note: è permanente: a differenza di dismissPushMessage, non c'è modo di annullare. Le notifiche nell'area notifiche e la cronologia degli invii in AppMint non vengono toccate. I nuovi messaggi continuano ad arrivare.

dismissPushMessage bridge#

window.WebToApk.dismissPushMessage(id: String): Boolean

Scarta UN messaggio dalla casella: lo swipe per riga di cui ha bisogno una schermata della casella (clearPushInbox è tutto o niente). REVERSIBILE per scelta: la voce è nascosta, non distrutta, quindi l'interfaccia può offrire "Annulla" per qualche secondo dopo lo swipe. Solo in locale: la notifica nella barra e la cronologia del creatore non vengono toccate.

Esempio

Nasconde un messaggio dalla casella push (con uno swipe per scartarlo). Si può annullare con restorePushMessage(id).

Restituisce: true se il messaggio è stato nascosto; false se l'id è sconosciuto o era già nascosto. Richiede: attiva AppMint Push nel passaggio Integrazione (Passaggio 3) quando crei l'app.

Scarta con swipe e 5 secondi per annullare:

function dismissRow(id, rowEl) {
  if (!(window.WebToApk && window.WebToApk.dismissPushMessage)) return;
  if (!WebToApk.dismissPushMessage(id)) return;
  rowEl.remove();

  const bar = document.getElementById('undo-bar');
  bar.hidden = false;
  const timer = setTimeout(function () { bar.hidden = true; }, 5000);
  document.getElementById('undo-btn').onclick = function () {
    clearTimeout(timer);
    bar.hidden = true;
    WebToApk.restorePushMessage(id);         // back in its old place
    renderInbox();
  };
}

Riordina la posta in arrivo quando si apre nascondendo i messaggi già letti e più vecchi di 30 giorni:

function hideOldReadMessages() {
  if (!(window.WebToApk && window.WebToApk.dismissPushMessage)) return 0;
  const cutoff = Date.now() - 30 * 24 * 60 * 60 * 1000;
  let hidden = 0;
  JSON.parse(WebToApk.getPushInbox() || '[]').forEach(function (m) {
    if (m.read && m.receivedAt < cutoff && WebToApk.dismissPushMessage(m.id)) hidden++;
  });
  return hidden;
}

if (hideOldReadMessages() > 0) renderInbox();

Scarta una riga con un vero swipe del dito (trascinala per più del 40% della sua larghezza):

function makeSwipeable(rowEl, id) {
  let startX = null;
  rowEl.addEventListener('pointerdown', function (e) { startX = e.clientX; rowEl.setPointerCapture(e.pointerId); });
  rowEl.addEventListener('pointermove', function (e) {
    if (startX !== null) rowEl.style.transform = 'translateX(' + (e.clientX - startX) + 'px)';
  });
  rowEl.addEventListener('pointerup', function (e) {
    const dx = startX === null ? 0 : e.clientX - startX;
    startX = null;
    if (Math.abs(dx) > rowEl.offsetWidth * 0.4 && window.WebToApk && WebToApk.dismissPushMessage(id)) {
      rowEl.remove();
    } else {
      rowEl.style.transform = '';            // not far enough: snap back
    }
  });
}

Note: cambia solo la casella di questo telefono. La notifica nella barra e la tua cronologia di invio in AppMint restano. I messaggi nascosti non vengono restituiti da getPushInbox().

getInAppCampaigns bridge#

window.WebToApk.getInAppCampaigns(): String

Messaggi in-app presenti in questa installazione: JSON [{id, name}] ("[]" senza AppMint Push).

Esempio

Elenca i messaggi in-app che questa installazione contiene in questo momento (le campagne di chi crea l'app dal centro di invio di AppMint Push di cui questo utente fa parte del pubblico) come stringa JSON [{"id": "...", "name": "..."}].

Restituisce: una stringa con un array JSON; "[]" quando non ce ne sono e in un'app creata senza AppMint Push. Richiede: AppMint Push attivato nel passaggio Integrazione (Passaggio 3) quando crei l'app. L'elenco si aggiorna a ogni avvio dell'app (e circa ogni ora in primo piano).

var list = [];
if (window.WebToApk && window.WebToApk.getInAppCampaigns) {
  try { list = JSON.parse(WebToApk.getInAppCampaigns()); } catch (e) {}
}
console.log('in-app messages on this phone:', list.map(function (c) { return c.name; }));

Mostra un elenco di debug nella tua schermata di amministrazione:

function renderInAppDebug(el) {
  var raw = (window.WebToApk && WebToApk.getInAppCampaigns) ? WebToApk.getInAppCampaigns() : '[]';
  var items = JSON.parse(raw);
  el.innerHTML = items.length
    ? items.map(function (c) { return '<li>' + c.name + ' <code>' + c.id + '</code></li>'; }).join('')
    : '<li>No in-app messages for this install</li>';
}
renderInAppDebug(document.getElementById('inapp-debug'));

Salta il tuo suggerimento di benvenuto quando il creatore ha già un messaggio con quel nome:

function hasCampaign(name) {
  try { return JSON.parse(WebToApk.getInAppCampaigns()).some(function (c) { return c.name === name; }); }
  catch (e) { return false; }
}
if (!hasCampaign('Welcome tour')) showMyOwnWelcome();

Note: vengono esposti solo l'id e il nome; il messaggio stesso raggiunge la pagina tramite l'evento appmint:inapp quando viene mostrato (vedi setInAppPresentation).

getPushInbox bridge#

window.WebToApk.getPushInbox(): String

Posta in arrivo di AppMint Push (messaggi inviati da chi crea l'app, dal più recente, max 50): array JSON di {id, title, body, imageUrl, link, receivedAt, read}. È sempre la verità completa e attuale: un'app che si monta in ritardo non perde nulla per aver mancato gli eventi `appmint:push` in tempo reale.

Esempio

Legge la casella in-app dei messaggi push che hai inviato con AppMint Push: dal più recente, fino a 50, senza quelli che l'utente ha scartato.

Restituisce: una stringa JSON, in modo sincrono. Analizzala. Ogni elemento: { id, title, body, imageUrl, link, receivedAt, read } (receivedAt in epoch ms; imageUrl e link sono '' quando il messaggio non li ha), più campi di design facoltativi quando hai usato un modello in AppMint: template, accent, iconUrl, buttons: [{label, link}], badge, inapp, countdownAt, progress, lines, collapse. '[]' quando è vuota. Richiede: attiva AppMint Push nel passaggio Integrazione (Passaggio 3) quando crei l'app; senza, la posta in arrivo è sempre vuota.

Mostra la posta in arrivo e aggiornala in tempo reale con appmint:push:

function loadInbox() {
  if (!(window.WebToApk && window.WebToApk.getPushInbox)) return [];
  try { return JSON.parse(WebToApk.getPushInbox() || '[]'); } catch (e) { return []; }
}

function renderInbox() {
  const inbox = loadInbox();
  const unread = inbox.filter(function (m) { return !m.read; }).length;
  document.getElementById('bell-count').textContent = unread ? String(unread) : '';
  const ul = document.getElementById('inbox');
  ul.innerHTML = '';
  inbox.forEach(function (m) {
    const li = document.createElement('li');
    li.className = m.read ? 'read' : 'unread';
    li.textContent = m.title + ' — ' + m.body;
    li.onclick = function () {
      WebToApk.markPushRead(m.id);
      if (m.link) location.href = m.link;
      renderInbox();
    };
    ul.appendChild(li);
  });
}

// While the app is open:
window.addEventListener('appmint:push', function (e) {
  // { type: 'received', message: {id, title, body, ...}, presented: true|false }
  // { type: 'revoked', id }  — you retracted the message
  // presented = the app already showed it on screen (see setPushPresentation)
  if (e.detail.type === 'received' && !e.detail.presented) showBanner(e.detail.message.title);
  renderInbox();
});

renderInbox();

Aggiorna il conteggio dei non letti sulla tua campanella ogni volta che l'utente torna nell'app (i messaggi arrivati mentre era in background sono già nella casella):

function unreadCount() {
  if (!(window.WebToApk && window.WebToApk.getPushInbox)) return 0;
  try {
    return JSON.parse(WebToApk.getPushInbox() || '[]').filter(function (m) { return !m.read; }).length;
  } catch (e) { return 0; }
}

function paintBell() {
  const n = unreadCount();
  const badge = document.getElementById('bell-count');
  badge.textContent = n > 9 ? '9+' : (n ? String(n) : '');
  badge.hidden = n === 0;
}

document.addEventListener('visibilitychange', function () {
  if (document.visibilityState === 'visible') paintBell();
});
paintBell();

Mostra l'immagine di un messaggio e i suoi pulsanti (solo se li hai progettati), con l'ora di arrivo:

function renderCard(m) {
  const card = document.createElement('article');
  if (m.accent) card.style.borderLeft = '4px solid ' + m.accent;
  if (m.imageUrl) {
    const img = document.createElement('img');
    img.src = m.imageUrl; img.alt = '';
    card.appendChild(img);
  }
  const h = document.createElement('h3');
  h.textContent = m.title;
  const p = document.createElement('p');
  p.textContent = m.body;
  const time = document.createElement('time');
  time.textContent = new Date(m.receivedAt).toLocaleString();
  card.append(h, p, time);
  (m.buttons || []).forEach(function (b) {
    const btn = document.createElement('button');
    btn.textContent = b.label;
    btn.onclick = function () { WebToApk.markPushRead(m.id); if (b.link) location.href = b.link; };
    card.appendChild(btn);
  });
  return card;
}

if (window.WebToApk && window.WebToApk.getPushInbox) {
  const list = document.getElementById('inbox');
  JSON.parse(WebToApk.getPushInbox() || '[]').forEach(function (m) { list.appendChild(renderCard(m)); });
}

Note: la casella è conservata sul telefono, quindi leggila quando si apre la tua schermata: gli eventi arrivano solo mentre l'app è a schermo. Un messaggio che ritiri da AppMint sparisce dalla casella e dalla barra delle notifiche. I messaggi inviati come "solo push" (barra delle notifiche) non vengono aggiunti alla casella. Lo stesso dettaglio viene passato anche a window.onAppMintPush(detail) se lo definisci.

getPushTags bridge#

window.WebToApk.getPushTags(): String

I tag di questa installazione come stringa di oggetto JSON, ad es. {"plan":"pro"}.

Esempio

Legge i tag AppMint Push di questa installazione.

Restituisce: una stringa JSON, in modo sincrono: un oggetto di valori di testo, ad es. '{"plan":"pro","cart":"open"}'; '{}' quando non ce ne sono. Analizzala (parse). Richiede: attiva AppMint Push nel passaggio Integra (Passaggio 3) quando crei l'app.

Leggi un tag:

function pushTags() {
  if (!(window.WebToApk && window.WebToApk.getPushTags)) return {};
  try { return JSON.parse(WebToApk.getPushTags() || '{}'); } catch (e) { return {}; }
}

const plan = pushTags().plan || 'free';

Imposta un tag solo quando cambia: ogni chiamata setPushTag fa registrare l'installazione su AppMint Push, quindi salta quelle che non cambiano nulla:

function ensureTag(key, value) {
  if (!(window.WebToApk && window.WebToApk.getPushTags)) return;
  const tags = JSON.parse(WebToApk.getPushTags() || '{}');
  if ((tags[key] || '') !== value) WebToApk.setPushTag(key, value);
}

ensureTag('plan', user.isPro ? 'pro' : 'free');

Elencali in una schermata di debug mentre provi l'invio a un tag:

const list = document.getElementById('push-tags');
if (window.WebToApk && window.WebToApk.getPushTags) {
  const tags = JSON.parse(WebToApk.getPushTags() || '{}');
  list.textContent = Object.keys(tags).length
    ? Object.keys(tags).map(function (k) { return k + ' = ' + tags[k]; }).join('\n')
    : 'No tags yet';
}

Note: questo è ciò che il telefono conserva; il centro di invio lo vede dopo il prossimo check-in dell'installazione, pochi secondi dopo una modifica quando il telefono è online.

getPushUser bridge#

window.WebToApk.getPushUser(): String

L'ID utente impostato per ultimo con setPushUser ("" se disconnesso o mai impostato).

Esempio

Legge l'ID utente che questa installazione ha comunicato per ultimo ad AppMint Push con setPushUser.

Restituisce: una string, in modo sincrono: l'ID salvato, oppure '' quando nessuno ha effettuato l'accesso o non è mai stato impostato. Richiede: attiva AppMint Push nel passaggio Integra (Passaggio 3) quando crei l'app.

Imposta l'ID solo quando è cambiato (a ogni avvio dell'app):

function syncPushUser(currentUserId) {
  if (!(window.WebToApk && window.WebToApk.getPushUser)) return;
  const want = currentUserId || '';
  if (WebToApk.getPushUser() !== want) WebToApk.setPushUser(want);
}

syncPushUser(localStorage.getItem('userId'));

Cancella un ID obsoleto quando la tua sessione è scaduta mentre l'app era chiusa:

async function checkSession() {
  const session = await myBackend.currentSession();       // null when expired
  if (!session && window.WebToApk && window.WebToApk.getPushUser && WebToApk.getPushUser() !== '') {
    WebToApk.setPushUser('');                              // stop personal messages to this phone
  }
}

checkSession();

Mostralo in una schermata di debug mentre provi l'invio a un singolo utente:

const info = document.getElementById('push-debug');
if (window.WebToApk && window.WebToApk.getPushUser) {
  const id = WebToApk.getPushUser();
  info.textContent = id ? 'Push user: ' + id : 'Push user: nobody signed in';
} else {
  info.textContent = 'Not inside the app';
}

Note: questo è ciò che il telefono conserva. Il centro di invio vede una modifica dopo il prossimo check-in dell'installazione, pochi secondi dopo quando il telefono è online.

markPushRead bridge#

window.WebToApk.markPushRead(id: String): Boolean

Segna come letto un messaggio push; passa "" per segnare come letti tutti i messaggi.

Esempio

Segna come letto un messaggio della posta in arrivo push, oppure tutti quando passi ''.

Restituisce: true se un messaggio è cambiato; false se nulla è cambiato (id sconosciuto, già letto, oppure AppMint Push non attivato). Richiede: attiva AppMint Push nel passaggio Integrazione (Passaggio 3) quando crei l'app.

function openMessage(id) {
  if (!(window.WebToApk && window.WebToApk.markPushRead)) return;
  WebToApk.markPushRead(id);                 // one message
  updateBellCount();
}

document.getElementById('mark-all-read').addEventListener('click', function () {
  if (!(window.WebToApk && window.WebToApk.markPushRead)) return;
  WebToApk.markPushRead('');                 // every message
  updateBellCount();
});

function updateBellCount() {
  const inbox = JSON.parse(WebToApk.getPushInbox() || '[]');
  const unread = inbox.filter(function (m) { return !m.read; }).length;
  document.getElementById('bell-count').textContent = unread ? String(unread) : '';
}

Segna un messaggio come letto una volta che l'utente lo ha davvero visto sullo schermo, non solo quando lo tocca:

if (window.WebToApk && window.WebToApk.markPushRead) {
  const seen = new IntersectionObserver(function (entries) {
    entries.forEach(function (entry) {
      if (!entry.isIntersecting) return;
      const id = entry.target.dataset.msgId;
      seen.unobserve(entry.target);
      if (WebToApk.markPushRead(id)) {       // true only when it was unread
        entry.target.classList.replace('unread', 'read');
        updateBellCount();
      }
    });
  }, { threshold: 0.6 });

  document.querySelectorAll('#inbox li.unread').forEach(function (li) { seen.observe(li); });
}

Azzera il badge quando si apre la schermata della casella, e ridisegna solo se qualcosa era davvero non letto:

function openInboxScreen() {
  showScreen('inbox');
  if (!(window.WebToApk && window.WebToApk.markPushRead)) return;
  const changed = WebToApk.markPushRead('');  // false: nothing was unread
  if (changed) {
    document.getElementById('bell-count').textContent = '';
    renderInbox();
  }
}

Note: lo stato di lettura è salvato solo su questo telefono. Non rimuove la notifica dalla barra delle notifiche.

restorePushMessage bridge#

window.WebToApk.restorePushMessage(id: String): Boolean

Annulla un'eliminazione: rimette il messaggio al suo posto nella posta in arrivo.

Esempio

Annulla dismissPushMessage(id): il messaggio torna nella posta in arrivo push al suo posto di prima.

Restituisce: true se il messaggio è stato ripristinato; false se l'ID è sconosciuto o non era nascosto. Richiede: attiva AppMint Push nel passaggio Integra (Passaggio 3) quando crei l'app.

let lastDismissed = null;

function onSwipe(id) {
  if (!(window.WebToApk && window.WebToApk.dismissPushMessage)) return;
  if (WebToApk.dismissPushMessage(id)) {
    lastDismissed = id;
    showUndo();
    renderInbox();
  }
}

document.getElementById('undo-btn').addEventListener('click', function () {
  if (!lastDismissed || !window.WebToApk) return;
  if (WebToApk.restorePushMessage(lastDismissed)) renderInbox();
  lastDismissed = null;
});

Annulla più swipe in una volta: ricorda ogni messaggio nascosto su questa schermata e ripristinali tutti:

const hiddenThisVisit = [];

function hide(id) {
  if (window.WebToApk && WebToApk.dismissPushMessage(id)) {
    hiddenThisVisit.push(id);
    document.getElementById('undo-all').hidden = false;
    renderInbox();
  }
}

document.getElementById('undo-all').addEventListener('click', function () {
  if (!(window.WebToApk && window.WebToApk.restorePushMessage)) return;
  hiddenThisVisit.splice(0).forEach(function (id) { WebToApk.restorePushMessage(id); });
  this.hidden = true;
  renderInbox();
});

Offri un elenco "Nascosti di recente" da cui l'utente può ripristinare i messaggi in seguito. getPushInbox() non restituisce i messaggi nascosti, quindi conserva tu i loro ID e titoli:

function loadHidden() {
  try { return JSON.parse(localStorage.getItem('hiddenMsgs') || '[]'); } catch (e) { return []; }
}

function renderHidden() {
  const ul = document.getElementById('recently-hidden');
  ul.innerHTML = '';
  loadHidden().forEach(function (h) {
    const li = document.createElement('li');
    li.textContent = h.title + ' ';
    const btn = document.createElement('button');
    btn.textContent = 'Restore';
    btn.onclick = function () {
      WebToApk.restorePushMessage(h.id);     // false: retracted, cleared or already back
      const rest = loadHidden().filter(function (x) { return x.id !== h.id; });
      try { localStorage.setItem('hiddenMsgs', JSON.stringify(rest)); } catch (e) {}
      renderHidden();
      renderInbox();
    };
    li.appendChild(btn);
    ul.appendChild(li);
  });
}

Note: un messaggio cancellato con clearPushInbox() o ritirato da te da AppMint non può essere ripristinato.

setInAppPresentation bridge#

window.WebToApk.setInAppPresentation(mode: String): Boolean

Presentazione dei messaggi in-app: "auto" (predefinito) lascia che la shell disegni il design di chi crea l'app; "none" (persistente) passa ogni messaggio alla pagina come `appmint:inapp` {type:'shown', presented:false, message} perché lo disegni da sé.

Esempio

Sceglie chi disegna un messaggio in-app (una campagna dal centro di invio di AppMint Push) quando scatta il suo trigger: l'app ('auto', il predefinito: il banner, la scheda centrale, il pannello inferiore o il design a schermo intero del creatore) oppure la tua pagina ('none').

Restituisce: true quando la modalità è stata salvata (resta sul telefono finché non viene cambiata); false per qualsiasi altro valore e in un'app creata senza AppMint Push. Richiede: AppMint Push attivato nel passaggio Integrazione (Passaggio 3) quando crei l'app.

Ogni messaggio in-app genera l'evento appmint:inapp (e chiama window.onAppMintInApp(detail) se lo hai definito) con type 'shown', 'clicked', 'dismissed' oppure 'answered' (una risposta con stelle o punteggio da 0 a 10, con question e value):

window.addEventListener('appmint:inapp', function (e) {
  var d = e.detail;   // { type, id, name, template?, presented?, message?, button?, link?, question?, value? }
  if (d.type === 'shown') analytics('inapp_shown', d.name);
  if (d.type === 'clicked') analytics('inapp_clicked', d.name + ' #' + d.button);
  if (d.type === 'dismissed') analytics('inapp_closed', d.name);
  if (d.type === 'answered') analytics('inapp_answer', d.name + ' ' + d.question + '=' + d.value);
});

Disegna tu i messaggi; l'app te li consegna invece di mostrarli:

if (window.WebToApk && WebToApk.setInAppPresentation) WebToApk.setInAppPresentation('none');

window.onAppMintInApp = function (d) {
  if (d.type !== 'shown' || d.presented) return;   // presented = the app already drew it
  var m = d.message;                                // { title, body, imageUrl, link, inapp, accent?, buttons?, emoji?, question?, lines? }
  showMyDialog(m.title, m.body, (m.buttons || []).map(function (b) {
    return { label: b.label, onClick: function () { if (b.link) location.href = b.link; } };
  }));
};

Restituisci la scelta all'app (per esempio da un interruttore nelle impostazioni):

document.getElementById('native-popups').addEventListener('change', function (e) {
  if (window.WebToApk && WebToApk.setInAppPresentation) {
    WebToApk.setInAppPresentation(e.target.checked ? 'auto' : 'none');
  }
});

Note: con 'none' un messaggio conta comunque come mostrato (si applicano i suoi limiti di frequenza) nel momento in cui viene consegnato alla pagina. Impostare 'none' chiude anche un messaggio che l'app sta mostrando in quel momento. I messaggi push hanno un proprio interruttore, setPushPresentation.

setPushPresentation bridge#

window.WebToApk.setPushPresentation(mode: String): Boolean

Presentazione nativa in-app dei messaggi push: "auto" (predefinito) lascia che la shell disegni il banner / modale / pannello / scheda a schermo intero scelti dal creatore mentre l'app è aperta; "none" la disattiva definitivamente (salvato) - per le app che disegnano i propri. L'evento `appmint:push` e la casella non cambiano in nessuno dei due casi; il flag `presented` dell'evento ricevuto dice se la shell lo ha mostrato.

Esempio

Attiva ('auto', il valore predefinito) o disattiva ('none') la visualizzazione sullo schermo dei messaggi AppMint Push da parte dell'app stessa, per le app che disegnano un proprio banner dall'evento appmint:push.

Restituisce: true quando la modalità è stata salvata; false per qualsiasi valore diverso da 'auto' o 'none'. La scelta viene salvata sul telefono e resta finché non la cambi. Richiede: attiva AppMint Push nel passaggio Integra (Passaggio 3) quando crei l'app.

Disegna il tuo banner invece di quello della shell:

if (window.WebToApk && window.WebToApk.setPushPresentation) {
  WebToApk.setPushPresentation('none');       // 'auto' to give it back to the shell
}

window.addEventListener('appmint:push', function (e) {
  const d = e.detail;
  // { type: 'received', message: {...}, presented: false } — presented = the shell already showed it
  if (d.type === 'received' && !d.presented) showMyBanner(d.message.title, d.message.body, d.message.link);
  if (d.type === 'revoked') hideMyBanner(d.id);
});

Lascia che l'utente disattivi i pop-up nella tua schermata delle impostazioni. Non esiste un getter, quindi conserva tu una copia della scelta per disegnare l'interruttore:

const toggle = document.getElementById('show-popups');
let saved = null;
try { saved = localStorage.getItem('pushPopups'); } catch (e) {}
toggle.checked = saved !== 'none';

toggle.addEventListener('change', function () {
  if (!(window.WebToApk && window.WebToApk.setPushPresentation)) return;
  const mode = toggle.checked ? 'auto' : 'none';
  if (WebToApk.setPushPresentation(mode)) {
    try { localStorage.setItem('pushPopups', mode); } catch (e) {}
  }
});

Con 'auto', scopri cosa ha fatto l'utente con un messaggio mostrato dall'app a schermo: opened quando lo ha toccato (action è -1 per il messaggio stesso, altrimenti l'indice del pulsante), closed quando lo ha chiuso senza toccarlo:

window.addEventListener('appmint:push', function (e) {
  const d = e.detail;
  if (d.type === 'opened') {
    // the message is already marked read in the inbox
    track('push_opened', { id: d.id, button: d.action, link: d.link });
    updateBellCount();
  } else if (d.type === 'closed') {
    track('push_closed', { id: d.id });
  }
});

Note: con 'auto', un messaggio inviato con stile in-app viene mostrato sopra l'app mentre è aperta (e poi non viene messo anche nella barra delle notifiche). Con 'none' la shell non lo disegna mai; la casella (getPushInbox) e l'evento appmint:push funzionano allo stesso modo in entrambi i casi. Impostare 'none' chiude anche un messaggio che la shell sta mostrando in quel momento.

setPushTag bridge#

window.WebToApk.setPushTag(key: String, value: String): Boolean

Imposta un tag di AppMint Push (chiave: lettere, cifre, _ fino a 32; valore fino a 128). Il centro di invio può puntare a "plan = pro", e un'automazione può partire a un tempo stabilito dopo l'impostazione di un tag (un carrello abbandonato: imposta cart=open, cancellalo al checkout). Un valore vuoto rimuove il tag. Fino a 50 tag per installazione.

Esempio

Imposta un tag AppMint Push su questa installazione, come plan = pro o city = pune. Il centro di invio (Home > Notifiche) può inviare a tutti quelli con un tag, e un'automazione sui tag può inviare un messaggio a un certo intervallo dopo l'impostazione di un tag: un carrello abbandonato, un livello completato. Un valore vuoto rimuove il tag.

Restituisce: true quando è salvato; false quando la chiave non è composta da 1-32 lettere, cifre o _, il valore supera i 128 caratteri, o l'installazione avrebbe più di 50 tag (in tal caso non viene salvato nulla). I tag sono conservati sul telefono e comunicati ad AppMint Push poco dopo (o al prossimo avvio se sei offline). Richiede: attiva AppMint Push nel passaggio Integra (Passaggio 3) quando crei l'app. Il targeting per tag e le automazioni raggiungono i telefoni con un'app creata con AppMint dal 30 set 2026 in poi.

Applica un tag a ciò che l'utente ha acquistato o scelto, così puoi inviare solo a "plan = pro":

function pushTag(key, value) {
  if (!(window.WebToApk && window.WebToApk.setPushTag)) return false;
  return WebToApk.setPushTag(key, value);
}

pushTag('plan', user.isPro ? 'pro' : 'free');
pushTag('city', user.city.toLowerCase());

Carrello abbandonato: imposta un tag quando ci sono articoli nel carrello e cancellalo al checkout. Nel centro di invio, aggiungi un'automazione di tag su cart con un ritardo (ad esempio 60 minuti); un telefono riceve il promemoria solo se cart è ancora impostato allo scadere del tempo:

function onCartChanged(items) {
  if (!(window.WebToApk && window.WebToApk.setPushTag)) return;
  // Setting 'open' again while it is already 'open' does not restart the automation's clock.
  WebToApk.setPushTag('cart', items.length > 0 ? 'open' : '');
}

function onCheckoutComplete() {
  if (window.WebToApk && window.WebToApk.setPushTag) WebToApk.setPushTag('cart', '');   // bought: no reminder
}

Cancella i tag specifici dell'utente alla disconnessione, insieme all'id utente:

function signOutOfPush() {
  if (!(window.WebToApk && window.WebToApk.setPushUser)) return;
  WebToApk.setPushUser('');
  WebToApk.setPushTag('plan', '');
  WebToApk.setPushTag('cart', '');
}

Note: i tag appartengono a questa installazione, non all'utente che ha effettuato l'accesso. Impostare un tag sul valore che ha già non cambia nulla sul server. Dopo la rimozione di un tag, reimpostarlo permette a un'automazione di tag di inviare di nuovo. Non inserire mai in un tag un indirizzo e-mail, un numero di telefono o qualsiasi dato privato.

setPushTags bridge#

window.WebToApk.setPushTags(json: String): Boolean

Imposta più tag in una volta da una stringa con un oggetto JSON; i valori "" rimuovono.

Esempio

Imposta più tag di AppMint Push in una volta da una stringa di oggetto JSON, ad es. '{"plan":"pro","team":"red"}'. Un valore "" rimuove quel tag; i tag che non nomini restano.

Restituisce: true quando è salvato; false quando la stringa non è un oggetto JSON, una chiave non è composta da 1-32 lettere, cifre o _, un valore supera i 128 caratteri, o l'installazione finirebbe con più di 50 tag: in tal caso non viene salvato nulla. Richiede: attiva AppMint Push nel passaggio Integra (Passaggio 3) quando crei l'app. Il targeting per tag e le automazioni raggiungono i telefoni con un'app creata con AppMint dal 30 set 2026 in poi.

Dopo l'accesso, applica i tag al profilo con una sola chiamata:

function tagProfile(profile) {
  if (!(window.WebToApk && window.WebToApk.setPushTags)) return false;
  return WebToApk.setPushTags(JSON.stringify({
    plan: profile.plan,                   // 'free' | 'pro'
    level: String(profile.level),         // values are text: turn numbers into strings
    team: profile.team || ''              // '' removes the tag
  }));
}

Al logout, rimuovili tutti (leggi i tag attuali, rimandali ciascuno come ''):

function clearPushTags() {
  if (!(window.WebToApk && window.WebToApk.getPushTags)) return;
  const tags = JSON.parse(WebToApk.getPushTags() || '{}');
  Object.keys(tags).forEach(function (k) { tags[k] = ''; });
  WebToApk.setPushTags(JSON.stringify(tags));
  WebToApk.setPushUser('');
}

Livello completato: applica un tag e lascia che un'automazione di tag su level_done (ad esempio 10 minuti) invii la sfida successiva:

function onLevelComplete(level, score) {
  if (!(window.WebToApk && window.WebToApk.setPushTags)) return;
  WebToApk.setPushTags(JSON.stringify({
    level_done: String(level),            // a new value each level, so the automation can fire again
    last_score: String(score)
  }));
}

Note: una chiamata è una modifica: o viene salvato tutto o niente. L'installazione comunica i nuovi tag ad AppMint Push poco dopo (o al prossimo avvio se sei offline).

setPushUser bridge#

window.WebToApk.setPushUser(id: String): Boolean

Pubblico di AppMint Push: dice al centro di invio del creatore CHI è questa installazione, così un messaggio può arrivare a un singolo utente che ha effettuato l'accesso ("u_42") o a tutti quelli con un tag. Chiamalo dopo l'accesso con il tuo ID account stabile; passa "" al logout. Lettere, cifre e _ @ . : + - (fino a 128). Restituisce false per qualsiasi altro valore, e in un'app che non usa AppMint Push (OneSignal / Firebase proprio: non viene inviato nulla, 2026-10-03). Non passare mai un indirizzo e-mail o un numero di telefono: usa l'ID del tuo database.

Esempio

Dice ad AppMint Push quale dei TUOI utenti ha effettuato l'accesso su questo telefono, così il centro di invio (Home > Notifiche) può inviare un messaggio a quel singolo utente. Chiamalo dopo l'accesso con il tuo ID account stabile; chiamalo con '' al logout.

Restituisce: true quando l'id è stato salvato; false per un id con caratteri diversi da lettere, cifre e _ @ . : + -, oppure più lungo di 128 caratteri (in quel caso non viene salvato nulla). L'id resta sul telefono finché non lo cambi, e questa installazione lo comunica ad AppMint Push poco dopo (o al prossimo avvio se è offline). Richiede: attiva AppMint Push nel passaggio Integrazione (Passaggio 3) quando crei l'app. L'invio a un utente raggiunge i telefoni con un'app creata con AppMint dal 30 set 2026 in poi; le build più vecchie ricevono comunque i messaggi inviati a Tutti.

Dopo l'accesso e al logout: usa l'ID del tuo database, mai un indirizzo e-mail o un numero di telefono:

function pushUser(id) {
  if (!(window.WebToApk && window.WebToApk.setPushUser)) return false;   // browser, or an older build
  return WebToApk.setPushUser(id);
}

async function signIn(email, password) {
  const user = await myBackend.signIn(email, password);   // your own sign-in
  pushUser(user.id);                                      // e.g. 'u_42' or a UUID
}

async function signOut() {
  await myBackend.signOut();
  pushUser('');                                           // this phone is nobody's now
}

Supabase: segui la sessione, così conta sia una sessione ripristinata sia un nuovo accesso:

supabase.auth.onAuthStateChange(function (event, session) {
  if (!(window.WebToApk && window.WebToApk.setPushUser)) return;
  const id = session ? session.user.id : '';     // the auth UUID: letters, digits and '-'
  if (WebToApk.getPushUser() !== id) WebToApk.setPushUser(id);
});

Rendi accettabile un ID quando il tuo può contenere altri caratteri (spazi, /, #), e registra quello raro che viene comunque rifiutato:

function pushUserIdFrom(rawId) {
  return String(rawId).trim().replace(/[^A-Za-z0-9_@.:+\-]/g, '_').slice(0, 128);
}

if (window.WebToApk && window.WebToApk.setPushUser) {
  const ok = WebToApk.setPushUser(pushUserIdFrom(currentUser.id));
  if (!ok) console.warn('push user id refused', currentUser.id);
}

Note: lo stesso utente che ha effettuato l'accesso su due telefoni viene raggiunto su entrambi. L'ID appartiene a questa installazione, non all'account: il logout deve cancellarlo, altrimenti il telefono continua a ricevere i messaggi dell'utente precedente. setPushUser('') non cancella i tag impostati con setPushTag; cancella al logout anche i tag specifici dell'utente.

trackEvent bridge#

window.WebToApk.trackEvent(name: String, propsJson: String): Boolean

Messaggi in-app: segnala un evento su cui le campagne di chi crea l'app possono reagire (trigger "event", stesso nome). propsJson è JSON facoltativo. Il nome `appmint:route` con {"path":"/x"} segnala un cambio di vista che l'URL non mostra. False per un nome fuori da [A-Za-z0-9_.:-]{1,64} e senza AppMint Push.

Esempio

Dice all'app che è successo qualcosa ("signed_up", "checkout_done", "level:3"). Un messaggio in-app creato nel centro di invio di AppMint Push con il trigger "Quando accade un evento" e lo stesso nome viene mostrato subito (o dopo l'attesa scelta dal creatore).

Restituisce: true quando l'evento è stato accettato; false per un nome fuori da lettere, cifre e _ . : - (fino a 64), e in un'app creata senza AppMint Push. AppMint.trackEvent(name, props) è la stessa chiamata con props come oggetto. Richiede: AppMint Push attivato nel passaggio Integrazione (Passaggio 3) quando crei l'app. propsJson è facoltativo ('') e non viene salvato.

// After a purchase: the creator's "Thanks, rate us?" message is set to trigger on "purchase_done".
function onPurchaseDone(order) {
  if (window.AppMint && AppMint.trackEvent) {
    AppMint.trackEvent('purchase_done', { total: order.total });
  }
}

Il bridge grezzo accetta le proprietà come stringa JSON (passa '' per nessuna):

function track(name, props) {
  if (!(window.WebToApk && window.WebToApk.trackEvent)) return false;   // a browser: nothing to show
  return WebToApk.trackEvent(name, props ? JSON.stringify(props) : '');
}
track('level:3');
track('tutorial_skipped', { step: 2 });

Un cambio di schermata che l'indirizzo non mostra (schede, una procedura guidata, una "pagina" modale) può essere segnalato come percorso, così i messaggi "In una pagina" del creatore lo vedono. La pagina può anche inviare l'evento appmint:route con il percorso; l'app lo ascolta:

function showTab(name) {
  document.querySelectorAll('.tab').forEach(function (t) { t.hidden = t.id !== name; });
  if (window.AppMint && AppMint.trackEvent) AppMint.trackEvent('appmint:route', { path: '/' + name });
}

// Same thing, without touching the bridge at all:
window.dispatchEvent(new CustomEvent('appmint:route', { detail: { path: '/cart' } }));

Note: i messaggi per percorso seguono già da soli le vere modifiche di URL (caricamenti di pagina, percorsi history.pushState, #/hash); segnala un percorso solo per le viste in cui l'indirizzo non cambia. Gli eventi non vengono contati né salvati da nessuna parte; servono solo a decidere se un messaggio viene mostrato.

Generato dal runtime dell'app e dai suoi file di esempio a ogni build della documentazione. Leggilo in Markdown · Tutte le famiglie.

Verificato rispetto al bridge distribuito il 22/10/2026.