Code in der App
Fast alles in einer Mini-App wird ohne Code gebaut. Reichen die fertigen Elemente und Blöcke nicht aus, können Sie eigenen Code an drei Stellen hinzufügen:
| Wo | Wann er ausgeführt wird | Wofür |
|---|---|---|
| Block „JavaScript“ | Wenn das Szenario den Block erreicht | Eine Aktion beim Tippen: Text kopieren, einen Link öffnen, einen Wert berechnen, mit der Bridge des Messengers sprechen |
| App-Code | Einmal beim Start, vor dem ersten Bildschirm, und danach bei Ereignissen | Analytics-Zähler, eigene Stile, externe Widgets |
| „HTML-Code“ — ein Element oder ein ganzer Bildschirm | Solange der Bildschirm geöffnet ist | Eigenes Layout, ein Rechner, ein Widget eines fremden Dienstes |
Der Code läuft auf dem Gerät der Person. Wer sich mit dem Browser auskennt, kann ihn deshalb sehen und fälschen, was der Code an den Server sendet. Legen Sie keine geheimen Schlüssel im Code ab und begrenzen Sie, welche Variablen und Tags der Code ändern darf — mehr dazu unten.
Block „JavaScript“
Ein Block aus der Kategorie „Daten und Logik“. Erreicht die App den Block, führt sie den Code aus und geht über den Ausgang „Ausgeführt“ oder „Fehler“ weiter.
| Einstellung | Was sie festlegt |
|---|---|
| „Code“ | Der Rumpf einer asynchronen Funktion: Schreiben Sie mit await und dem Objekt app. Bis zu 20 000 Zeichen |
| „Zeitlimit, Sekunden“ | Von 1 bis 60, standardmäßig 10. Dauert es länger, geht das Szenario über den Ausgang „Fehler“ weiter, und der Code selbst kann im Hintergrund zu Ende laufen |
| „Ergebnisvariable“ | Was return zurückgegeben hat. Ein Objekt wird als JSON gespeichert |
| „Fehlervariable“ | Der Fehlertext — für den Bildschirm nach dem Ausgang „Fehler“ |
| „Was der Code ändern darf“ | Die Liste des Erlaubten — siehe unten |


Platzhalter {{ name }} funktionieren im Code nicht: Lesen Sie Variablenwerte über app.variables.get().
Variablen, die über app.variables.set() geschrieben wurden, und geänderte Tags gehen zusammen mit dem Ausgang des Blocks an den Server.
„Was der Code ändern darf“
Der Schalter „Nur Aufgelistetes ändern“ ist bei einem neuen Block eingeschaltet. Damit nimmt der Server vom Code nur Folgendes an:
- Variablen aus der Liste „Variablen“;
- Tags aus den Listen „Tags des Bot-Kontakts“ und „Tags des App-Nutzers“ — eine leere Liste bedeutet, dass der Code diese Tags gar nicht ändert;
- die Ergebnis- und die Fehlervariable — sie sind immer erlaubt.
Alles andere verwirft der Server und schreibt in das Fehlerprotokoll „Der Block hat das vom Code Geschriebene verworfen“. Schreibt der Code Namen, die nicht in den Listen stehen, warnen die Einstellungen des Blocks davor und bieten „Zu den Listen hinzufügen“ an.
Schalten Sie die Einschränkung nur aus, wenn nichts von den Variablen und Tags abhängt: Sonst kann sich eine Person zum Beispiel das Tag VIP oder einen Rabatt verschaffen.
Das Objekt app
| Aufruf | Was er tut |
|---|---|
app.variables.get('name') |
Wert einer Variable |
app.variables.set('name', value) |
Variable schreiben — geht mit dem Ausgang des Blocks an den Server |
app.variables.all() |
Alle Variablen als Objekt |
app.tags.has('vip') / add('vip') / remove('vip') / all() |
Tags des App-Nutzers — jeder hat sie, auch ohne Chatbot |
app.contact?.name |
Kontakt des Chatbots: id, name, first_name, last_name, username, phone, email, address, source, created_at, telegram_id, max_id. null, wenn die App nicht aus einem Bot geöffnet wurde |
app.contact.variables.get('name') / set('name', value) |
Eigene Variablen des Kontakts, getrennt von den Variablen der App. Was geschrieben wird, geht mit dem Ausgang des Blocks in den Kontakt |
app.contact.tags.has('vip') / add / remove / all() |
Tags des Bot-Kontakts |
app.platform |
Woher die App geöffnet wurde: telegram, max, webchat, pwa oder browser |
app.startParam |
Parameter des Startlinks (startapp) |
app.user |
language, name und username im Messenger |
app.device |
mode (ios oder md), dark, standalone, width, height, userAgent |
await app.toast(message) |
Kurzmeldung |
await app.alert(message, title) |
Meldung mit dem Button OK — wartet, bis sie geschlossen wird |
await app.confirm(question) |
Ja/Nein-Frage — gibt true oder false zurück |
app.openLink('https://…') |
Link öffnen: im Messenger über dessen Mittel, sonst in einem neuen Tab |
await app.copy(text) |
In die Zwischenablage kopieren |
await app.share({title, text, url}) |
Das Teilen-Menü des Systems; ohne es wird der Link kopiert |
app.vibrate('success') |
Vibration: light, medium, heavy, success, warning oder error |
app.localStorage.setItem('key', 'value') |
Speicher des Nutzers auf dem Server — siehe unten |
app.storage.get('key') / set / remove |
Speicher auf dem Gerät, eigener für jede App |
await app.sleep(500) |
Die angegebene Zahl von Millisekunden warten |
app.close() |
App schließen |
app.telegram |
Telegram.WebApp direkt, außerhalb von Telegram — null |
app.max |
Die Bridge von MAX direkt, außerhalb von MAX — null |
Beispiel aus den Einstellungen des Blocks:
// Thema und Bildschirmbreite – in Variablen
const device = app.device
app.variables.set('theme', device.dark ? 'dark' : 'light')
if (app.platform === 'telegram') {
app.vibrate('success')
}
// Der Rückgabewert kommt in die Ergebnisvariable
return device.width
Fehler im Code sind in der Vorschau in der Browserkonsole sichtbar und landen im Fehlerprotokoll — „JavaScript-Fehler“.
App-Code
Code für die ganze App: Er wird einmal beim Start ausgeführt, vor dem ersten Bildschirm, und hört auf Ereignisse. Sie öffnen ihn mit dem Button „App-Code“ (Symbol „</>“) in der Leiste über dem Schema. Ist Code hinterlegt, ist das Symbol eingefärbt.
Im Fenster „App-Code“:
- „Code“ — bis zu 100 000 Zeichen;
- „Variablen, die der Code schreiben darf“ — bis zu 50 Namen. Andere Variablen nimmt der Server nicht an;
- eine Übersicht der Ereignisse und ein „Beispiel“ mit dem Button „Beispiel einfügen“.


Der Code wird in der Version gespeichert: Eine neue Version und eine Vorlage erhalten eine Kopie davon. Nach dem Speichern startet eine geöffnete Vorschau neu.
Ereignisse
| Abonnement | Wann es auslöst |
|---|---|
app.on('start', ({platform, startParam}) => {}) |
Die App wurde gestartet |
app.on('screen', ({id, name, type}) => {}) |
Ein Bildschirm oder ein Fenster darüber wird angezeigt |
app.on('event', ({blockId, eventId}) => {}) |
Tippen auf einen Button, einen Listenpunkt oder ein Element — vor dem Senden an den Server |
app.on('field', ({variable, value}) => {}) |
Die Person hat ein Eingabefeld geändert |
app.on('error', ({message}) => {}) |
Die App hat einen Fehler angezeigt |
app.on('hide', () => {}) / app.on('show', () => {}) |
Die App wurde ausgeblendet und wieder geöffnet |
app.on('theme', ({dark}) => {}) |
Helles oder dunkles Design wurde gewechselt |
app.on('storage', ({key, newValue}) => {}) |
Der Code eines Elements „HTML“ hat in localStorage geschrieben |
- Ein Abonnement auf
start,screenundthemeerhält sofort den aktuellen Wert — auch wenn es nachawaitabgeschlossen wurde. app.on()gibt eine Funktion zum Abbestellen zurück:const stop = app.on(…); stop(). Es gibt auchapp.off(name, handler).await app.loadScript('https://…')lädt ein externes Skript: einen Zähler, ein Widget, eine Bibliothek. Die Adresse — nurhttp://oderhttps://.
Alles andere wie beim Block „JavaScript“: app.variables, app.toast, app.alert, app.openLink, app.storage, app.localStorage, app.telegram und weitere. app.contact und app.tags sind hier nur lesbar: Tags zu ändern ist Aufgabe der Tag-Blöcke.
Variablen, die über app.variables.set() geschrieben wurden, gehen mit dem nächsten Ereignis an den Server.
Beispiel aus dem Fenster — Google-Tag:
// Google-Tag einbinden
window.dataLayer = window.dataLayer || []
function gtag() { dataLayer.push(arguments) }
gtag('js', new Date())
gtag('config', 'G-XXXXXXXXXX', {send_page_view: false})
await app.loadScript('https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX')
// Jeder Bildschirm ist ein Seitenaufruf
app.on('screen', ({id, name}) => {
gtag('event', 'page_view', {page_title: name, page_location: location.origin + '/screen/' + id})
})
// Tippen sind Ereignisse
app.on('event', ({eventId}) => {
gtag('event', 'tap', {event_id: eventId})
})
Fehler im App-Code — beim Start und in den Handlern — sind in der Konsole sichtbar und landen im Fehlerprotokoll mit dem Grund „Fehler im App-Code“ und dem Aufrufstapel. Derselbe Fehler wird nur einmal geschrieben.
„HTML-Code“: Element und Bildschirm
Eigenes HTML mit Skripten und Stilen gibt es in zwei Formen:
- Element „HTML-Code“ — in der Gruppe „Widgets“, steht in einem Bereich des Bildschirms neben anderen Elementen;
- Bildschirm „HTML-Code“ — die dritte Bildschirmart nach „Standardfenster“ und „Tabs unten“: Der ganze Bildschirm ist Ihr Code, ohne Kopfzeile und Bereiche. Ein neuer Bildschirm dieser Art erhält sofort ein Beispiel mit einem Button und den Ausgang
next. Zu einem modalen Fenster lässt er sich nicht machen.
Der Code läuft in einem isolierten Frame: Sitzung, Daten der App und der übrige Bildschirm sind für ihn nicht erreichbar. Skripte und Stile gehören in den Code. Die Textfarbe übernimmt der Frame aus dem Design der App.
| Einstellung | Was sie festlegt |
|---|---|
| „Code“ | HTML bis zu 100 000 Zeichen |
| „Höhe“ (beim Element) | „Nach Inhalt“ — passt sich dem Code an, auch wenn er seinen Inhalt selbst ändert; „Fest“ — von 40 bis 2000 Pixel, was nicht hineinpasst, wird innerhalb gescrollt |
| „Ausgänge“ | Bis zu 20. Ein Ausgang hat einen „Schlüssel“ (lateinische Buchstaben, Ziffern, _ und -) und einen „Name im Schema“. Ein Ausgang ist ein Übergang zu einem anderen Block des Schemas |
| „Variablen, die der Code schreiben darf“ | Bis zu 50 Namen. Andere nimmt der Server nicht an |


Was der Code im Frame nutzen kann
| Aufruf | Was er tut |
|---|---|
app.event('next') |
Über den Ausgang mit diesem Schlüssel weitergehen |
app.event('next', {name: 'value'}) |
Weitergehen und erlaubte Variablen schreiben |
app.variables.set('name', 'value') |
Eine erlaubte Variable sofort schreiben, ohne Übergang: Der Bildschirm bleibt |
localStorage.setItem('key', 'value') |
Speicher des Nutzers auf dem Server — siehe unten. sessionStorage gilt, solange der Bildschirm offen ist |
app.openLink('https://…') |
Einen Link im Browser öffnen. Gewöhnliche Links <a> öffnen sich genauso |
{{ name }} |
Den Wert einer Variable direkt in den Code einsetzen — als Text, maskiert |
Im Schema wird der Code nicht ausgeführt — stattdessen erscheint ein Platzhalter. Im Bildschirm-Editor zeigt der Frame das Ergebnis und startet nach einer Änderung des Codes neu.
Speicher
localStorage auf dem Server |
app.storage |
|
|---|---|---|
| Wo verfügbar | localStorage im Frame „HTML-Code“, app.localStorage im Block „JavaScript“ und im App-Code |
Block „JavaScript“ und App-Code |
| Wo er liegt | Auf dem Server, beim App-Nutzer | Im Browser der Person |
| Übersteht | Neustart, Leeren des Telefons, Gerätewechsel im selben Messenger | Bis die Browserdaten gelöscht werden |
| Gemeinsam | Für alle Elemente „HTML-Code“, den App-Code und die Blöcke „JavaScript“ einer App | Eigener für jede App |
| Werte | Nur Strings, bis zu 100 000 Zeichen samt Schlüsseln | Beliebige Werte, gespeichert als JSON |
Der Speicher auf dem Server ist für jede Plattform eigen: Bei derselben Person ist er in Telegram, MAX und im Browser verschieden.
Einschränkungen
- Der Code des Blocks „JavaScript“ hat bis zu 20 000 Zeichen, der App-Code und der HTML-Code bis zu 100 000.
- Das Zeitlimit des Blocks „JavaScript“ beträgt bis zu 60 Sekunden.
- Ins Protokoll gelangen höchstens 20 Fehler pro Minute von einem Block.