<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://knuddels-wiki.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tom+Unterwegs</id>
	<title>Knuddels-Wiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://knuddels-wiki.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tom+Unterwegs"/>
	<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php/Spezial:Beitr%C3%A4ge/Tom_Unterwegs"/>
	<updated>2026-06-07T04:02:15Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=User_App:Frontend/Environment&amp;diff=129933</id>
		<title>User App:Frontend/Environment</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=User_App:Frontend/Environment&amp;diff=129933"/>
		<updated>2019-11-05T17:31:02Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Es gibt bei der HTML-UI ein paar Besonderheiten bzw. Anpassungen die ihr bei einer unveränderten Browser-Umgebung nicht hättet. Hier werden diese näher erleutert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== UserApps Client-API ==&lt;br /&gt;
&lt;br /&gt;
Die [https://developer.knuddels.de/docs/modules/HTMLUI.html Client-API] (alle APIs dort mit `Client.&amp;lt;xxx&amp;gt;`) sind zusätzlich verfügbar. diese stellen euch ein paar Hilfs-Methoden zur Verfügung und sind die Schnittstelle um Events an den Server zu schicken und von diesem zu empfangen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Erzwungene Client-Updates ==&lt;br /&gt;
&lt;br /&gt;
Öffnet sich beim Nutzer eine HTML-UI (auch von SystemApps - also von Knuddels selbst veröffentlichen Features) und wir erkennen dass der Nutzer einen veralteten Chat-Client verwendet der für die zu öffnende HTML-UI nicht geeignet ist, dann wird dem Nutzer statt der HTML-UI ein Migrations/Update-Hinweis angezeigt. Dies betrifft vor allem Nutzer mit einer veralteten PC-App von Knuddels.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Neuer AppLoader ==&lt;br /&gt;
&lt;br /&gt;
Seit dem 17.07.2018 gibt es für HTML-UIs eine neue Loader Architektur, der neue &amp;quot;AppLoader&amp;quot;. Dieser bringt einige neue Möglichkeiten, Features und Änderungen an APIs mit sich. Auf diese wird in den folgenden Abschnitten eingegangen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Polyfills (API-Patches die wir automatisch einspielen) ==&lt;br /&gt;
&lt;br /&gt;
Es liegt leider in der Natur der Browser, dass nicht alle (Firefox, Chrome, Edge, Safari, Chrome for Android, jxBrowser [Desktop App], Internet Explorer) das gleiche Set an Features und API unterstützen. Manchmal haben bestimmte Implementierungen auch Bugs. Daher patchen wir den Browser bevor die erste Zeile eures Codes ausgeführt wird. Wir patchen folgende APIs:&lt;br /&gt;
&lt;br /&gt;
* [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promise] (API für asynchrone Programmierung)&lt;br /&gt;
* [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign Object.assign] (Manipulation von Javascript-Objekten)&lt;br /&gt;
* [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol Symbol] (hier benutzen wir das NPM Package &#039;core-js/modules/es6.symbol&#039;)&lt;br /&gt;
* [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator Symbol.interator] (hier benutzen wir das NPM Package &#039;core-js/fn/symbol/iterator.js&#039;)&lt;br /&gt;
* [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith String.prototype.startsWith]&lt;br /&gt;
&lt;br /&gt;
Ihr müsst diese Patches/Polyfills also nicht mehr selbst einbinden, falls ihr diese API/Features benutzen wollt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sandbox &amp;lt;iframe&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Eure HTML-UI wird innerhalb eines [https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe &amp;lt;iframe&amp;gt;] das in einer [https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#Attributes Sandbox (siehe &amp;quot;sandbox&amp;quot;-Attribute)] ausgeführt wird geladen. Das bringt ein paar Einschränkungen mit sich, die ihr in der verlinkten Dokumentation zum sandbox-Attribut nachlesen könnt. Auch Zugriff zu Kamera und Mikrofon sind nicht möglich.&lt;br /&gt;
Es sind folgendes allow-* Flags gesetzt: allow-forms, allow-orientation-lock, allow-pointer-lock, allow-same-origin, allow-scripts&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Veränderungen von Web-APIs ==&lt;br /&gt;
&lt;br /&gt;
Wir haben auch einige wenige normale Web-APIs verändert. Das haben wir vor allem getan da diese technische Probleme provozieren können oder konnten oder weil sie die User-Experience stark negativ beeinflussen können.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;alert()&#039;&#039; erzeugt jetzt ein Warning und wird sonst ersetzt durch [https://developer.mozilla.org/en-US/docs/Web/API/Console/log console.log()]&lt;br /&gt;
* &#039;&#039;prompt()&#039;&#039; erzeugt jetzt ein Warning und macht sonst nichts&lt;br /&gt;
* &#039;&#039;confirm()&#039;&#039; erzeugt jetzt ein Warning und macht sonst nichts&lt;br /&gt;
* [https://developer.mozilla.org/en-US/docs/Web/API/Window/history window.history] ist komplett deaktiviert&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Änderungen an bestehenden APIs ==&lt;br /&gt;
&lt;br /&gt;
Mit dem neuen AppLoader haben wir kleine Anpassungen an bestehenden APIs vorgenommen die vor allem der Natur sind, dass sie technische Probleme oder Lücken fixen oder verhindern.&lt;br /&gt;
&lt;br /&gt;
* [https://developer.knuddels.de/docs/classes/Client.html#method_addEventListener Client.addEventListener(type, callback)]: `type` muss nun vom Typ `string` sein&lt;br /&gt;
* [https://developer.knuddels.de/docs/classes/Client.html#method_removeEventListener Client.removeEventListener(type)]: Funktioniert jetzt wieder und entfernt alle Listener des entsprechenden Typs (durch einen Fehler wurde der Listener nie entfernt)&lt;br /&gt;
* (NEU) [https://developer.knuddels.de/docs/classes/Client.html#method_removeEventListener Client.removeEventListener(type, callback)]: entfernt einen bestimmten Listener für ein bestimmtes Event&lt;br /&gt;
* Nutzeraktivitätsmessung: Der Mechanismus der die Aktivät des Nutzers in der HTML-UI misst wurde überarbeitet und funktioniert jetzt wie gewollt (das heißt der &amp;quot;/dice&amp;quot;-Hack ist nicht mehr nötig)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Deprecation Notice (veraltete APIs) ==&lt;br /&gt;
&lt;br /&gt;
Im alten AppLoader gab es aus historischen Gründen noch einige APIs die seit Jahren nicht mehr zur offiziellen Dokumentation und damit API gehört haben. Diese haben wir nun entweder entfernt (da sie sowieso nur für interne Verwendung gedacht waren). Andere APIs, die aktuell noch immer von vielen Apps genutzt werden, haben wir mit Warnungen versehen und dazu Migrations-Hinweise veröffentlicht. Auf diese gehen wir nun etwas näher ein.&lt;br /&gt;
&lt;br /&gt;
Wir werden diese APIs zu einem noch nicht definierten Zeitpunkt in der Zukunft entfernen. Wir kündigen das dann rechtzeitig an.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Für euch heißt das&#039;&#039;&#039;: Bitte passt eure Apps an und tauscht die veralteten APIs mit der entsprechenden aktuellen API aus! (siehe Warnings)&lt;br /&gt;
&lt;br /&gt;
=== document.addEventListener(&amp;quot;eventReceived&amp;quot;, function() {...}) ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: &#039;&#039;You are using a deprecated API (document event listener for &amp;quot;eventReceived&amp;quot;). Please use &amp;quot;Client.addEventListener()&amp;quot; instead. See: https://developer.knuddels.de/docs/classes/Client.html#method_addEventListener&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es gab in den Anfangszeiten [https://forum.knuddels.de/ubbthreads.php?ubb=showflat&amp;amp;Number=2909131#Post2909131 wie hier erwähnt] kurzzeitig diese Variante um Events vom Server zu empfangen. In dieser Zeit ist auch die Ziegenphobie-Demo-App entstanden. Wir haben nach wenigen Monaten die alte API als &amp;quot;Deprecated&amp;quot; markiert, und sie war auch niemals offiziell dokumentiert. Da wir aber versäumt haben die HTML-UI-Demo-App (Ziegenphobie) an die neuen APIs anzupassen hat sich die Verwendung dieser API stark verbreitet. Die Demo-Apps mit HTML-UI sind jetzt auf die aktuellsten APIs aktualisiert worden.&lt;br /&gt;
&lt;br /&gt;
=== Client.onSendEventReceived() ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: &#039;&#039;You are using &amp;quot;Client.onSendEventReceived()&amp;quot; which is an internal API. Please use &amp;quot;Client.dispatchEvent()&amp;quot; instead. See: https://developer.knuddels.de/docs/classes/Client.html#method_dispatchEvent&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Diese API war nie öffentlich oder offiziell. Allerdings hat sie mindestens den Weg in ein beliebtes Framework geschafft und sich dadurch weit verbreitet. Aus diesem Grund können wir sie nicht ohne Weiteres entfernen. Es ist generell immer der empfohlene und richtige Weg ausschließlich APIs zu verwenden die in der offiziellen Dokumentation auch entsprechend dokumentiert sind.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weiterführende Informationen ==&lt;br /&gt;
&lt;br /&gt;
Wir haben für die Entwicklung von Webseiten und vor allem Apps mit Web-Technologien einen [https://docs.google.com/document/d/1W9hguLt7ScQkKpOJ_sDlKXjJVyqpi7oO1iBmG066g0c/edit Web-Client Coding Guide] geschrieben. Dort findet ihr sehr viele weitere Infos und Guidelines für erfolgreiches Entwickeln im Web Frontend.&lt;br /&gt;
Hinweis: Dieser Guide ist für Fortgeschrittene!&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=User_App:Backend/Environment&amp;diff=129932</id>
		<title>User App:Backend/Environment</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=User_App:Backend/Environment&amp;diff=129932"/>
		<updated>2019-11-05T17:30:41Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[Dies ist vorerst eine sporadische Version dieses Artikels. Ausführlicher Artikel folgt.]&lt;br /&gt;
&lt;br /&gt;
== UserApps Server ==&lt;br /&gt;
&lt;br /&gt;
Der Server-Teil einer UserApp läuft auf einem Server von Knuddels. Der Server-Teil besteht ausschließlich aus einer Config (&amp;quot;app.config&amp;quot;) und einer &amp;quot;main.js&amp;quot; als Einstiegspunkt. Die Umgebung in der die UserApp ausgeführt wird ist eine [https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino Rhino-Instanz].&lt;br /&gt;
&lt;br /&gt;
Was diese Rhino-Instanz an JavaScript-Features hat kann man in dieser [https://kangax.github.io/compat-table/es6/ Compatibility Table] nachschlagen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Schwierigkeiten ==&lt;br /&gt;
&lt;br /&gt;
Da die aktuell verwendete JavaScript Runtime (Rhino) nicht sonderlich auf der Höhe der Zeit ist muss man einige sonst üblichen Features patchen (Polyfill) oder Transpiler einsetzen. Hier eine kleine Übersicht:&lt;br /&gt;
&lt;br /&gt;
* [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const const] wird nicht unterstützt ([https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let let] hingegen schon)&lt;br /&gt;
* [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promise] muss man polyfillen (aus Kompatibilitätsgründen empfehlen wir NPM Package &amp;quot;es6-promise&amp;quot; version &amp;quot;4.1.0&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128278</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128278"/>
		<updated>2019-08-09T10:26:39Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Link auf Knuddels Blog geändert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Für Anfänger ==&lt;br /&gt;
Lerne Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Einstieg]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/HTML-UI|HTML-UI (grafische Oberfläche)]]&lt;br /&gt;
&lt;br /&gt;
== Für Fortgeschrittene ==&lt;br /&gt;
&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/UserApps_teilen|UserApps installieren und freigeben]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Newsletter-Versand|Newsletter-Versand]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/AppBot-Profilbild|AppBot-Profilbild]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/KnuddelAccount|KnuddelAccount]]&lt;br /&gt;
&lt;br /&gt;
  Du kannst dich auf Discord an fortgeschrittene UserApp-Entwickler wenden. Den Link zum Discord-Channel findest du unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [https://blog.knuddels.de/user-app-tutorials/ blog.knuddels.de] - hier gibt es viele Tutorials!&lt;br /&gt;
* [[User_Apps/Tutorial|Hallo Welt]]&lt;br /&gt;
&lt;br /&gt;
== Meta ==&lt;br /&gt;
&lt;br /&gt;
Tutorial über das Schreiben von UserApp-Tutorials: [[UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta|UserApp-Tutorials-Meta]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128277</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128277"/>
		<updated>2019-08-09T10:25:55Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Link auf Knuddels Blog geändert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Für Anfänger ==&lt;br /&gt;
Lerne Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Einstieg]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/HTML-UI|HTML-UI (grafische Oberfläche)]]&lt;br /&gt;
&lt;br /&gt;
== Für Fortgeschrittene ==&lt;br /&gt;
&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/UserApps_teilen|UserApps installieren und freigeben]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Newsletter-Versand|Newsletter-Versand]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/AppBot-Profilbild|AppBot-Profilbild]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/KnuddelAccount|KnuddelAccount]]&lt;br /&gt;
&lt;br /&gt;
  Du kannst dich auf Discord an fortgeschrittene UserApp-Entwickler wenden. Den Link zum Discord-Channel findest du unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [https://blog.knuddels.de/user-app-tutorials/] - hier gibt es viele Tutorials!&lt;br /&gt;
* [[User_Apps/Tutorial|Hallo Welt]]&lt;br /&gt;
&lt;br /&gt;
== Meta ==&lt;br /&gt;
&lt;br /&gt;
Tutorial über das Schreiben von UserApp-Tutorials: [[UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta|UserApp-Tutorials-Meta]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128276</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128276"/>
		<updated>2019-08-09T10:24:52Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Struktur geändert und Link auf Knuddels Blog hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Für Anfänger ==&lt;br /&gt;
Lerne Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Einstieg]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/HTML-UI|HTML-UI (grafische Oberfläche)]]&lt;br /&gt;
&lt;br /&gt;
== Für Fortgeschrittene ==&lt;br /&gt;
&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/UserApps_teilen|UserApps installieren und freigeben]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Newsletter-Versand|Newsletter-Versand]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/AppBot-Profilbild|AppBot-Profilbild]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/KnuddelAccount|KnuddelAccount]]&lt;br /&gt;
&lt;br /&gt;
  Du kannst dich auf Discord an fortgeschrittene UserApp-Entwickler wenden. Den Link zum Discord-Channel findest du unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [https://blog.knuddels.de/user-app-tutorials/#Tutorial blog.knuddels.de] - hier gibt es viele Tutorials!&lt;br /&gt;
* [[User_Apps/Tutorial|Hallo Welt]]&lt;br /&gt;
&lt;br /&gt;
== Meta ==&lt;br /&gt;
&lt;br /&gt;
Tutorial über das Schreiben von UserApp-Tutorials: [[UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta|UserApp-Tutorials-Meta]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128273</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128273"/>
		<updated>2019-08-08T14:18:41Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Fehler in Link korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Für Anfänger ==&lt;br /&gt;
Lerne Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Einstieg]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/HTML-UI|HTML-UI (grafische Oberfläche)]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/UserApps_teilen|UserApps installieren und freigeben]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Newsletter-Versand|Newsletter-Versand]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/AppBot-Profilbild|AppBot-Profilbild]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/KnuddelAccount|KnuddelAccount]]&lt;br /&gt;
&lt;br /&gt;
== Für Fortgeschrittene ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Es gibt leider noch keine Tutorials für Fortgeschrittene.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Du kannst dich auf Discord an fortgeschrittene UserApp-Entwickler wenden. Den Link zum Discord-Channel findest du unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[User_Apps/Tutorial|Hallo Welt]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Meta ==&lt;br /&gt;
&lt;br /&gt;
Tutorial über das Schreiben von UserApp-Tutorials: [[UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta|UserApp-Tutorials-Meta]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/KnuddelAccount&amp;diff=128272</id>
		<title>UserApp-Entwicklung/Tutorials/KnuddelAccount</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/KnuddelAccount&amp;diff=128272"/>
		<updated>2019-08-08T14:17:58Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Die Seite wurde neu angelegt: „Das hier ist ein Tutorial für UserApp-Entwickler. Allgemeine Artikel zum Knuddelaccount sind der Artikel Knuddelaccount und der Artikel [[/knuddelaccount]…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das hier ist ein Tutorial für UserApp-Entwickler. Allgemeine Artikel zum Knuddelaccount sind der Artikel [[Knuddelaccount]] und der Artikel [[/knuddelaccount]].&lt;br /&gt;
&lt;br /&gt;
== Wieso KnuddelAccount verwenden? ==&lt;br /&gt;
&lt;br /&gt;
Der Knuddelaccount ermöglicht es UserApp-Entwicklern und MyChannel-Betreibern u.a., [[Knuddelgebühr]]en zu sparen, da Nutzer der UserApp einen gewissen Betrag Knuddel zur freien Verfügung stellen können, ohne ihn direkt an den AppBot zu überweisen. Außerdem können Nutzer so einen besseren Überblick über ihre Knuddel behalten und die Betreiber sind besser vor Schaden geschützt (bspw. vor Nutzern, die durch häufige Ein- und Auszahlungen schaden wollen).&lt;br /&gt;
&lt;br /&gt;
== Hook &amp;quot;onAccountReceivedKnuddel&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
Die UserApps-API funktioniert derzeit so, dass sie ihr Verhalten bzgl. Knuddelaccounts ändert, wenn der Entwickler die [[UserApp-Entwicklung/Doku/Hook|Hook]] [https://developer.knuddels.de/docs/classes/App.html#method_onAccountReceivedKnuddel onAccountReceivedKnuddel] implementiert hat.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Nutzer mit &amp;lt;function&amp;gt;/appknuddel&amp;lt;/function&amp;gt; Knuddel an einen AppBot überweist, geht der Betrag normalerweise direkt an den AppBot. Ist aber die Hook vorhanden, wird der Betrag zunächst auf den KnuddelAccount des Users überwiesen. Der Bot kann dann jederzeit mit [https://developer.knuddels.de/docs/classes/KnuddelAccount.html#method_use KnuddelAccount.use()] Knuddel von dem KnuddelAccount tatsächlich auf den Bot transferieren. Zugriff auf den KnuddelAccount eines Users erhält man über [https://developer.knuddels.de/docs/classes/User.html#method_getKnuddelAccount User.getKnuddelAccount()]&lt;br /&gt;
&lt;br /&gt;
=== Standard (ohne &amp;quot;onAccountReceivedKnuddel&amp;quot;-Hook): ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:knuddeaccount_no_hook.png|560px|Knuddel-Fluss mit onAccountReceivedKnuddel-Hook]]&lt;br /&gt;
&lt;br /&gt;
=== Mit &amp;quot;onAccountReceivedKnuddel&amp;quot;-Hook: ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:knuddeaccount_hook.png|560px|Knuddel-Fluss mit onAccountReceivedKnuddel-Hook]]&lt;br /&gt;
&lt;br /&gt;
== Wichtige Funktionen in der API ==&lt;br /&gt;
&lt;br /&gt;
* [https://developer.knuddels.de/docs/classes/KnuddelAccount.html#method_use KnuddelAccount.use()]: KnuddelAccount → Bot&lt;br /&gt;
* [https://developer.knuddels.de/docs/classes/BotUser.html#method_transferKnuddel BotUser.transferKnuddel()]: Bot → User / KnuddelAccount&lt;br /&gt;
* [https://developer.knuddels.de/docs/classes/User.html#method_getKnuddelAccount User.getKnuddelAccount()]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Datei:knuddeaccount_no_hook.png&amp;diff=128271</id>
		<title>Datei:knuddeaccount no hook.png</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Datei:knuddeaccount_no_hook.png&amp;diff=128271"/>
		<updated>2019-08-08T13:45:41Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Hinweis auf Tutorial hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
&lt;br /&gt;
Gehört zum Tutorial [[UserApp-Entwicklung/Tutorials/KnuddelAccount]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Datei:knuddeaccount_no_hook.png&amp;diff=128270</id>
		<title>Datei:knuddeaccount no hook.png</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Datei:knuddeaccount_no_hook.png&amp;diff=128270"/>
		<updated>2019-08-08T13:44:57Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Kategorie:UserApp-Entwicklung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Datei:knuddeaccount_hook.png&amp;diff=128269</id>
		<title>Datei:knuddeaccount hook.png</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Datei:knuddeaccount_hook.png&amp;diff=128269"/>
		<updated>2019-08-08T13:21:56Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Kategorie Verlinkung repariert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
&lt;br /&gt;
Gehört zum Tutorial [[UserApp-Entwicklung/Tutorials/KnuddelAccount]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Datei:knuddeaccount_hook.png&amp;diff=128268</id>
		<title>Datei:knuddeaccount hook.png</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Datei:knuddeaccount_hook.png&amp;diff=128268"/>
		<updated>2019-08-08T13:20:34Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: [[Kategorie:UserApp-Entwicklung]&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung ==&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Doku/Hook&amp;diff=128252</id>
		<title>UserApp-Entwicklung/Doku/Hook</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Doku/Hook&amp;diff=128252"/>
		<updated>2019-08-08T09:10:14Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Die Seite wurde neu angelegt: „ == Was sind Hooks? ==  Aus Wikipedia&amp;lt;ref&amp;gt;https://de.wikipedia.org/wiki/Hook_(Informatik)&amp;lt;/ref&amp;gt;:  ::&amp;#039;&amp;#039;&amp;#039;Hook&amp;#039;&amp;#039;&amp;#039; (englisch für Haken, auch Einschubmethode genan…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Was sind Hooks? ==&lt;br /&gt;
&lt;br /&gt;
Aus Wikipedia&amp;lt;ref&amp;gt;https://de.wikipedia.org/wiki/Hook_(Informatik)&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;Hook&#039;&#039;&#039; (englisch für Haken, auch Einschubmethode genannt) bezeichnet in der Programmierung eine Schnittstelle, mit der fremder Programmcode in eine bestehende Anwendung integriert werden kann, um diese zu erweitern, deren Ablauf zu verändern oder um bestimmte Ereignisse abzufangen.&lt;br /&gt;
&lt;br /&gt;
Solche Hooks gibt es auch in der [[API|UserApps-API]], nämlich für das [https://developer.knuddels.de/docs/classes/App.html App-Objekt]. Bei der Ausführung des Codes wird getestet, ob die entsprechende Funktion (z.B. onUserJoined, mayShowPublicMessage etc.) vorliegt; Die Funktion wird dann bei den entsprechenden Aktionen aufgerufen - egal welchen Code der Entwickler in diese Funktion geschrieben hat.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Kategorie:UserApp-Entwicklung&amp;diff=128246</id>
		<title>Kategorie:UserApp-Entwicklung</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Kategorie:UserApp-Entwicklung&amp;diff=128246"/>
		<updated>2019-08-08T08:45:59Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Link auf Startseite &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[UserApp-Entwicklung|Startseite &amp;quot;UserApp-Entwicklung&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;Kategorie &amp;quot;UserApp-Entwicklung&#039;&#039;&#039; enthält alle Artikel zu [[User_App|UserApps]], die für &#039;&#039;&#039;UserApp-Entwickler&#039;&#039;&#039; gedacht sind -  also [[UserApp-Entwicklung/Tutorials|Tutorials]], technische Dokumentation usw.&amp;lt;br&amp;gt;&lt;br /&gt;
Im Gegensatz dazu enthält die andere [https://knuddels-wiki.de/index.php?title=Kategorie:User_App Kategorie &amp;quot;User App&amp;quot;] Artikel, die für gewöhnliche Nutzer gedacht sind.&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Doku/AppId&amp;diff=128245</id>
		<title>UserApp-Entwicklung/Doku/AppId</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Doku/AppId&amp;diff=128245"/>
		<updated>2019-08-08T08:44:40Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= AppId =&lt;br /&gt;
=== Was ist die AppId? ===&lt;br /&gt;
Die &#039;&#039;&#039;AppId&#039;&#039;&#039; ist eine eindeutige Zuordnung einer App zu seinem Entwickler. Sie wird benötigt um gleichnamige Apps voneinander zu unterscheiden.&lt;br /&gt;
=== Woraus setzt sich die AppId zusammen? ===&lt;br /&gt;
Die &#039;&#039;&#039;AppId&#039;&#039;&#039; setzt sich aus folgenden Teilen zusammen:&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;FUNCTION&amp;gt;knuddelsDEV&amp;lt;/FUNCTION&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;.&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;FUNCTION&amp;gt;&amp;lt;FTP-Benutzername&amp;gt;&amp;lt;/FUNCTION&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;.&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;FUNCTION&amp;gt;&amp;lt;Ordner-Name&amp;gt;&amp;lt;/FUNCTION&amp;gt;&lt;br /&gt;
=== Wie kann ich die AppId auslesen? ===&lt;br /&gt;
Um die &#039;&#039;&#039;AppId&#039;&#039;&#039; auszulesen kannst du folgenden Coden nutzen:&lt;br /&gt;
&amp;lt;PRE&amp;gt;KnuddelsServer.getAppAccess().getOwnInstance().getRootInstance().getAppInfo().getAppId();&amp;lt;/PRE&amp;gt;&lt;br /&gt;
* [https://developer.knuddels.de/docs/classes/AppInfo.html#method_getAppId AppInstance.getAppId()]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=/knuddelaccount&amp;diff=128244</id>
		<title>/knuddelaccount</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=/knuddelaccount&amp;diff=128244"/>
		<updated>2019-08-08T08:41:08Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;User App&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datei:Vorschau - Knuddelaccount (Kontenübersicht).jpg|thumb|250px|Vorschau der Funktion]]&lt;br /&gt;
&lt;br /&gt;
==Allgemeines==&lt;br /&gt;
Mit der [[Funktion]] &amp;lt;function&amp;gt;/knuddelaccount&amp;lt;/function&amp;gt; ruft man im Java-[[Chat]] eine Übersicht seiner Knuddelkonten auf. Diese Konten beziehen sich auf die Userapps in [[MyChannel]]n.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Voraussetzungen==&lt;br /&gt;
Jedes Mitglied, welches im Chat Java-Chat online ist, kann die Funktion &amp;lt;function&amp;gt;/knuddelaccount&amp;lt;/function&amp;gt; nutzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
===/knuddelaccount===&lt;br /&gt;
Öffnet im Chat ein Fenster, welches eine Übersicht der vorhanden Knuddelkonten zeigt.&lt;br /&gt;
Über die gewählten Aktionen kann man sich vom Konto die Kontoauszüge zeigen lassen, oder die vorhandenen Knuddel Auszahlen lassen. Dies geht jeweils über die Links im Aktions Menü.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weiterführende Informationen==&lt;br /&gt;
* [[Liste der Chatfunktionen]] - Hier befindet sich eine Übersicht aller vorhandenen Chatfunktionen&lt;br /&gt;
* [[Knuddelaccount]] - Informationen zum Knuddelaccount&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Chatfunktion|knuddelaccount]] [[Kategorie:User_App]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Knuddelaccount&amp;diff=128243</id>
		<title>Knuddelaccount</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Knuddelaccount&amp;diff=128243"/>
		<updated>2019-08-08T08:40:01Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;User App&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Allgemeines==&lt;br /&gt;
Der &#039;&#039;&#039;Knuddelaccount&#039;&#039;&#039; oder auch einfacher gesagt die Übersicht der Knuddelkonten für die [[User Apps]] wurde am 24.07.[[2015]] ins Knuddelsystem eingepflegt. Die Übersicht zeigt in erster Linie eine bessere Kontoübersicht der Konten aus den MyChannel-Apps. Die [[Funktion]] dient aber nicht nur den Usern, sondern auch dem Knuddelssystem. Die Knuddel, die ein User von der App erhält, werden demnach auch ab sofort versteuert. Dies bedeutet, dass die App, aber auch jeder User, bei einer Knuddelüberweisung die [[Knuddelgebühr]] an das System zu entrichten hat. Die Gebühr wird automatisch an das System übermittelt.&lt;br /&gt;
&lt;br /&gt;
Eine Übersicht der Konten erhält man jeder Zeit im Chat, sobald man dort den [[Befehl]] [[/knuddelaccount]] eingibt.&lt;br /&gt;
&lt;br /&gt;
==Vorschau==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Vorschau - Knuddelaccount (Kontenübersicht).jpg‎|Kontenübersicht&lt;br /&gt;
Vorschau - Knuddelaccount (Kontoauszug).jpg|Kontoauszug&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weiterführende Informationen==&lt;br /&gt;
*[[Liste der Chatfunktionen]] - Übersicht aller Chatfunktionen&lt;br /&gt;
*[[User Apps]] - Alle Infos zu den von Nutzer für Knuddels entwickelten Apps in MyChanneln&lt;br /&gt;
*[[/knuddelaccount]] - Detaillierte Erklärung der Funktion&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:User_App]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Limits&amp;diff=128242</id>
		<title>Limits</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Limits&amp;diff=128242"/>
		<updated>2019-08-08T08:38:46Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: auch zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines ==&lt;br /&gt;
Innerhalb des Chats gibt es einige (technische) Begrenzungen. Diese dienen unter Anderem der Vermeidung von [[Spam]] oder Missbrauch der Dienste. Eine der bekanntesten Limits betrifft wohl die Anzahl der Smileys pro Chatnachricht.&lt;br /&gt;
&lt;br /&gt;
== Limitierungen ==&lt;br /&gt;
&lt;br /&gt;
=== Chat allgemein ===&lt;br /&gt;
==== Nachrichten ====&lt;br /&gt;
[[/m|Postfach]]-Nachricht: 2.000 Zeichen&lt;br /&gt;
&lt;br /&gt;
Öffentliche Nachricht: 1.000 Zeichen&lt;br /&gt;
&lt;br /&gt;
Private Nachricht: 2.000 Zeichen&lt;br /&gt;
&lt;br /&gt;
Zeilenumbrüche pro Nachricht: 4&lt;br /&gt;
&lt;br /&gt;
=== User App Entwicklung ===&lt;br /&gt;
Für die Entwicklung und den Betrieb einer [[User App]] gelten einige besondere Beschränkungen. Dies ist notwendig, da pro Server-Instanz mehrere User Apps laufen. Durch die Beschränkungen kann sichergestellt werden, dass keine User App übermäßig hohe Ressourcen beansprucht.&lt;br /&gt;
&lt;br /&gt;
Um eine Abschaltung oder Einschränkung der User App zu verhindern, sollte auf eine Einhaltung der Limits geachtet werden.&lt;br /&gt;
&lt;br /&gt;
In Einzelfällen können, für besonders große/aktive [[Channel]], bestimmte Beschränkungen durch das [[Knuddelsteam]] manuell angepasst werden. Hierzu bedarf es einer Kontaktaufnahme durch den Channelbesitzer.&lt;br /&gt;
&lt;br /&gt;
==== Externe Kommunikation ====&lt;br /&gt;
Alle hier genannten Daten gelten inklusive der Header-Daten.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Request size Limit: 10kB&lt;br /&gt;
&lt;br /&gt;
Response size Limit: 50kB&lt;br /&gt;
&lt;br /&gt;
Maximale Anzahl gleichzeitige Requests: 50&lt;br /&gt;
&lt;br /&gt;
Daten-Limit: 50MB pro 10min&lt;br /&gt;
&lt;br /&gt;
Request-Limit: 100 Requests pro 10min&lt;br /&gt;
&lt;br /&gt;
==== Knuddel-Transfer-Reason ====&lt;br /&gt;
Maximale Länge für displayReasonText: 2000 Zeichen&lt;br /&gt;
&lt;br /&gt;
==== Persistence ====&lt;br /&gt;
Maximale Länge: 102.400 Zeichen&lt;br /&gt;
&lt;br /&gt;
==== Server zu UI | UI zu Server ====&lt;br /&gt;
Maximale Länge: 10.000 Zeichen&lt;br /&gt;
&lt;br /&gt;
==== Nachrichten ====&lt;br /&gt;
&lt;br /&gt;
Öffentliche Nachrichten: 30 in 15s&amp;lt;br&amp;gt;&lt;br /&gt;
Private Nachrichten: 45 in 15s&amp;lt;br&amp;gt;&lt;br /&gt;
AppInstance.sendAppEvent(): 50 in 5s&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:User App]] [[Kategorie:UserApp-Entwicklung]] [[Kategorie:Begriffserklärung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128241</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128241"/>
		<updated>2019-08-08T08:32:23Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Für Anfänger ==&lt;br /&gt;
Lerne Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Einstieg]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/HTML-UI|HTML-UI (grafische Oberfläche)]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/UserApps_teilen|UserApps installieren und freigeben]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Newsletter-Versand|Newsletter-Versand]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/AppBot-Profilbild|AppBot-Profilbild]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Knuddelaccount|Knuddelaccount]]&lt;br /&gt;
&lt;br /&gt;
== Für Fortgeschrittene ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Es gibt leider noch keine Tutorials für Fortgeschrittene.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Du kannst dich auf Discord an fortgeschrittene UserApp-Entwickler wenden. Den Link zum Discord-Channel findest du unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[User_Apps/Tutorial|Hallo Welt]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Meta ==&lt;br /&gt;
&lt;br /&gt;
Tutorial über das Schreiben von UserApp-Tutorials: [[UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta|UserApp-Tutorials-Meta]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/AppBot-Profilbild&amp;diff=128162</id>
		<title>UserApp-Entwicklung/Tutorials/AppBot-Profilbild</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/AppBot-Profilbild&amp;diff=128162"/>
		<updated>2019-07-23T09:28:12Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: kleine Verbesserungen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einführung ==&lt;br /&gt;
&lt;br /&gt;
Wenn du mit deinem [[UserApp-Entwicklung/Doku/AppBot|AppBot]] [https://developer.knuddels.de/docs/classes/User.html#method_sendPrivateMessage Privatnachrichten] an deine Besucher schickst, möchtest du wahrscheinlich, dass dein AppBot ein eigenes Profilbild hat. Das ist auch möglich!&lt;br /&gt;
&lt;br /&gt;
== Bild erstellen ==&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Profilbildern normaler Nutzer muss auf dem Profilbild eines AppBots keine reale Person abgebildet sein (auf sonstigen Profilbildern muss der Besitzer abgebildet sein). Ansonsten gelten hier aber [[Allgemeine_Geschäftsbedingungen/Fotos|die selben Regeln wie für Profilbilder normaler Nutzer]].&lt;br /&gt;
&lt;br /&gt;
== Passwort für den AppBot ==&lt;br /&gt;
&lt;br /&gt;
Du weißt das Passwort deines AppBots zunächst nicht. Allerdings kannst du es neu setzen, da der AppBot mit der selben E-Mail-Adresse registriert ist wie dein Hauptnick. Geh also auf [https://www.knuddels.de www.knuddels.de], klicke auf &#039;&#039;Passwort vergessen&#039;&#039;, gib den Nick deines AppBots ein und bestätige. Jetzt solltest du eine E-Mail erhalten und kannst ein neues Passwort wählen.&lt;br /&gt;
&lt;br /&gt;
== Profilbild hochladen ==&lt;br /&gt;
&lt;br /&gt;
Logge dich jetzt in der Fotogalerie unter [https://photo.knuddels.de/photos-login.html photo.knuddels.de] mit dem Nick und dem Passwort deines AppBots ein und lade dort das Bild hoch.&lt;br /&gt;
&lt;br /&gt;
Fertig!&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta&amp;diff=128161</id>
		<title>UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta&amp;diff=128161"/>
		<updated>2019-07-23T08:29:09Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tipps und Konventionen für das Schreiben von Tutorials zu UserApps.&lt;br /&gt;
&lt;br /&gt;
== Erstellen des Wiki-Artikels ==&lt;br /&gt;
&lt;br /&gt;
* [[Knuddels-Wiki:Tutorial01|Registriere dich zunächst im Wiki und logge dich ein.]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Knuddels-Wiki:Tutorial03|Hier wird erklärt, wie du neue Artikel erstellst.]]&lt;br /&gt;
&lt;br /&gt;
  Wichtig: Der &#039;&#039;&#039;Titel&#039;&#039;&#039; deines Tutorials sollte mit &#039;&#039;&#039;UserApp-Entwicklung/Tutorials/&#039;&#039;&#039; beginnen!&lt;br /&gt;
  Artikel, die kein Tutorial sind, sondern lediglich etwas dokumentieren, sollten mit &#039;&#039;&#039;UserApp-Entwicklung/Doku/&#039;&#039;&#039; beginnen.&lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
* Tutorial: [[UserApp-Entwicklung/Tutorials/HTML-UI]]&lt;br /&gt;
* Doku: [[UserApp-Entwicklung/Doku/AppId]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code-Beispiele einfügen ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;amp;#x3C;pre&amp;amp;#x3E;-Tag ===&lt;br /&gt;
&lt;br /&gt;
Code ist auf dem Knuddels-Wiki am besten in einem &#039;&#039;&#039;&amp;amp;#x3C;pre&amp;amp;#x3E;&#039;&#039;&#039;-Tag aufgehoben.&amp;lt;br&amp;gt;&lt;br /&gt;
Allerdings gibt es auch hier noch Probleme mit der Formatierung, zum Beispiel werden Whitespaces am Anfang der Zeile entfernt.&lt;br /&gt;
&lt;br /&gt;
=== Whitespaces ===&lt;br /&gt;
&lt;br /&gt;
Die Whitespaces am Anfang der Zeile (oder einfach alle) können durch &#039;&#039;&#039;&amp;amp;#x26;nbsp;&#039;&#039;&#039; (geschütztes Leerzeichen) ersetzt werden, damit sie trotzdem angezeigt werden.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python sähe das so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; s = &amp;quot;&amp;quot;&amp;quot;... hier der Quellcode ...&lt;br /&gt;
... noch mehr Quellcode ...&lt;br /&gt;
...&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print(s.replace(&amp;quot; &amp;quot;, &amp;quot;&amp;amp;#x26;nbsp;&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTML-Quellcode ===&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung von XML-Tags sollte der Quellcode außerdem zuerst einmal durch dieses Tool &amp;quot;escaped&amp;quot; werden: https://mothereff.in/html-entities&lt;br /&gt;
&lt;br /&gt;
=== Syntax-Highlighting ===&lt;br /&gt;
&lt;br /&gt;
Das Knuddels-Wiki hat derzeit leider kein Syntax-Highlighting.&lt;br /&gt;
&lt;br /&gt;
=== Quellcode sichern ===&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist durch diese Änderungen im Bearbeitungsfeld im Wiki nicht mehr gut lesbar. Um für spätere Änderungen noch die originale Version des Code-Beispiels zu erhalten, kann es in einem XML-Kommentar gesichert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;#x3C;!--&lt;br /&gt;
hier die Originalversion&lt;br /&gt;
--&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;#x3C;pre&amp;amp;#x3E;&lt;br /&gt;
hier die &amp;quot;escapte&amp;quot; Version&lt;br /&gt;
&amp;amp;#x3C;/pre&amp;amp;#x3E;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zusammenfassung ===&lt;br /&gt;
&lt;br /&gt;
# Code in einem Kommentar &#039;&#039;&#039;&amp;amp;#x3C;!--  --&amp;amp;#x3E;&#039;&#039;&#039; sichern&lt;br /&gt;
# Falls XML-Tags im Code vorkommen, durch dieses Tool jagen: https://mothereff.in/html-entities&lt;br /&gt;
# alle Leerzeichen (eigentlich nur am Anfang jeder Zeile) durch &#039;&#039;&#039;&amp;amp;#x26;nbsp;&#039;&#039;&#039; ersetzen&lt;br /&gt;
# das Ergebnis in einem &#039;&#039;&#039;&amp;amp;#x3C;pre&amp;amp;#x3E;&amp;amp;#x3C;/pre&amp;amp;#x3E;&#039;&#039;&#039;-Tag einfügen&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/AppBot-Profilbild&amp;diff=128160</id>
		<title>UserApp-Entwicklung/Tutorials/AppBot-Profilbild</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/AppBot-Profilbild&amp;diff=128160"/>
		<updated>2019-07-23T08:28:39Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einführung ==&lt;br /&gt;
&lt;br /&gt;
Das Profilbild deines [[UserApp-Entwicklung/Doku/AppBot|AppBots]] sieht standardmäßig ziemlich unoriginell aus. Aber wenn du beispielsweise deinen AppBot Besuchern [https://developer.knuddels.de/docs/classes/User.html#method_sendPrivateMessage Privatnachrichten] schicken lässt, möchtest du wahrscheinlich, dass dein AppBot ein eigenes Profilbild hat. Das ist auch möglich!&lt;br /&gt;
&lt;br /&gt;
== Bild erstellen ==&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Profilbildern normaler Nutzer muss auf dem Profilbild eines AppBots keine Person abgebildet sein. Ansonsten gelten hier aber [https://www.knuddels.de/info/foto-rules.html die selben Regeln wie für Profilbilder normaler Nutzer].&lt;br /&gt;
&lt;br /&gt;
== Passwort für den AppBot ==&lt;br /&gt;
&lt;br /&gt;
Du weißt das Passwort deines AppBots zunächst nicht. Allerdings kannst du es neu setzen, da der AppBot mit der selben E-Mail-Adresse registriert ist wie dein Hauptnick. Geh also auf [https://www.knuddels.de www.knuddels.de], klicke auf &#039;&#039;Passwort vergessen&#039;&#039;, gib den Nick deines AppBots ein und bestätige. Jetzt solltest du eine E-Mail erhalten und kannst ein neues Passwort wählen.&lt;br /&gt;
&lt;br /&gt;
== Profilbild hochladen ==&lt;br /&gt;
&lt;br /&gt;
Das Bild muss im &#039;&#039;&#039;.jpg&#039;&#039;&#039;- oder &#039;&#039;&#039;.gif&#039;&#039;&#039;-Format vorliegen, damit du es hochladen kannst.&lt;br /&gt;
&lt;br /&gt;
Logge dich jetzt in der Fotogalerie unter [https://photo.knuddels.de/photos-login.html photo.knuddels.de] mit dem Nick und dem Passwort deines AppBots ein und lade dort das Bild hoch.&lt;br /&gt;
&lt;br /&gt;
Fertig!&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/UserApps_teilen&amp;diff=128159</id>
		<title>UserApp-Entwicklung/Tutorials/UserApps teilen</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/UserApps_teilen&amp;diff=128159"/>
		<updated>2019-07-23T08:28:25Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= UserApps installieren und freigeben =&lt;br /&gt;
=== Eine UserApp installieren ===&lt;br /&gt;
&lt;br /&gt;
Um eine UserApp bei sich im Channel zu installieren, benötigt man die dazugehörige [[UserApp-Entwicklung/Doku/AppId|AppId]], diese erhält man in der Regel vom [[UserApp-Entwicklung/Doku/AppDeveloper|AppDeveloper]].&lt;br /&gt;
&lt;br /&gt;
es gibt nun 2 Möglichkeiten eine App zu installieren:&lt;br /&gt;
===== Installation per Chat-Befehl =====&lt;br /&gt;
Um eine App zu installieren benötigt man folgenden Befehl:&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;function&amp;gt;/apps install [knuddelsDEV.]&amp;lt;FTP-Benutzername&amp;gt;.&amp;lt;Ordner-Name&amp;gt;&amp;lt;/function&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;lt;SMALL&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;FUNCTION&amp;gt;knuddelsDEV&amp;lt;/FUNCTION&amp;gt; ist eine optionale Angabe und nicht erforderlich&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;FUNCTION&amp;gt;&amp;lt;FTP-Benutzername&amp;gt;&amp;lt;/FUNCTION&amp;gt; ist der Benutzername für den FTP-Server, des AppEntwicklers, dessen App ihr installieren wollt.&amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;FUNCTION&amp;gt;&amp;lt;Ordner-Name&amp;gt;&amp;lt;/FUNCTION&amp;gt; Ist der Name des Ordners der App, welche installiert werden soll. &amp;lt;BR&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Weitere informationen sind unter [[UserApp-Entwicklung/Doku/AppId|AppId]] zu finden.&lt;br /&gt;
&amp;lt;/SMALL&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Installation per HTML-UI =====&lt;br /&gt;
&lt;br /&gt;
- folgt -&lt;br /&gt;
&lt;br /&gt;
=== Eigene UserApp für andere Nutzer freigeben ===&lt;br /&gt;
Die Installationsrechte für die App werden über den Eintrag [[UserApp-Entwicklung/Doku/mayBeInstalledBy|mayBeInstalledBy]] in der Datei [[UserApp-Entwicklung/Doku/app.config|app.config]] geregelt.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möchten wir die App nun für andere Freigeben, müssen wir den Eintrag entsprechend ändern. Hier gibt es nun verschiedene Möglichkeiten der Freigabe:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Eintrag !! Auswirkung&lt;br /&gt;
|-&lt;br /&gt;
| mayBeInstalledBy.1 = *.* || Jeder Nutzer kann deine App installieren. Hierbei spielt keine Rolle ob auf dem DEV-Server oder dem Live-Server.&lt;br /&gt;
|-&lt;br /&gt;
| mayBeInstalledBy.1 = *.knuddelsDE || Jeder Nutzer kann kann deine App auf dem LIVE-Server installieren&lt;br /&gt;
|-&lt;br /&gt;
| mayBeInstalledBy.1 = *.knuddelsDEV || Jeder Nutzer kann kann deine App auf dem DEV-Server installieren&lt;br /&gt;
|-&lt;br /&gt;
| mayBeInstalledBy.1 = rmpg.* || Nur &#039;&#039;&#039;rmpg&#039;&#039;&#039; kann die App installieren. Hierbei spielt keine Rolle ob auf dem DEV-Server oder dem Live-Server.&lt;br /&gt;
|-&lt;br /&gt;
| mayBeInstalledBy.1 = rmpg.knuddelsDE&amp;lt;BR&amp;gt;mayBeInstalledBy.2 = [[James]].knuddelsDEV || &#039;&#039;&#039;rmpg&#039;&#039;&#039; kann die App auf dem LIVE-Server installieren, James hingegen nur auf dem DEV-Server.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Für die Installation der App wird noch die [[UserApp-Entwicklung/Doku/AppId|AppId]] benötigt.&lt;br /&gt;
&lt;br /&gt;
Um die App dann nun zu installieren kann man entweder den Chatbefehl dafür eingeben&amp;lt;PRE&amp;gt;/apps install APPID&amp;lt;/PRE&amp;gt;, oder über /apps in der UI auf &#039;&#039;&#039;App installieren&#039;&#039;&#039; klicken und dort die [[UserApp-Entwicklung/Doku/AppId|AppId]] eingeben.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/HTML-UI&amp;diff=128158</id>
		<title>UserApp-Entwicklung/Tutorials/HTML-UI</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/HTML-UI&amp;diff=128158"/>
		<updated>2019-07-23T08:28:02Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
In diesem Tutorial lernst du, wie du eine grafische Oberfläche in deinen UserApps verwenden kannst, um z.B. grafische Spiele für Knuddels zu programmieren. Du solltest schon einmal etwas mit HTML und JavaScript gemacht haben, um folgen zu können.&lt;br /&gt;
&lt;br /&gt;
== Der Server ==&lt;br /&gt;
&lt;br /&gt;
Der Server-Code deiner UserApp steht in der &#039;&#039;&#039;main.js&#039;&#039;&#039;. Wenn du nur in der &#039;&#039;&#039;main.js&#039;&#039;&#039; programmierst, läuft der ganze Code deiner UserApp ausschließlich auf den Servern von Knuddels.&amp;lt;br&amp;gt;&lt;br /&gt;
Damit kann man zwar schon viel machen, aber für mehr Interaktionsmöglichkeiten brauchst du eine grafische Oberfläche.&lt;br /&gt;
&lt;br /&gt;
== Der Client ==&lt;br /&gt;
&lt;br /&gt;
Der Code für den Client befindet sich im &#039;&#039;&#039;www&#039;&#039;&#039;-Unterordner deiner UserApp.&lt;br /&gt;
Den Einstieg bildet eine HTML-Datei, die du nennen kannst, wie du willst. Dort kannst du dann auch JavaScript-Dateien einbinden, um Code auf dem Gerät deines Besuchers auszuführen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur deiner UserApp könnte dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
KnuddelJumper/&lt;br /&gt;
    www/&lt;br /&gt;
        game.html&lt;br /&gt;
        game.js&lt;br /&gt;
        player.png&lt;br /&gt;
        enemy.png&lt;br /&gt;
    main.js&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
KnuddelJumper/&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;www/&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;game.html&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;game.js&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;player.png&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;enemy.png&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;main.js&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die HTML-Datei kann dann z.B. so eine Struktur haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- use https://mothereff.in/html-entities and replace &amp;quot; &amp;quot; with &amp;quot;&amp;amp;nbsp;&amp;quot;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;head&amp;gt;&lt;br /&gt;
        &amp;lt;script src=&amp;quot;game.js&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/head&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        &amp;lt;button&amp;gt;Hier klicken&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;#x3C;html&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;head&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;script&amp;amp;nbsp;src=&amp;amp;#x22;game.js&amp;amp;#x22;/&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/head&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;body&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;button&amp;amp;#x3E;Hier&amp;amp;nbsp;klicken&amp;amp;#x3C;/button&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/body&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;#x3C;/html&amp;amp;#x3E;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Während der Entwicklung wirst du allerdings oft Änderungen an deinem Script machen. Da Knuddels dein Script zwischenspeichert, wenn du es einfach mit dem &#039;&#039;&#039;&amp;lt;script&amp;gt;&#039;&#039;&#039;-Tag einbindest, werden deine Änderungen oft nicht übernommen. Um Knuddels dazu zu zwingen immer die aktuellste Version deines Scripts zu laden, musst du das Knuddels stattdessen mit [https://developer.knuddels.de/docs/classes/Client.html#method_includeJS Client.includeJS()] mitteilen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;head&amp;gt;&lt;br /&gt;
        &amp;lt;script&amp;gt;&lt;br /&gt;
            Client.includeJS(&amp;quot;game.js&amp;quot;);&lt;br /&gt;
        &amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;/head&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        &amp;lt;button&amp;gt;Hier klicken&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;#x3C;html&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;head&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;script&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Client.includeJS(&amp;amp;#x22;game.js&amp;amp;#x22;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/script&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/head&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;body&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;button&amp;amp;#x3E;Hier&amp;amp;nbsp;klicken&amp;amp;#x3C;/button&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/body&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;#x3C;/html&amp;amp;#x3E;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Server und Client ==&lt;br /&gt;
&lt;br /&gt;
=== AppContent senden ===&lt;br /&gt;
&lt;br /&gt;
Die HTML-Datei und der restliche Inhalt des &#039;&#039;&#039;www&#039;&#039;&#039;-Unterordners wird [https://developer.knuddels.de/docs/classes/AppContent.html AppContent] genannt. Das ist die grafische Oberfäche deiner UserApp.&amp;lt;br&amp;gt;&lt;br /&gt;
Der AppContent erscheint aber nicht automatisch bei dem Besucher deines Channels! Du musst den AppContent erst an den Besucher (den Client) senden.&lt;br /&gt;
In der Regel macht man das direkt wenn der Besucher den Channel betritt, also in &#039;&#039;&#039;App.onUserJoined&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
var App = (new function() {&lt;br /&gt;
&lt;br /&gt;
    let htmlFile = new HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
    let appContent = AppContent.overlayContent(htmlFile, 640, 480);&lt;br /&gt;
&lt;br /&gt;
    this.onUserJoined = function(user) {&lt;br /&gt;
        user.sendAppContent(appContent);&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;htmlFile&amp;amp;nbsp;=&amp;amp;nbsp;new&amp;amp;nbsp;HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;appContent&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.overlayContent(htmlFile,&amp;amp;nbsp;640,&amp;amp;nbsp;480);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(appContent);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der [https://developer.knuddels.de/docs/classes/AppContent.html AppContent] wird so nur einmal von der App geladen und dann einfach an jeden Besucher mit [https://developer.knuddels.de/docs/classes/User.html#method_sendAppContent User.sendAppContent()] gesendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  Hinweis: [https://developer.knuddels.de/docs/classes/HTMLFile.html new HTMLFile()] sucht die angegebene Datei im &#039;&#039;&#039;www&#039;&#039;&#039;-Unterordner.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Damit ist dieses Tutorial eigentlich fertig:&#039;&#039;&#039; Deine Besucher sehen jetzt eine grafische Oberfläche, wenn sie deinen Channel betreten und du kannst wie auf Webseiten Scripts einbinden. Ein paar wichtige Hinweise kommen aber noch!&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der AppContent kann verschiedene &#039;&#039;&#039;ViewModes&#039;&#039;&#039; annehmen, je nachdem welche Methode du verwendest:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Overlay&#039;&#039;&#039; mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_overlayContent AppContent.overlayContent()]&lt;br /&gt;
* &#039;&#039;&#039;Popup&#039;&#039;&#039; mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_popupContent AppContent.popupContent()]&lt;br /&gt;
* &#039;&#039;&#039;Headerbar&#039;&#039;&#039; mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_headerbarContent AppContent.headerbarContent()]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Tipp:&#039;&#039;&#039; Nicht alle Geräte können jeden &#039;&#039;&#039;ViewMode&#039;&#039;&#039; anzeigen. Daher ist es gute Praxis, wenn du mit [https://developer.knuddels.de/docs/classes/User.html#method_canSendAppContent User.canSendAppContent()] entscheidest, welchen AppContent du sendest.&lt;br /&gt;
&#039;&#039;&#039;Beispiel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
var App = (new function() {&lt;br /&gt;
&lt;br /&gt;
    let htmlFile = new HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
    let overlay = AppContent.overlayContent(htmlFile, 640, 480);&lt;br /&gt;
    let popup  = AppContent.popupContent(htmlFile, 640, 480);&lt;br /&gt;
    let headerbar = AppContent.headerbarContent(htmlFile, 480);&lt;br /&gt;
&lt;br /&gt;
    this.onUserJoined = function(user) {&lt;br /&gt;
&lt;br /&gt;
        if (user.canSendAppContent(overlay)) {&lt;br /&gt;
            user.sendAppContent(overlay);&lt;br /&gt;
&lt;br /&gt;
        } else if (user.canSendAppContent(popup)) {&lt;br /&gt;
            user.sendAppContent(popup);&lt;br /&gt;
&lt;br /&gt;
        } else if (user.canSendAppContent(headerbar)) {&lt;br /&gt;
            user.sendAppContent(headerbar);&lt;br /&gt;
&lt;br /&gt;
        } else {&lt;br /&gt;
            user.sendPrivateMessage(&amp;quot;Die UserApp kann auf deinem Gerät leider nicht angezeigt werden.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;htmlFile&amp;amp;nbsp;=&amp;amp;nbsp;new&amp;amp;nbsp;HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;overlay&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.overlayContent(htmlFile,&amp;amp;nbsp;640,&amp;amp;nbsp;480);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;popup&amp;amp;nbsp;&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.popupContent(htmlFile,&amp;amp;nbsp;640,&amp;amp;nbsp;480);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;headerbar&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.headerbarContent(htmlFile,&amp;amp;nbsp;480);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(user.canSendAppContent(overlay))&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(overlay);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;if&amp;amp;nbsp;(user.canSendAppContent(popup))&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(popup);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;if&amp;amp;nbsp;(user.canSendAppContent(headerbar))&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(headerbar);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(&amp;quot;Die&amp;amp;nbsp;UserApp&amp;amp;nbsp;kann&amp;amp;nbsp;auf&amp;amp;nbsp;deinem&amp;amp;nbsp;Gerät&amp;amp;nbsp;leider&amp;amp;nbsp;nicht&amp;amp;nbsp;angezeigt&amp;amp;nbsp;werden.&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events senden ===&lt;br /&gt;
&lt;br /&gt;
Dein Code auf dem Server und dein Code auf dem Client laufen jetzt praktisch unabhängig voneinander. Meistens ist es aber hilfreich, wenn Server und Client miteinander kommunizieren können.&lt;br /&gt;
&lt;br /&gt;
==== Client → Server ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Beispiel:&#039;&#039;&#039; Wenn der Nutzer auf der grafischen Oberfläche einen Knopf drückt, soll der AppBot eine öffentliche Nachricht in den Channel schreiben.&amp;lt;br&amp;gt;&lt;br /&gt;
Du kannst aber nur von der &#039;&#039;&#039;main.js&#039;&#039;&#039; (also vom Server aus) Chat-Nachrichten schicken. [https://developer.knuddels.de/docs/classes/BotUser.html#method_sendPublicMessage BotUser.sendPublicMessage()] funktioniert im Client nicht.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Client muss also dem Server mitteilen, dass der Nutzer einen Button gedrückt hat. Das ist mit [https://developer.knuddels.de/docs/classes/Client.html#method_sendEvent Client.sendEvent()] möglich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Client.sendEvent(&amp;quot;buttonPressed&amp;quot;, {});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei können noch zusätzliche Daten in Form eines JavaScript-Objekts mitgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Der Server kann dann in der &#039;&#039;&#039;main.js&#039;&#039;&#039; in [https://developer.knuddels.de/docs/classes/App.html#method_onEventReceived App.onEventReceived()] reagieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
var App = (new function() {&lt;br /&gt;
    &lt;br /&gt;
    //...&lt;br /&gt;
    &lt;br /&gt;
    this.onEventReceived = function(user, type, data, appContentSession) {&lt;br /&gt;
&lt;br /&gt;
        if (type == &amp;quot;buttonPressed&amp;quot;) {&lt;br /&gt;
            let bot = KnuddelsServer.getDefaultBotUser();&lt;br /&gt;
            bot.sendPublicMessage(user.getProfileLink()+&amp;quot; hat den Knopf gedrückt!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;//...&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onEventReceived&amp;amp;nbsp;=&amp;amp;nbsp;function(user,&amp;amp;nbsp;type,&amp;amp;nbsp;data,&amp;amp;nbsp;appContentSession)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(type&amp;amp;nbsp;==&amp;amp;nbsp;&amp;quot;buttonPressed&amp;quot;)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;bot&amp;amp;nbsp;=&amp;amp;nbsp;KnuddelsServer.getDefaultBotUser();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;bot.sendPublicMessage(user.getProfileLink()+&amp;quot;&amp;amp;nbsp;hat&amp;amp;nbsp;den&amp;amp;nbsp;Knopf&amp;amp;nbsp;gedrückt!&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Server → alle Clients ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Beispiel:&#039;&#039;&#039; In der &#039;&#039;&#039;main.js&#039;&#039;&#039; wird eine zufällige Zahl generiert. Diese Zahl soll an alle Besucher des Channels geschickt werden, sodass diese dann in der HTML-UI angezeigt werden kann.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_sendEvent AppContent.sendEvent()] kannst du ein Event an alle Besucher schicken, bei denen dieser AppContent aktiv ist:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let randomNumber = Math.floor(10 * Math.random());&lt;br /&gt;
appContent.sendEvent(&amp;quot;showNumber&amp;quot;, {randomNumber: number});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Client kannst du mit [https://developer.knuddels.de/docs/classes/Client.html#method_addEventListener Client.addEventListener()] auf die Events vom Server reagieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Client.addEventListener(&amp;quot;showNumber&amp;quot;, function(event) {&lt;br /&gt;
        let number = event.data.number;&lt;br /&gt;
        &lt;br /&gt;
        document.open();&lt;br /&gt;
        document.write(&amp;quot;Die magische Zahl heißt: &amp;quot;+number);&lt;br /&gt;
        document.close()&lt;br /&gt;
});&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Client.addEventListener(&amp;quot;showNumber&amp;quot;,&amp;amp;nbsp;function(event)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;number&amp;amp;nbsp;=&amp;amp;nbsp;event.data.number;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;document.open();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;document.write(&amp;quot;Die&amp;amp;nbsp;magische&amp;amp;nbsp;Zahl&amp;amp;nbsp;heißt:&amp;amp;nbsp;&amp;quot;+number);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;document.close()&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Server → ein bestimmter Client ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel:&#039;&#039;&#039; Du wählst einen Besucher zufällig aus und möchtest, dass sich bei diesem Besucher die Farbe der HTML-UI ändert.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dazu musst du vom Server aus (also in der &#039;&#039;&#039;main.js&#039;&#039;&#039;) diesem Client ein Event senden.&amp;lt;br&amp;gt;&lt;br /&gt;
Du kannst aber nicht einfach &#039;&#039;User.sendEvent()&#039;&#039; aufrufen (diesen Befehl gibt es nicht). Eine UserApp kann nämlich verschiedene &#039;&#039;&#039;ViewModes&#039;&#039;&#039; auf einmal verwenden (sogenannte &#039;&#039;&#039;AppContentSessions&#039;&#039;&#039;). Du musst der API also sagen, an welche &#039;&#039;&#039;AppContentSession&#039;&#039;&#039; du das Event senden möchtest.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn du weißt, welchen &#039;&#039;&#039;ViewMode&#039;&#039;&#039; der Besucher verwendet (z.B. weil du sowieso immer nur ein Popup sendest), kannst du einfach mit dem Befehl [https://developer.knuddels.de/docs/classes/User.html#method_getAppContentSession User.getAppContentSession] die AppContentSession erhalten und dann das Event senden. &#039;&#039;&#039;Beispiel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let appContentSession = user.getAppContentSession(AppViewMode.Popup);&lt;br /&gt;
appContentSession.sendEvent(&amp;quot;changeColor&amp;quot;, {red:255, green:0, blue:255});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn dein Client allerdings gleichzeitig mehrere aktive &#039;&#039;&#039;AppContentSessions&#039;&#039;&#039; haben könnte (z.B. eine Headerbar und ein Popup), kannst du eine Liste aller aktiven AppContentSessions eines Besuchers mit [https://developer.knuddels.de/docs/classes/User.html#method_getAppContentSessions User.getAppContentSessions()] erhalten. &#039;&#039;&#039;Beispiel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
let appContentSessions = user.getAppContentSessions();&lt;br /&gt;
&lt;br /&gt;
for (let i = 0; i &amp;lt; appContentSessions.length; i++) {&lt;br /&gt;
    let appContentSession = appContentSessions[i];&lt;br /&gt;
    appContentSession.sendEvent(&amp;quot;changeColor&amp;quot;, {red:255, green:0, blue:255});&lt;br /&gt;
}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let&amp;amp;nbsp;appContentSessions&amp;amp;nbsp;=&amp;amp;nbsp;user.getAppContentSessions();&lt;br /&gt;
&lt;br /&gt;
for&amp;amp;nbsp;(let&amp;amp;nbsp;i&amp;amp;nbsp;=&amp;amp;nbsp;0;&amp;amp;nbsp;i&amp;amp;nbsp;&amp;lt;&amp;amp;nbsp;appContentSessions.length;&amp;amp;nbsp;i++)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;appContentSession&amp;amp;nbsp;=&amp;amp;nbsp;appContentSessions[i];&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;appContentSession.sendEvent(&amp;quot;changeColor&amp;quot;,&amp;amp;nbsp;{red:255,&amp;amp;nbsp;green:0,&amp;amp;nbsp;blue:255});&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier kannst du im Client wieder mit [https://developer.knuddels.de/docs/classes/Client.html#method_addEventListener Client.addEventListener()] auf die Events reagieren.&lt;br /&gt;
&lt;br /&gt;
==== Limits ====&lt;br /&gt;
&lt;br /&gt;
Für die Daten, die du mit den Events zwischen Client und Server sendest, gibt es gewisse [[Limits]]. Diese Limits werden [[Limits|hier]] beschrieben.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/Beginner&amp;diff=128157</id>
		<title>UserApp-Entwicklung/Tutorials/Beginner</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/Beginner&amp;diff=128157"/>
		<updated>2019-07-23T08:27:25Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
In diesem Tutorial lernst du Schritt für Schritt, deine erste UserApp zu programmieren.&amp;lt;br&amp;gt;&lt;br /&gt;
Hier geht es darum, erstmal alles zum Laufen zu bringen und ein paar Basics zu vermitteln, sodass ab dann selbstständig weiterentwickelt werden kann.&lt;br /&gt;
&lt;br /&gt;
== Bevor es losgeht ==&lt;br /&gt;
&lt;br /&gt;
=== Werde Entwickler ===&lt;br /&gt;
&lt;br /&gt;
Stelle sicher, dass du ein Entwickler bist. Gib dazu &#039;&#039;&#039;/apps developer&#039;&#039;&#039; im Chat ein und erfülle die Kriterien, falls du das noch nicht getan hast.&lt;br /&gt;
&lt;br /&gt;
=== Verwende die Desktop-App ===&lt;br /&gt;
&lt;br /&gt;
Wir empfehlen dir stark, zum Entwickeln die Desktop-App auf deinem Computer zu verwenden. Du kannst die App [https://www.knuddels.de/stapp-win hier herunterladen].&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Die erste UserApp ==&lt;br /&gt;
&lt;br /&gt;
=== Entwicklungs-Server ===&lt;br /&gt;
Das Entwickeln beginnt auf dem Entwicklungs-Server. Gib &#039;&#039;&#039;/apps developer&#039;&#039;&#039; ein und wähle den Punkt &#039;&#039;&#039;Login auf Entwicklungs-Server&#039;&#039;&#039; aus. Jetzt sollte eine Desktop-Verknüpfung für den Login auf dem Entwicklungs-Server angelegt worden sein.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn du Knuddels über diese Verknüpfung startest, landest du nach dem Login auf dem Entwicklungs-Server. Hier kannst du später in Ruhe an deiner UserApp tüfteln, bevor du deine Änderungen auf dem Live-Server hochlädst.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logge dich jetzt mit den Zugangsdaten auf dem  Entwicklungsserver ein, die dir James gesendet hat (&#039;&#039;&#039;Entwickler-Nick&#039;&#039;&#039; und &#039;&#039;&#039;Entwickler-Passwort&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
  Tipp: Du kannst die Zugangsdaten aus James&#039; Nachricht mit Shift+Rechtsklick in das Chat-Fenster kopieren.&lt;br /&gt;
&lt;br /&gt;
=== MyChannel ===&lt;br /&gt;
&lt;br /&gt;
Nach dem Einloggen sollte sich automatisch das [[MyChannel]]-Edit Fenster öffnen. Ansonsten gib &#039;&#039;&#039;/mychannel&#039;&#039;&#039; ein.&amp;lt;br&amp;gt;&lt;br /&gt;
Du legst dir jetzt einen eigenen Channel an, in dem du gleich deine erste UserApp installieren wirst. Eine Info zu den Einstellungen erhältst du durch Klicken auf den Titel des jeweiligen Feldes. Außer über deinen Channel-Namen musst du dir aber erstmal keine Gedanken machen (du kannst dieses Fenster jederzeit wieder mit &#039;&#039;&#039;/mychannel&#039;&#039;&#039; öffnen). Drücke anschließend auf &#039;&#039;&#039;Speichern&#039;&#039;&#039; und &#039;&#039;&#039;Schließen&#039;&#039;&#039; und betritt deinen MyChannel mit &#039;&#039;&#039;/go &amp;lt;dein eigener Channel-Name&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Installation der UserApp ===&lt;br /&gt;
&lt;br /&gt;
Für dieses Tutorial haben wir dir schon Dateien für eine Beispiel-UserApp namens &amp;quot;HeyThere&amp;quot; auf den Server geladen. Installiere diese UserApp in deinem MyChannel mit &#039;&#039;&#039;/apps install HeyThere&#039;&#039;&#039;. Du kannst die UserApp später wieder aus deinem Channel löschen.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es müsste sich nun automatisch das Konfigurationsfenster für die UserApp geöffnet haben. Ansonsten öffne es selbst mit  &#039;&#039;&#039;/apps&#039;&#039;&#039; und klicke auf den Namen der UserApp (&amp;quot;HeyThere&amp;quot;).&lt;br /&gt;
  Hinweis: Durch einen Bug kann es sein, dass das Fenster auf dem Entwicklungs-Server nichts anzeigt. Schließe es einfach und öffne es gleich nochmal mit &#039;&#039;&#039;/apps&#039;&#039;&#039;. Wir hoffen, diesen Bug bald beheben zu können.&lt;br /&gt;
&lt;br /&gt;
Im Menüpunkt &amp;quot;AppBot&amp;quot; kannst du einen [[UserApp-Entwicklung/Doku/AppBot|AppBot]] erstellen und an deine UserApp binden. Ein AppBot ist ein bisschen wie [[James|Butler James]], nur eben für deine UserApp in deinem Channel. Drücke hierzu auf &amp;quot;hinzufügen&amp;quot; → &amp;quot;Nick anlegen&amp;quot;, denk dir einen Nicknamen aus und bestätige.&lt;br /&gt;
&lt;br /&gt;
Starte jetzt deine erste UserApp.&lt;br /&gt;
  Falls sich kein entsprechendes Fenster öffnet, starte die UserApp selbst, indem du im App-Menü auf &#039;&#039;&#039;aktivieren&#039;&#039;&#039; klickst.&lt;br /&gt;
Verlasse nun deinen Channel (indem du in einen anderen Channel gehst) und betritt ihn dann wieder (z.B. mit &#039;&#039;&#039;/go &amp;lt;dein eigener Channel-Name&amp;gt;&#039;&#039;&#039;). Dein AppBot sollte dich jetzt begrüßen!&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um mit dem Entwickeln zu starten, mach mit dem nächsten Schritt weiter (FTP-Setup). Du kannst auch schon mal einen Blick in die [http://developer.knuddels.de/docs/ UserApps-API-Dokumentation] werfen.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bestimmt wird es auch mal eine Stelle geben, an der du nicht weiter weißt. Zögere nicht, [http://forum.knuddels.de/ubbthreads.php?ubb=postlist&amp;amp;Board=272&amp;amp;page=1 im Forum] Fragen zu stellen, wenn dir etwas nicht klar ist! Die anderen Entwickler sind freundlich, gehen fair miteinander um und helfen sich gerne gegenseitig.&lt;br /&gt;
&lt;br /&gt;
== FTP-Setup ==&lt;br /&gt;
&lt;br /&gt;
Du benötigst für die UserApp-Entwicklung ein FTP-Programm, um die Dateien für deine UserApp auf die Server von Knuddels hochzuladen.&lt;br /&gt;
&lt;br /&gt;
=== Was ist eigentlich FTP? ===&lt;br /&gt;
&lt;br /&gt;
FTP (File Transfer Protocol) ist ein Protokoll, mit dem Daten zwischen zwei Computern im Internet ausgetauscht werden können.&amp;lt;br&amp;gt;&lt;br /&gt;
Zum Glück gibt es ganz einfache Programme, die hinter den Kulissen dieses Protokoll sprechen, sodass du die Dateien mit wenigen Klicks hochladen kannst.&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung des FTP-Zugangs ===&lt;br /&gt;
&lt;br /&gt;
Du wirst die Dateien deiner UserApp auf zwei verschiedenen Servern hochladen:&lt;br /&gt;
# auf dem &#039;&#039;&#039;Entwicklungs-Server&#039;&#039;&#039;, unter der URL &#039;&#039;&#039;devappupload.knuddels.de&#039;&#039;&#039;&lt;br /&gt;
# auf dem &#039;&#039;&#039;Live-Server&#039;&#039;&#039;, unter der URL &#039;&#039;&#039;appupload.knuddels.de&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Für beide Server musst du dir jeweils eine Verbindung einrichten. Dafür brauchst du ein FTP-Programm.&lt;br /&gt;
Schau dir dazu [https://bitbucket.org/knuddels/user-apps/wiki/Bootstrap/FTP-Setup diese Erklärung] an.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Diese Erklärung zeigt allerdings nur die Verbindung zum Live-Server&#039;&#039;&#039; - verwende für den Entwicklungs-Server stattdessen die URL &#039;&#039;&#039;devappupload.knuddels.de&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als Zugangsdaten verwendest du die Zugangsdaten, die James dir geschickt hat (&#039;&#039;&#039;FTP-Nutzer&#039;&#039;&#039; und &#039;&#039;&#039;FTP-Passwort&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
  Tipp: Du kannst die Zugangsdaten aus James&#039; Nachricht mit Shift+Rechtsklick in das Chat-Fenster kopieren.&lt;br /&gt;
  Unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039; kannst du sie außerdem erneut anfordern.&lt;br /&gt;
&lt;br /&gt;
Achte außerdem jeweils darauf, eine &#039;&#039;&#039;unverschlüsselte Verbindung&#039;&#039;&#039; zu wählen.&lt;br /&gt;
&lt;br /&gt;
== Beispiel-Code anschauen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du weißt, wie du Dateien über den FTP-Zugang von dem Server herunter- und hochladen kannst, kannst du dir jetzt anschauen, wie eine UserApp aufgebaut ist.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logge dich in deinem FTP-Programm auf dem Entwicklungs-Server ein, navigiere in den Ordner &#039;&#039;&#039;ftp → HeyThere&#039;&#039;&#039; und lade dort die Datei &#039;&#039;&#039;main.js&#039;&#039;&#039; herunter. Du kannst diese Datei jetzt anschauen, verändern und dann wieder dort hochladen. So verstehst du, wie alles funktioniert.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;main.js&#039;&#039;&#039; kannst du sogar im normalen Texteditor anschauen und bearbeiten.&amp;lt;br&amp;gt;&lt;br /&gt;
Empfehlenswert ist das aber nicht.&lt;br /&gt;
*Auf Windows kannst du dir (zum Beispiel) [http://notepad-plus-plus.org/ Notepad++] herunterladen.&lt;br /&gt;
* Auf macOS kannst du dir (zum Beispiel) [https://itunes.apple.com/de/app/textwrangler/id404010395?mt=12 Textwrangler] herunterladen.&lt;br /&gt;
Diese Programme können dir das Entwickeln erleichtern. (Natürlich kannst du auch eine IDE verwenden, wenn du dich damit auskennst.)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schau dir den Code jetzt an und nimm einige Veränderungen vor.&lt;br /&gt;
&lt;br /&gt;
  Idee: Lass deinen AppBot Besucher abhängig von ihrem Geschlecht begrüßen! Zum Beispiel männliche Besucher mit &amp;quot;Hey Prinz &amp;lt;Nickname&amp;gt;&amp;quot; und weibliche Besucher mit &amp;quot;Hey Prinzessin &amp;lt;Nickname&amp;gt;&amp;quot;. Findest du heraus, wie das geht?&lt;br /&gt;
&lt;br /&gt;
→ Jetzt ist ein guter Zeitpunkt, die [https://developer.knuddels.de/docs/ API-Dokumentation] anzuschauen.&lt;br /&gt;
Der Aufbau der &#039;&#039;&#039;main.js&#039;&#039;&#039; wird [https://bitbucket.org/knuddels/user-apps/wiki/Bootstrap/App-Erstellen hier] erklärt.&lt;br /&gt;
&lt;br /&gt;
Gehe danach folgendermaßen vor:&lt;br /&gt;
# Verändere die Datei und speichere sie.&lt;br /&gt;
# Lade die Datei auf den FTP-Server hoch (ersetze die alte &#039;&#039;&#039;main.js&#039;&#039;&#039;).&lt;br /&gt;
# Öffne das App-Menü in deinem Channel mit &#039;&#039;&#039;/apps&#039;&#039;&#039; und drücke auf &#039;&#039;&#039;update/restart&#039;&#039;&#039;. Deine App fährt herunter und startet nach wenigen Sekunden erneut - mit deinem neuen Code.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wird gezeigt, wie man Besucher abhängig von ihrem Geschlecht begrüßen kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Begrüße Besucher abhängig von ihrem Geschlecht ==&lt;br /&gt;
&lt;br /&gt;
So kannst du neuen Besuchern eine Begrüßungsnachricht abhängig von ihrem Geschlecht schicken:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;main.js&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;!-- schneller Workaround (&amp;lt;code&amp;gt; ist kaputt, whitespaces werden gestript): Leerzeichen durch &amp;amp;nbsp; ersetzen --&amp;gt;&lt;br /&gt;
&amp;lt;!-- in Python: print(&amp;quot;code() {...}&amp;quot;.replace(&amp;quot; &amp;quot;, &amp;quot;&amp;amp;nbsp;&amp;quot;)) --&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&amp;amp;nbsp;&amp;amp;nbsp;//&amp;amp;nbsp;diese&amp;amp;nbsp;Funktion&amp;amp;nbsp;wird&amp;amp;nbsp;aufgerufen,&amp;amp;nbsp;wenn&amp;amp;nbsp;ein&amp;amp;nbsp;Nutzer&amp;amp;nbsp;den&amp;amp;nbsp;Channel&amp;amp;nbsp;betritt&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;gender&amp;amp;nbsp;=&amp;amp;nbsp;user.getGender();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;nick&amp;amp;nbsp;&amp;amp;nbsp;=&amp;amp;nbsp;user.getNick();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;title;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(gender&amp;amp;nbsp;==&amp;amp;nbsp;Gender.Male)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;title&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Prinz&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;nick;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;if&amp;amp;nbsp;(gender&amp;amp;nbsp;==&amp;amp;nbsp;Gender.Female)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;title&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Prinzessin&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;nick;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;{&amp;amp;nbsp;&amp;amp;nbsp;//&amp;amp;nbsp;der&amp;amp;nbsp;Nutzer&amp;amp;nbsp;hat&amp;amp;nbsp;sich&amp;amp;nbsp;nicht&amp;amp;nbsp;als&amp;amp;nbsp;männlich&amp;amp;nbsp;oder&amp;amp;nbsp;weiblich&amp;amp;nbsp;ausgegeben&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;title&amp;amp;nbsp;=&amp;amp;nbsp;nick;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;message&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Hey&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;title&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;,&amp;amp;nbsp;willkommen&amp;amp;nbsp;im&amp;amp;nbsp;Channel!&amp;amp;nbsp;Du&amp;amp;nbsp;bist&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;user.getAge()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;Jahre&amp;amp;nbsp;alt.&amp;quot;;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(message);&amp;amp;nbsp;&amp;amp;nbsp;//&amp;amp;nbsp;der&amp;amp;nbsp;AppBot&amp;amp;nbsp;sendet&amp;amp;nbsp;eine&amp;amp;nbsp;private&amp;amp;nbsp;Nachricht&amp;amp;nbsp;an&amp;amp;nbsp;den&amp;amp;nbsp;Nutzer&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schaffst du es außerdem, die Besucher sowohl abhängig von ihrem Alter, als auch von ihrem Geschlecht zu begrüßen?   &lt;br /&gt;
→ Begrüße Besucher...&lt;br /&gt;
* unter 18 Jahren mit: &#039;&#039;&#039;&amp;quot;Hallo Junge &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;quot;Hallo Mädchen &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
* zwischen 18 und 60 Jahren mit: &#039;&#039;&#039;&amp;quot;Hallo Herr &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;quot;Hallo Frau &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
* über 60 Jahren mit: &#039;&#039;&#039;&amp;quot;Hallo Opa &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;quot;Hallo Oma &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Schau in die [https://developer.knuddels.de/docs/ UserApps-API-Dokumentation], wenn du eine Funktion suchst.&lt;br /&gt;
Den fertigen Code kannst du dir hier herunterladen: [https://bitbucket.org/knuddels/user-apps/downloads/Beispielcode%20HeyThere%20-%20Stufe%202%20-%20Erweiterung.zip Begrüßung nach Alter und Geschlecht]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt lernst du, wie Besucher &#039;&#039;&#039;Knuddel&#039;&#039;&#039; an deinen AppBot transferieren können!&lt;br /&gt;
&lt;br /&gt;
== Knuddel überweisen ==&lt;br /&gt;
&lt;br /&gt;
Nutzer können Knuddel an deinen AppBot überweisen. Diese Knuddel kannst du dir dann später auf deinen eigenen Nick überweisen lassen. Hier lernst du, wie du das in deiner UserApp machen kannst.&lt;br /&gt;
&lt;br /&gt;
Der AppBot soll jeden neuen Nutzer nach einem Knuddel fragen. Wenn er diesen bekommt, bedankt er sich bei dem Nutzer.&lt;br /&gt;
&lt;br /&gt;
  Auf dem Entwicklungs-Server hat dein Nick so viele Knuddel, dass du das einfach testen kannst.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;main.js&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;appBotNick&amp;amp;nbsp;=&amp;amp;nbsp;KnuddelsServer.getDefaultBotUser().getNick();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;message&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Gibst&amp;amp;nbsp;du&amp;amp;nbsp;mir&amp;amp;nbsp;_°BB°°&amp;gt;_heinen&amp;amp;nbsp;Knuddel|/appknuddel&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;appBotNick.escapeKCode()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;&amp;lt;°°°_?&amp;quot;;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(message);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onKnuddelReceived&amp;amp;nbsp;=&amp;amp;nbsp;function(sender,&amp;amp;nbsp;receiver,&amp;amp;nbsp;knuddelAmount,&amp;amp;nbsp;transferReason)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;sender.sendPrivateMessage(&amp;quot;Danke,&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;sender.getNick()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;!&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erklärung: Was ist KCode? ===&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;App.onUserJoined&#039;&#039;&#039; wird dem Nutzer eine Nachricht mit seltsamen Zeichen gesendet:  &lt;br /&gt;
&lt;br /&gt;
  &amp;quot;Gibst du mir _°BB°°&amp;gt;_heinen Knuddel|/appknuddel &amp;quot; + appBotNick.escapeKCode() + &amp;quot;&amp;lt;°°°_?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das ist [[Formatierungen|KCode]]. Dieser Code wird vor dem Anzeigen umgewandelt, sodass die Nutzer einen Link präsentiert bekommen, auf dessen Klick hin ein Befehl ausgeführt wird: Hier ist dieser Befehl &#039;&#039;&#039;/appknuddel &amp;lt;Nickname des AppBots&amp;gt;&#039;&#039;&#039;. Mit dem Klicken auf den Link überweist der Nutzer also einen Knuddel an den AppBot.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;appBotNick.escapeKCode()&#039;&#039;&#039; dient dazu, dass der Befehl auch bei Sonderzeichen im Nicknamen deines AppBots richtig ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
[[Formatierungen|→ Hier kannst du dir anschauen, wie KCode funktioniert.]]&lt;br /&gt;
&lt;br /&gt;
  Idee für wahre Kapitalisten: Du kannst den Besucher deines Channels vielleicht dazu bringen, dem AppBot einen Knuddel zu schenken, wenn der AppBot dem Besucher nach einiger Zeit eine traurige Nachricht schreibt, falls er bis dahin keinen Knuddel von dem Besucher erhalten hat.&lt;br /&gt;
&lt;br /&gt;
Eine mögliche Lösung dieses Problems kannst du dir hier anschauen: [https://bitbucket.org/knuddels/user-apps/downloads/Beispielcode%20HeyThere%20-%20Stufe%203%20-%20Erweiterung.zip Download Code-Beispiel (Traurige Nachricht vom AppBot)]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt lernst du, wie du dauerhaft Daten über deine Besucher speichern kannst.&lt;br /&gt;
&lt;br /&gt;
== UserPersistence: Nutzerdaten speichern ==&lt;br /&gt;
&lt;br /&gt;
Wenn du dir beispielsweise dauerhaft merken willst, wie viele Knuddel ein Nutzer jeweils schon deinem AppBot überwiesen hat, brauchst du eine Möglichkeit, zu jedem Nutzer eine Zahl zu speichern.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  Allerdings kannst du nicht einfach eine Variable in deinem Code haben, worüber du alles speicherst - das wäre nämlich mit jedem Neustart der App wieder weg.&lt;br /&gt;
&lt;br /&gt;
In der [https://developer.knuddels.de/docs/ UserApps-API] gibt es genau dafür das Objekt [https://developer.knuddels.de/docs/classes/UserPersistence.html UserPersistence].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;main.js&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;userPersistence&amp;amp;nbsp;=&amp;amp;nbsp;user.getPersistence();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;userSpending&amp;amp;nbsp;=&amp;amp;nbsp;userPersistence.getNumber(&amp;quot;spending&amp;quot;,&amp;amp;nbsp;0);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(userSpending&amp;amp;nbsp;&amp;gt;&amp;amp;nbsp;10)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(&amp;quot;Willkommen,&amp;amp;nbsp;gütiger&amp;amp;nbsp;Spender!&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;appBotNick&amp;amp;nbsp;=&amp;amp;nbsp;KnuddelsServer.getDefaultBotUser().getNick();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;message&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Gibst&amp;amp;nbsp;du&amp;amp;nbsp;mir&amp;amp;nbsp;_°BB°°&amp;gt;_heinen&amp;amp;nbsp;Knuddel|/appknuddel&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;appBotNick.escapeKCode()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;&amp;lt;°°°_?&amp;quot;;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(message);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onKnuddelReceived&amp;amp;nbsp;=&amp;amp;nbsp;function(sender,&amp;amp;nbsp;receiver,&amp;amp;nbsp;knuddelAmount,&amp;amp;nbsp;transferReason)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;sender.sendPrivateMessage(&amp;quot;Danke,&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;sender.getNick()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;userPersistence&amp;amp;nbsp;=&amp;amp;nbsp;sender.getPersistence();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;userPersistence.addNumber(&amp;quot;spending&amp;quot;,&amp;amp;nbsp;knuddelAmount.asNumber());&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die App merkt sich nun, wie viele Knuddel deine Besucher bereits eingezahlt haben. Besonders gönnerische Besucher begrüßt er ehrerbietig!&lt;br /&gt;
&lt;br /&gt;
== Dein Fortschitt ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Du bist schon weit gekommen!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Du hast gelernt, wie man sich auf dem Entwicklungs-Server anmeldet und eine App installiert.&lt;br /&gt;
* Du hast dich mit FTP vertraut gemacht und kannst deine Dateien jetzt einfach an den Knuddels-Server senden.&lt;br /&gt;
* Du weißt jetzt, wie man auf verschiedene Events in deinem Channel reagiert.&lt;br /&gt;
* Du bist mit der Überweisung von Knuddel an deinen AppBot vertraut.&lt;br /&gt;
* Du kannst Daten über deine Besucher dauerhaft speichern.&lt;br /&gt;
&lt;br /&gt;
Jetzt kannst du deine UserApp mal veröffentlichen! Dazu musst du deine UserApp per FTP auf dem Live-Server hochladen - so wie schon vorher auf dem Entwicklungs-Server. Melde dich dann ganz normal bei Knuddels an und installiere deine UserApp mit &#039;&#039;&#039;/apps install &amp;lt;UserApp-Name&amp;gt;&#039;&#039;&#039; in deinem MyChannel.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und wenn du jetzt noch deinen MyChannel unter &#039;&#039;&#039;/mychannel&#039;&#039;&#039; veröffentlichst, können auch andere Nutzer zufällig auf deinen MyChannel stoßen.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wie geht&#039;s weiter? ==&lt;br /&gt;
&lt;br /&gt;
Vielleicht hast du Lust, ein grafisches Spiel zu programmieren? Oder ein textbasiertes RPG?&amp;lt;br&amp;gt;&lt;br /&gt;
Ab jetzt bist du dir selbst überlassen - und kannst dich natürlich jederzeit an die Community wenden.&amp;lt;br&amp;gt;&lt;br /&gt;
Auf dem Entwickler-Portal [https://developer.knuddels.de/ developer.knuddels.de] findest du das meiste im Zusammenhang mit UserApps.&lt;br /&gt;
&lt;br /&gt;
[[UserApp-Entwicklung|→ Übersicht: UserApp-Entwicklung]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128156</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128156"/>
		<updated>2019-07-23T08:26:23Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Für Anfänger ==&lt;br /&gt;
Lerne Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Einstieg]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/HTML-UI|HTML-UI (grafische Oberfläche)]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/UserApps_teilen|UserApps installieren und freigeben]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Newsletter-Versand|Newsletter-Versand]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/AppBot-Profilbild|AppBot-Profilbild]]&lt;br /&gt;
&lt;br /&gt;
== Für Fortgeschrittene ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Es gibt leider noch keine Tutorials für Fortgeschrittene.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Du kannst dich auf Discord an fortgeschrittene UserApp-Entwickler wenden. Den Link zum Discord-Channel findest du unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[User_Apps/Tutorial|Hallo Welt]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Meta ==&lt;br /&gt;
&lt;br /&gt;
Tutorial über das Schreiben von UserApp-Tutorials: [[UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta|UserApp-Tutorials-Meta]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung&amp;diff=128155</id>
		<title>UserApp-Entwicklung</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung&amp;diff=128155"/>
		<updated>2019-07-23T08:25:46Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: zu Kategorie &amp;quot;UserApp-Entwicklung&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Hier findest du alles was du wissen musst, um deine eigene UserApp auf Knuddels zu programmieren.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn du noch nicht weißt, was eine UserApp ist, schau einfach hier: [[User_App|Was ist eine UserApp?]]&amp;lt;br&amp;gt;&lt;br /&gt;
Einen Überblick über alles im Zusammenhang mit UserApps (auch dieses Wiki) findest du auf dem Entwickler-Portal unter [https://developer.knuddels.de/ developer.knuddels.de].&lt;br /&gt;
&lt;br /&gt;
== Tutorials https://knuddels-wiki.de/images/c/c9/Icon_-_Newbie.gif ==&lt;br /&gt;
&lt;br /&gt;
Wenn du noch keine UserApp entwickelt hast, kannst du das [[UserApp-Entwicklung/Tutorials/Beginner|Beginner-Tutorial]] machen. Dort lernst du Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
→ [[UserApp-Entwicklung/Tutorials|Hier ist die Übersicht über alle Tutorials.]]&lt;br /&gt;
&lt;br /&gt;
== Wichtige Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://developer.knuddels.de/ developer.knuddels.de] - das Entwickler-Portal (Überblick über alles im Zusammenhang mit UserApps)&lt;br /&gt;
* [https://developer.knuddels.de/docs/ UserApps-API Docs]&lt;br /&gt;
* [https://www.knuddels.de/changelog Changelog]&lt;br /&gt;
&lt;br /&gt;
== Andere UserApps-Entwickler ==&lt;br /&gt;
&lt;br /&gt;
* Wir freuen uns, wenn sich neue Entwickler kurz [https://forum.knuddels.de/ubbthreads.php?ubb=showflat&amp;amp;Number=2704910 im Forum vorstellen]. Aber das ist natürlich kein Muss.&lt;br /&gt;
* Die Kommunikation findet über den Discord Server statt.&amp;lt;br&amp;gt;Gib &#039;&#039;&#039;/apps developer&#039;&#039;&#039; ein und klicke auf den entsprechenden Link.&amp;lt;br&amp;gt;[https://blog.knuddels.de/2018/07/31/kommunikation-zukuenftig-auf-discord/ → Blogeintrag dazu]&lt;br /&gt;
* Außerdem gibt es im [https://forum.knuddels.de/ubbthreads.php?ubb=cfrm&amp;amp;c=9 UserApps-Forum] viele Beiträge!&lt;br /&gt;
&lt;br /&gt;
== Die UserApps-API https://knuddels-wiki.de/images/2/29/Quiz-Smiley.gif ==&lt;br /&gt;
&lt;br /&gt;
Willst du mehr über die UserApps-API wissen? Schau mal hier rein:&lt;br /&gt;
&lt;br /&gt;
* [[API|Was ist die UserApps-API?]]&lt;br /&gt;
* [https://developer.knuddels.de/docs/ UserApps-API Docs]&lt;br /&gt;
&lt;br /&gt;
== Design &amp;amp; Grafik in UserApps https://knuddels-wiki.de/images/a/a0/Rose.gif ==&lt;br /&gt;
&lt;br /&gt;
UserApps können natürlich auch Grafiken, Animationen und Sounds wiedergeben! Du kannst sogar ein 3D-Spiel als UserApp programmieren!&lt;br /&gt;
Mindestens kannst du aber mal &#039;&#039;&#039;KCode&#039;&#039;&#039; lernen, falls du das noch nicht getan hast.  &lt;br /&gt;
Schau dir als Einstieg folgende Links an:&lt;br /&gt;
&lt;br /&gt;
* Texte vom AppBot formatieren: [[Formatierungen]]&lt;br /&gt;
* Grafische Web-Oberfläche&lt;br /&gt;
** [[User_App:HTML-UI/Web|Einführung 1]]&lt;br /&gt;
** [https://bitbucket.org/knuddels/user-apps/wiki/HTML-UI/Web Einführung 2]&lt;br /&gt;
** [https://bitbucket.org/knuddels/user-apps/wiki/HTML-UI/Environment Besonderheiten der HTML-UI (Environment)]&lt;br /&gt;
&lt;br /&gt;
== Technische Infos ==&lt;br /&gt;
&lt;br /&gt;
* [https://bitbucket.org/knuddels/user-apps/wiki/Development Development] - einige Basics und technische Infos&lt;br /&gt;
* [[Limits|Technische Limits]] für UserApps&lt;br /&gt;
&lt;br /&gt;
== Bugs ==&lt;br /&gt;
&lt;br /&gt;
Wenn du einen Bug bemerkt hast, kannst du jemanden im &#039;&#039;&#039;/team bugs&#039;&#039;&#039; anschreiben.  &lt;br /&gt;
Deine Ideen und Wünsche kannst du mit uns auf Discord teilen.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Kategorie:UserApp-Entwicklung&amp;diff=128154</id>
		<title>Kategorie:UserApp-Entwicklung</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Kategorie:UserApp-Entwicklung&amp;diff=128154"/>
		<updated>2019-07-23T08:22:56Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Die Seite wurde neu angelegt: „Die &amp;#039;&amp;#039;&amp;#039;Kategorie &amp;quot;UserApp-Entwicklung&amp;#039;&amp;#039;&amp;#039; enthält alle Artikel zu UserApps, die für &amp;#039;&amp;#039;&amp;#039;UserApp-Entwickler&amp;#039;&amp;#039;&amp;#039; gedacht sind -  also UserApp-Entwi…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die &#039;&#039;&#039;Kategorie &amp;quot;UserApp-Entwicklung&#039;&#039;&#039; enthält alle Artikel zu [[User_App|UserApps]], die für &#039;&#039;&#039;UserApp-Entwickler&#039;&#039;&#039; gedacht sind -  also [[UserApp-Entwicklung/Tutorials|Tutorials]], technische Dokumentation usw.&amp;lt;br&amp;gt;&lt;br /&gt;
Im Gegensatz dazu enthält die andere [https://knuddels-wiki.de/index.php?title=Kategorie:User_App Kategorie &amp;quot;User App&amp;quot;] Artikel, die für gewöhnliche Nutzer gedacht sind.&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Bots_(virtuelle_Person)&amp;diff=128152</id>
		<title>Bots (virtuelle Person)</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Bots_(virtuelle_Person)&amp;diff=128152"/>
		<updated>2019-07-22T17:04:46Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: verlinkt auf AppBot&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Allgemeines==&lt;br /&gt;
Ein &#039;&#039;&#039;Bot&#039;&#039;&#039; ist ein Programm, welches verschiedene Aufgaben übernehmen kann. So ist z.B. [[James]] auch ein Bot. Bots können jegliche Art von Aufgaben übernehmen. Diese sind zum Beispiel, durchgehend online sein oder auch auf Anfragen zu reagieren, dies aber auch nur, aus einer Liste mit vorgegebenen Antworten. &lt;br /&gt;
&lt;br /&gt;
Bots sind in jeglicher Art, außer die Systembots und die [[UserApp-Entwicklung/Doku/AppBot|AppBots]] von [[User_Apps|UserApps]], in [[Knuddels]] verboten. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Weiterführende Informationen==&lt;br /&gt;
* [[James]] - Informationen zum Chat-Butler&lt;br /&gt;
* [[User_Apps|UserApps]] - Informationen zu den UserApps&lt;br /&gt;
* [[UserApp-Entwicklung/Doku/AppBot|AppBot]] - Informationen zu den AppBots von UserApps&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/Beginner&amp;diff=128151</id>
		<title>UserApp-Entwicklung/Tutorials/Beginner</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/Beginner&amp;diff=128151"/>
		<updated>2019-07-22T17:01:27Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: /* Installation der UserApp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
In diesem Tutorial lernst du Schritt für Schritt, deine erste UserApp zu programmieren.&amp;lt;br&amp;gt;&lt;br /&gt;
Hier geht es darum, erstmal alles zum Laufen zu bringen und ein paar Basics zu vermitteln, sodass ab dann selbstständig weiterentwickelt werden kann.&lt;br /&gt;
&lt;br /&gt;
== Bevor es losgeht ==&lt;br /&gt;
&lt;br /&gt;
=== Werde Entwickler ===&lt;br /&gt;
&lt;br /&gt;
Stelle sicher, dass du ein Entwickler bist. Gib dazu &#039;&#039;&#039;/apps developer&#039;&#039;&#039; im Chat ein und erfülle die Kriterien, falls du das noch nicht getan hast.&lt;br /&gt;
&lt;br /&gt;
=== Verwende die Desktop-App ===&lt;br /&gt;
&lt;br /&gt;
Wir empfehlen dir stark, zum Entwickeln die Desktop-App auf deinem Computer zu verwenden. Du kannst die App [https://www.knuddels.de/stapp-win hier herunterladen].&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Die erste UserApp ==&lt;br /&gt;
&lt;br /&gt;
=== Entwicklungs-Server ===&lt;br /&gt;
Das Entwickeln beginnt auf dem Entwicklungs-Server. Gib &#039;&#039;&#039;/apps developer&#039;&#039;&#039; ein und wähle den Punkt &#039;&#039;&#039;Login auf Entwicklungs-Server&#039;&#039;&#039; aus. Jetzt sollte eine Desktop-Verknüpfung für den Login auf dem Entwicklungs-Server angelegt worden sein.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn du Knuddels über diese Verknüpfung startest, landest du nach dem Login auf dem Entwicklungs-Server. Hier kannst du später in Ruhe an deiner UserApp tüfteln, bevor du deine Änderungen auf dem Live-Server hochlädst.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logge dich jetzt mit den Zugangsdaten auf dem  Entwicklungsserver ein, die dir James gesendet hat (&#039;&#039;&#039;Entwickler-Nick&#039;&#039;&#039; und &#039;&#039;&#039;Entwickler-Passwort&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
  Tipp: Du kannst die Zugangsdaten aus James&#039; Nachricht mit Shift+Rechtsklick in das Chat-Fenster kopieren.&lt;br /&gt;
&lt;br /&gt;
=== MyChannel ===&lt;br /&gt;
&lt;br /&gt;
Nach dem Einloggen sollte sich automatisch das [[MyChannel]]-Edit Fenster öffnen. Ansonsten gib &#039;&#039;&#039;/mychannel&#039;&#039;&#039; ein.&amp;lt;br&amp;gt;&lt;br /&gt;
Du legst dir jetzt einen eigenen Channel an, in dem du gleich deine erste UserApp installieren wirst. Eine Info zu den Einstellungen erhältst du durch Klicken auf den Titel des jeweiligen Feldes. Außer über deinen Channel-Namen musst du dir aber erstmal keine Gedanken machen (du kannst dieses Fenster jederzeit wieder mit &#039;&#039;&#039;/mychannel&#039;&#039;&#039; öffnen). Drücke anschließend auf &#039;&#039;&#039;Speichern&#039;&#039;&#039; und &#039;&#039;&#039;Schließen&#039;&#039;&#039; und betritt deinen MyChannel mit &#039;&#039;&#039;/go &amp;lt;dein eigener Channel-Name&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Installation der UserApp ===&lt;br /&gt;
&lt;br /&gt;
Für dieses Tutorial haben wir dir schon Dateien für eine Beispiel-UserApp namens &amp;quot;HeyThere&amp;quot; auf den Server geladen. Installiere diese UserApp in deinem MyChannel mit &#039;&#039;&#039;/apps install HeyThere&#039;&#039;&#039;. Du kannst die UserApp später wieder aus deinem Channel löschen.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es müsste sich nun automatisch das Konfigurationsfenster für die UserApp geöffnet haben. Ansonsten öffne es selbst mit  &#039;&#039;&#039;/apps&#039;&#039;&#039; und klicke auf den Namen der UserApp (&amp;quot;HeyThere&amp;quot;).&lt;br /&gt;
  Hinweis: Durch einen Bug kann es sein, dass das Fenster auf dem Entwicklungs-Server nichts anzeigt. Schließe es einfach und öffne es gleich nochmal mit &#039;&#039;&#039;/apps&#039;&#039;&#039;. Wir hoffen, diesen Bug bald beheben zu können.&lt;br /&gt;
&lt;br /&gt;
Im Menüpunkt &amp;quot;AppBot&amp;quot; kannst du einen [[UserApp-Entwicklung/Doku/AppBot|AppBot]] erstellen und an deine UserApp binden. Ein AppBot ist ein bisschen wie [[James|Butler James]], nur eben für deine UserApp in deinem Channel. Drücke hierzu auf &amp;quot;hinzufügen&amp;quot; → &amp;quot;Nick anlegen&amp;quot;, denk dir einen Nicknamen aus und bestätige.&lt;br /&gt;
&lt;br /&gt;
Starte jetzt deine erste UserApp.&lt;br /&gt;
  Falls sich kein entsprechendes Fenster öffnet, starte die UserApp selbst, indem du im App-Menü auf &#039;&#039;&#039;aktivieren&#039;&#039;&#039; klickst.&lt;br /&gt;
Verlasse nun deinen Channel (indem du in einen anderen Channel gehst) und betritt ihn dann wieder (z.B. mit &#039;&#039;&#039;/go &amp;lt;dein eigener Channel-Name&amp;gt;&#039;&#039;&#039;). Dein AppBot sollte dich jetzt begrüßen!&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um mit dem Entwickeln zu starten, mach mit dem nächsten Schritt weiter (FTP-Setup). Du kannst auch schon mal einen Blick in die [http://developer.knuddels.de/docs/ UserApps-API-Dokumentation] werfen.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bestimmt wird es auch mal eine Stelle geben, an der du nicht weiter weißt. Zögere nicht, [http://forum.knuddels.de/ubbthreads.php?ubb=postlist&amp;amp;Board=272&amp;amp;page=1 im Forum] Fragen zu stellen, wenn dir etwas nicht klar ist! Die anderen Entwickler sind freundlich, gehen fair miteinander um und helfen sich gerne gegenseitig.&lt;br /&gt;
&lt;br /&gt;
== FTP-Setup ==&lt;br /&gt;
&lt;br /&gt;
Du benötigst für die UserApp-Entwicklung ein FTP-Programm, um die Dateien für deine UserApp auf die Server von Knuddels hochzuladen.&lt;br /&gt;
&lt;br /&gt;
=== Was ist eigentlich FTP? ===&lt;br /&gt;
&lt;br /&gt;
FTP (File Transfer Protocol) ist ein Protokoll, mit dem Daten zwischen zwei Computern im Internet ausgetauscht werden können.&amp;lt;br&amp;gt;&lt;br /&gt;
Zum Glück gibt es ganz einfache Programme, die hinter den Kulissen dieses Protokoll sprechen, sodass du die Dateien mit wenigen Klicks hochladen kannst.&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung des FTP-Zugangs ===&lt;br /&gt;
&lt;br /&gt;
Du wirst die Dateien deiner UserApp auf zwei verschiedenen Servern hochladen:&lt;br /&gt;
# auf dem &#039;&#039;&#039;Entwicklungs-Server&#039;&#039;&#039;, unter der URL &#039;&#039;&#039;devappupload.knuddels.de&#039;&#039;&#039;&lt;br /&gt;
# auf dem &#039;&#039;&#039;Live-Server&#039;&#039;&#039;, unter der URL &#039;&#039;&#039;appupload.knuddels.de&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Für beide Server musst du dir jeweils eine Verbindung einrichten. Dafür brauchst du ein FTP-Programm.&lt;br /&gt;
Schau dir dazu [https://bitbucket.org/knuddels/user-apps/wiki/Bootstrap/FTP-Setup diese Erklärung] an.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Diese Erklärung zeigt allerdings nur die Verbindung zum Live-Server&#039;&#039;&#039; - verwende für den Entwicklungs-Server stattdessen die URL &#039;&#039;&#039;devappupload.knuddels.de&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als Zugangsdaten verwendest du die Zugangsdaten, die James dir geschickt hat (&#039;&#039;&#039;FTP-Nutzer&#039;&#039;&#039; und &#039;&#039;&#039;FTP-Passwort&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
  Tipp: Du kannst die Zugangsdaten aus James&#039; Nachricht mit Shift+Rechtsklick in das Chat-Fenster kopieren.&lt;br /&gt;
  Unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039; kannst du sie außerdem erneut anfordern.&lt;br /&gt;
&lt;br /&gt;
Achte außerdem jeweils darauf, eine &#039;&#039;&#039;unverschlüsselte Verbindung&#039;&#039;&#039; zu wählen.&lt;br /&gt;
&lt;br /&gt;
== Beispiel-Code anschauen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du weißt, wie du Dateien über den FTP-Zugang von dem Server herunter- und hochladen kannst, kannst du dir jetzt anschauen, wie eine UserApp aufgebaut ist.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logge dich in deinem FTP-Programm auf dem Entwicklungs-Server ein, navigiere in den Ordner &#039;&#039;&#039;ftp → HeyThere&#039;&#039;&#039; und lade dort die Datei &#039;&#039;&#039;main.js&#039;&#039;&#039; herunter. Du kannst diese Datei jetzt anschauen, verändern und dann wieder dort hochladen. So verstehst du, wie alles funktioniert.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;main.js&#039;&#039;&#039; kannst du sogar im normalen Texteditor anschauen und bearbeiten.&amp;lt;br&amp;gt;&lt;br /&gt;
Empfehlenswert ist das aber nicht.&lt;br /&gt;
*Auf Windows kannst du dir (zum Beispiel) [http://notepad-plus-plus.org/ Notepad++] herunterladen.&lt;br /&gt;
* Auf macOS kannst du dir (zum Beispiel) [https://itunes.apple.com/de/app/textwrangler/id404010395?mt=12 Textwrangler] herunterladen.&lt;br /&gt;
Diese Programme können dir das Entwickeln erleichtern. (Natürlich kannst du auch eine IDE verwenden, wenn du dich damit auskennst.)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schau dir den Code jetzt an und nimm einige Veränderungen vor.&lt;br /&gt;
&lt;br /&gt;
  Idee: Lass deinen AppBot Besucher abhängig von ihrem Geschlecht begrüßen! Zum Beispiel männliche Besucher mit &amp;quot;Hey Prinz &amp;lt;Nickname&amp;gt;&amp;quot; und weibliche Besucher mit &amp;quot;Hey Prinzessin &amp;lt;Nickname&amp;gt;&amp;quot;. Findest du heraus, wie das geht?&lt;br /&gt;
&lt;br /&gt;
→ Jetzt ist ein guter Zeitpunkt, die [https://developer.knuddels.de/docs/ API-Dokumentation] anzuschauen.&lt;br /&gt;
Der Aufbau der &#039;&#039;&#039;main.js&#039;&#039;&#039; wird [https://bitbucket.org/knuddels/user-apps/wiki/Bootstrap/App-Erstellen hier] erklärt.&lt;br /&gt;
&lt;br /&gt;
Gehe danach folgendermaßen vor:&lt;br /&gt;
# Verändere die Datei und speichere sie.&lt;br /&gt;
# Lade die Datei auf den FTP-Server hoch (ersetze die alte &#039;&#039;&#039;main.js&#039;&#039;&#039;).&lt;br /&gt;
# Öffne das App-Menü in deinem Channel mit &#039;&#039;&#039;/apps&#039;&#039;&#039; und drücke auf &#039;&#039;&#039;update/restart&#039;&#039;&#039;. Deine App fährt herunter und startet nach wenigen Sekunden erneut - mit deinem neuen Code.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wird gezeigt, wie man Besucher abhängig von ihrem Geschlecht begrüßen kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Begrüße Besucher abhängig von ihrem Geschlecht ==&lt;br /&gt;
&lt;br /&gt;
So kannst du neuen Besuchern eine Begrüßungsnachricht abhängig von ihrem Geschlecht schicken:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;main.js&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;!-- schneller Workaround (&amp;lt;code&amp;gt; ist kaputt, whitespaces werden gestript): Leerzeichen durch &amp;amp;nbsp; ersetzen --&amp;gt;&lt;br /&gt;
&amp;lt;!-- in Python: print(&amp;quot;code() {...}&amp;quot;.replace(&amp;quot; &amp;quot;, &amp;quot;&amp;amp;nbsp;&amp;quot;)) --&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&amp;amp;nbsp;&amp;amp;nbsp;//&amp;amp;nbsp;diese&amp;amp;nbsp;Funktion&amp;amp;nbsp;wird&amp;amp;nbsp;aufgerufen,&amp;amp;nbsp;wenn&amp;amp;nbsp;ein&amp;amp;nbsp;Nutzer&amp;amp;nbsp;den&amp;amp;nbsp;Channel&amp;amp;nbsp;betritt&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;gender&amp;amp;nbsp;=&amp;amp;nbsp;user.getGender();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;nick&amp;amp;nbsp;&amp;amp;nbsp;=&amp;amp;nbsp;user.getNick();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;title;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(gender&amp;amp;nbsp;==&amp;amp;nbsp;Gender.Male)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;title&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Prinz&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;nick;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;if&amp;amp;nbsp;(gender&amp;amp;nbsp;==&amp;amp;nbsp;Gender.Female)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;title&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Prinzessin&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;nick;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;{&amp;amp;nbsp;&amp;amp;nbsp;//&amp;amp;nbsp;der&amp;amp;nbsp;Nutzer&amp;amp;nbsp;hat&amp;amp;nbsp;sich&amp;amp;nbsp;nicht&amp;amp;nbsp;als&amp;amp;nbsp;männlich&amp;amp;nbsp;oder&amp;amp;nbsp;weiblich&amp;amp;nbsp;ausgegeben&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;title&amp;amp;nbsp;=&amp;amp;nbsp;nick;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;message&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Hey&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;title&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;,&amp;amp;nbsp;willkommen&amp;amp;nbsp;im&amp;amp;nbsp;Channel!&amp;amp;nbsp;Du&amp;amp;nbsp;bist&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;user.getAge()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;Jahre&amp;amp;nbsp;alt.&amp;quot;;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(message);&amp;amp;nbsp;&amp;amp;nbsp;//&amp;amp;nbsp;der&amp;amp;nbsp;AppBot&amp;amp;nbsp;sendet&amp;amp;nbsp;eine&amp;amp;nbsp;private&amp;amp;nbsp;Nachricht&amp;amp;nbsp;an&amp;amp;nbsp;den&amp;amp;nbsp;Nutzer&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schaffst du es außerdem, die Besucher sowohl abhängig von ihrem Alter, als auch von ihrem Geschlecht zu begrüßen?   &lt;br /&gt;
→ Begrüße Besucher...&lt;br /&gt;
* unter 18 Jahren mit: &#039;&#039;&#039;&amp;quot;Hallo Junge &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;quot;Hallo Mädchen &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
* zwischen 18 und 60 Jahren mit: &#039;&#039;&#039;&amp;quot;Hallo Herr &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;quot;Hallo Frau &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
* über 60 Jahren mit: &#039;&#039;&#039;&amp;quot;Hallo Opa &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;quot;Hallo Oma &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Schau in die [https://developer.knuddels.de/docs/ UserApps-API-Dokumentation], wenn du eine Funktion suchst.&lt;br /&gt;
Den fertigen Code kannst du dir hier herunterladen: [https://bitbucket.org/knuddels/user-apps/downloads/Beispielcode%20HeyThere%20-%20Stufe%202%20-%20Erweiterung.zip Begrüßung nach Alter und Geschlecht]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt lernst du, wie Besucher &#039;&#039;&#039;Knuddel&#039;&#039;&#039; an deinen AppBot transferieren können!&lt;br /&gt;
&lt;br /&gt;
== Knuddel überweisen ==&lt;br /&gt;
&lt;br /&gt;
Nutzer können Knuddel an deinen AppBot überweisen. Diese Knuddel kannst du dir dann später auf deinen eigenen Nick überweisen lassen. Hier lernst du, wie du das in deiner UserApp machen kannst.&lt;br /&gt;
&lt;br /&gt;
Der AppBot soll jeden neuen Nutzer nach einem Knuddel fragen. Wenn er diesen bekommt, bedankt er sich bei dem Nutzer.&lt;br /&gt;
&lt;br /&gt;
  Auf dem Entwicklungs-Server hat dein Nick so viele Knuddel, dass du das einfach testen kannst.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;main.js&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;appBotNick&amp;amp;nbsp;=&amp;amp;nbsp;KnuddelsServer.getDefaultBotUser().getNick();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;message&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Gibst&amp;amp;nbsp;du&amp;amp;nbsp;mir&amp;amp;nbsp;_°BB°°&amp;gt;_heinen&amp;amp;nbsp;Knuddel|/appknuddel&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;appBotNick.escapeKCode()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;&amp;lt;°°°_?&amp;quot;;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(message);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onKnuddelReceived&amp;amp;nbsp;=&amp;amp;nbsp;function(sender,&amp;amp;nbsp;receiver,&amp;amp;nbsp;knuddelAmount,&amp;amp;nbsp;transferReason)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;sender.sendPrivateMessage(&amp;quot;Danke,&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;sender.getNick()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;!&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erklärung: Was ist KCode? ===&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;App.onUserJoined&#039;&#039;&#039; wird dem Nutzer eine Nachricht mit seltsamen Zeichen gesendet:  &lt;br /&gt;
&lt;br /&gt;
  &amp;quot;Gibst du mir _°BB°°&amp;gt;_heinen Knuddel|/appknuddel &amp;quot; + appBotNick.escapeKCode() + &amp;quot;&amp;lt;°°°_?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das ist [[Formatierungen|KCode]]. Dieser Code wird vor dem Anzeigen umgewandelt, sodass die Nutzer einen Link präsentiert bekommen, auf dessen Klick hin ein Befehl ausgeführt wird: Hier ist dieser Befehl &#039;&#039;&#039;/appknuddel &amp;lt;Nickname des AppBots&amp;gt;&#039;&#039;&#039;. Mit dem Klicken auf den Link überweist der Nutzer also einen Knuddel an den AppBot.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;appBotNick.escapeKCode()&#039;&#039;&#039; dient dazu, dass der Befehl auch bei Sonderzeichen im Nicknamen deines AppBots richtig ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
[[Formatierungen|→ Hier kannst du dir anschauen, wie KCode funktioniert.]]&lt;br /&gt;
&lt;br /&gt;
  Idee für wahre Kapitalisten: Du kannst den Besucher deines Channels vielleicht dazu bringen, dem AppBot einen Knuddel zu schenken, wenn der AppBot dem Besucher nach einiger Zeit eine traurige Nachricht schreibt, falls er bis dahin keinen Knuddel von dem Besucher erhalten hat.&lt;br /&gt;
&lt;br /&gt;
Eine mögliche Lösung dieses Problems kannst du dir hier anschauen: [https://bitbucket.org/knuddels/user-apps/downloads/Beispielcode%20HeyThere%20-%20Stufe%203%20-%20Erweiterung.zip Download Code-Beispiel (Traurige Nachricht vom AppBot)]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt lernst du, wie du dauerhaft Daten über deine Besucher speichern kannst.&lt;br /&gt;
&lt;br /&gt;
== UserPersistence: Nutzerdaten speichern ==&lt;br /&gt;
&lt;br /&gt;
Wenn du dir beispielsweise dauerhaft merken willst, wie viele Knuddel ein Nutzer jeweils schon deinem AppBot überwiesen hat, brauchst du eine Möglichkeit, zu jedem Nutzer eine Zahl zu speichern.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  Allerdings kannst du nicht einfach eine Variable in deinem Code haben, worüber du alles speicherst - das wäre nämlich mit jedem Neustart der App wieder weg.&lt;br /&gt;
&lt;br /&gt;
In der [https://developer.knuddels.de/docs/ UserApps-API] gibt es genau dafür das Objekt [https://developer.knuddels.de/docs/classes/UserPersistence.html UserPersistence].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;main.js&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;userPersistence&amp;amp;nbsp;=&amp;amp;nbsp;user.getPersistence();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;userSpending&amp;amp;nbsp;=&amp;amp;nbsp;userPersistence.getNumber(&amp;quot;spending&amp;quot;,&amp;amp;nbsp;0);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(userSpending&amp;amp;nbsp;&amp;gt;&amp;amp;nbsp;10)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(&amp;quot;Willkommen,&amp;amp;nbsp;gütiger&amp;amp;nbsp;Spender!&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;appBotNick&amp;amp;nbsp;=&amp;amp;nbsp;KnuddelsServer.getDefaultBotUser().getNick();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;message&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Gibst&amp;amp;nbsp;du&amp;amp;nbsp;mir&amp;amp;nbsp;_°BB°°&amp;gt;_heinen&amp;amp;nbsp;Knuddel|/appknuddel&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;appBotNick.escapeKCode()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;&amp;lt;°°°_?&amp;quot;;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(message);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onKnuddelReceived&amp;amp;nbsp;=&amp;amp;nbsp;function(sender,&amp;amp;nbsp;receiver,&amp;amp;nbsp;knuddelAmount,&amp;amp;nbsp;transferReason)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;sender.sendPrivateMessage(&amp;quot;Danke,&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;sender.getNick()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;userPersistence&amp;amp;nbsp;=&amp;amp;nbsp;sender.getPersistence();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;userPersistence.addNumber(&amp;quot;spending&amp;quot;,&amp;amp;nbsp;knuddelAmount.asNumber());&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die App merkt sich nun, wie viele Knuddel deine Besucher bereits eingezahlt haben. Besonders gönnerische Besucher begrüßt er ehrerbietig!&lt;br /&gt;
&lt;br /&gt;
== Dein Fortschitt ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Du bist schon weit gekommen!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Du hast gelernt, wie man sich auf dem Entwicklungs-Server anmeldet und eine App installiert.&lt;br /&gt;
* Du hast dich mit FTP vertraut gemacht und kannst deine Dateien jetzt einfach an den Knuddels-Server senden.&lt;br /&gt;
* Du weißt jetzt, wie man auf verschiedene Events in deinem Channel reagiert.&lt;br /&gt;
* Du bist mit der Überweisung von Knuddel an deinen AppBot vertraut.&lt;br /&gt;
* Du kannst Daten über deine Besucher dauerhaft speichern.&lt;br /&gt;
&lt;br /&gt;
Jetzt kannst du deine UserApp mal veröffentlichen! Dazu musst du deine UserApp per FTP auf dem Live-Server hochladen - so wie schon vorher auf dem Entwicklungs-Server. Melde dich dann ganz normal bei Knuddels an und installiere deine UserApp mit &#039;&#039;&#039;/apps install &amp;lt;UserApp-Name&amp;gt;&#039;&#039;&#039; in deinem MyChannel.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und wenn du jetzt noch deinen MyChannel unter &#039;&#039;&#039;/mychannel&#039;&#039;&#039; veröffentlichst, können auch andere Nutzer zufällig auf deinen MyChannel stoßen.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wie geht&#039;s weiter? ==&lt;br /&gt;
&lt;br /&gt;
Vielleicht hast du Lust, ein grafisches Spiel zu programmieren? Oder ein textbasiertes RPG?&amp;lt;br&amp;gt;&lt;br /&gt;
Ab jetzt bist du dir selbst überlassen - und kannst dich natürlich jederzeit an die Community wenden.&amp;lt;br&amp;gt;&lt;br /&gt;
Auf dem Entwickler-Portal [https://developer.knuddels.de/ developer.knuddels.de] findest du das meiste im Zusammenhang mit UserApps.&lt;br /&gt;
&lt;br /&gt;
[[UserApp-Entwicklung|→ Übersicht: UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Doku/AppBot&amp;diff=128150</id>
		<title>UserApp-Entwicklung/Doku/AppBot</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Doku/AppBot&amp;diff=128150"/>
		<updated>2019-07-22T16:58:16Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Die Seite wurde neu angelegt: „== Allgemeines ==  Ein AppBot ist ein Account bei Knuddels, der nicht von einer Person, sondern von einer UserApp gesteuert wird. Die UserApp kann…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Ein AppBot ist ein Account bei Knuddels, der nicht von einer Person, sondern von einer [[User_App|UserApp]] gesteuert wird. Die UserApp kann bestimmte Aktionen auslösen, beispielsweise das Senden einer Nachricht oder das Überweisen von [[Knuddel]].&lt;br /&gt;
Jede UserApp benötigt einen AppBot. In der Regel registriert der Channelbesitzer einen AppBot beim Installieren der entsprechenden UserApp (→ [[UserApp-Entwicklung/Tutorials/Beginner|Beginner-Tutorial]]).&lt;br /&gt;
&lt;br /&gt;
== Nickname ==&lt;br /&gt;
&lt;br /&gt;
Du kannst dem AppBot jeden beliebigen Namen geben (solange er noch nicht vergeben ist), aber es ist für die Nutzer deiner UserApp deutlich angenehmer, wenn du dich dabei am Namen des MyChannels oder der UserApp orientierst.&lt;br /&gt;
&lt;br /&gt;
== Profilbild ==&lt;br /&gt;
&lt;br /&gt;
Als Ersteller eines AppBots ist es möglich, das Profilbild des AppBots zu ändern.&amp;lt;br&amp;gt;&lt;br /&gt;
→ [[UserApp-Entwicklung/Tutorials/AppBot-Profilbild|Tutorial: AppBot-Profilbild]]&lt;br /&gt;
&lt;br /&gt;
== Weiterführende Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://bitbucket.org/knuddels/user-apps/wiki/AppBotBinden Wie binde ich einen AppBot?]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128149</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128149"/>
		<updated>2019-07-22T16:45:21Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Tutorial verlinkt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Für Anfänger ==&lt;br /&gt;
Lerne Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Einstieg]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/HTML-UI|HTML-UI (grafische Oberfläche)]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/UserApps_teilen|UserApps installieren und freigeben]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Newsletter-Versand|Newsletter-Versand]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/AppBot-Profilbild|AppBot-Profilbild]]&lt;br /&gt;
&lt;br /&gt;
== Für Fortgeschrittene ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Es gibt leider noch keine Tutorials für Fortgeschrittene.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Du kannst dich auf Discord an fortgeschrittene UserApp-Entwickler wenden. Den Link zum Discord-Channel findest du unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[User_Apps/Tutorial|Hallo Welt]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Meta ==&lt;br /&gt;
&lt;br /&gt;
Tutorial über das Schreiben von UserApp-Tutorials: [[UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta|UserApp-Tutorials-Meta]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/AppBot-Profilbild&amp;diff=128148</id>
		<title>UserApp-Entwicklung/Tutorials/AppBot-Profilbild</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/AppBot-Profilbild&amp;diff=128148"/>
		<updated>2019-07-22T16:36:31Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Die Seite wurde neu angelegt: „== Einführung ==  Das Profilbild deines AppBots sieht standardmäßig ziemlich unoriginell aus. Aber wenn du beispielsweis…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einführung ==&lt;br /&gt;
&lt;br /&gt;
Das Profilbild deines [[UserApp-Entwicklung/Doku/AppBot|AppBots]] sieht standardmäßig ziemlich unoriginell aus. Aber wenn du beispielsweise deinen AppBot Besuchern [https://developer.knuddels.de/docs/classes/User.html#method_sendPrivateMessage Privatnachrichten] schicken lässt, möchtest du wahrscheinlich, dass dein AppBot ein eigenes Profilbild hat. Das ist auch möglich!&lt;br /&gt;
&lt;br /&gt;
== Bild erstellen ==&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu Profilbildern normaler Nutzer muss auf dem Profilbild eines AppBots keine Person abgebildet sein. Ansonsten gelten hier aber [https://www.knuddels.de/info/foto-rules.html die selben Regeln wie für Profilbilder normaler Nutzer].&lt;br /&gt;
&lt;br /&gt;
== Passwort für den AppBot ==&lt;br /&gt;
&lt;br /&gt;
Du weißt das Passwort deines AppBots zunächst nicht. Allerdings kannst du es neu setzen, da der AppBot mit der selben E-Mail-Adresse registriert ist wie dein Hauptnick. Geh also auf [https://www.knuddels.de www.knuddels.de], klicke auf &#039;&#039;Passwort vergessen&#039;&#039;, gib den Nick deines AppBots ein und bestätige. Jetzt solltest du eine E-Mail erhalten und kannst ein neues Passwort wählen.&lt;br /&gt;
&lt;br /&gt;
== Profilbild hochladen ==&lt;br /&gt;
&lt;br /&gt;
Das Bild muss im &#039;&#039;&#039;.jpg&#039;&#039;&#039;- oder &#039;&#039;&#039;.gif&#039;&#039;&#039;-Format vorliegen, damit du es hochladen kannst.&lt;br /&gt;
&lt;br /&gt;
Logge dich jetzt in der Fotogalerie unter [https://photo.knuddels.de/photos-login.html photo.knuddels.de] mit dem Nick und dem Passwort deines AppBots ein und lade dort das Bild hoch.&lt;br /&gt;
&lt;br /&gt;
Fertig!&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=User_Apps&amp;diff=128147</id>
		<title>User Apps</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=User_Apps&amp;diff=128147"/>
		<updated>2019-07-22T15:02:19Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: verständlichere Einleitung, eigener Abschnitt für &amp;quot;Geschichte&amp;quot;, kleinere Verbesserungen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NN}}&lt;br /&gt;
&lt;br /&gt;
==Allgemeines==&lt;br /&gt;
&lt;br /&gt;
UserApps sind von Nutzern geschriebene Programme, die in [[MyChannel]]n laufen. Das können zum Beispiel Spiele oder hilfreiche Tools für [[Channelmoderator]]en sein. Nicht jede UserApp muss einen grafischen Teil haben, sie kann auch ausschließlich über den Chat laufen.&amp;lt;br&amp;gt;&lt;br /&gt;
Jeder Nutzer kann selbst UserApps entwickeln, sobald er den Status [[Familymitglied]] erreicht. Die [[UserApp-Entwicklung]] ist wiederum ein eigener Teil des Knuddels-Wikis. Dort gibt es zum Beispiel [[UserApp-Entwicklung/Tutorials|Tutorials für Anfänger und Fortgeschrittene]].&lt;br /&gt;
&lt;br /&gt;
== Geschichte ==&lt;br /&gt;
&lt;br /&gt;
Am [[2014|24.12.2014]] stellte [[Ironist]] im Forum die Beta-Phase der UserApps vor. Hierbei handelt es sich um Spiele oder Features, welche von Chattern entwickelt  und dann bei Knuddels integriert werden können. Diese Apps lassen sich dann in verschiedenen [[MyChannel]]n verwenden. In der Beta-Phase wurden zwölf Apps vorgestellt.&lt;br /&gt;
&lt;br /&gt;
Seit dem [[2015|17.09.2015]] ist es jedem [[Familymitglied]] im deutschen Knuddels-Chat, möglich, eigene UserApps zu entwickeln.&lt;br /&gt;
&lt;br /&gt;
Seit Dezember [[2015]] gibt es sogenannte Entwickler-Coaches. Diese helfen den UserApp-Entwicklern bei Fragen und/oder Problemen mit den UserApps. Außerdem halten die Coaches regelmäßig [[Entwicklertreffen]] im Channel [[Channel:App Entwickler|App Entwickler]] ab. Neben Neuigkeiten die dort vorgestellt werden, haben alle Anwesenden auch die Möglichkeiten Fragen zu stellen und eigene Ideen wie auch Verbesserungsvorschläge einzubringen.&lt;br /&gt;
&lt;br /&gt;
== Voraussetzungen ==&lt;br /&gt;
&lt;br /&gt;
Es gelten folgende Voraussetzungen, um UserApp-Entwickler zu werden:&lt;br /&gt;
&lt;br /&gt;
* [[Familymitglied]] werden&lt;br /&gt;
* [[TAN-System]] aktivieren&lt;br /&gt;
* [[E-Mail-Verifikation|E-Mail-Adresse verifizieren]]&lt;br /&gt;
* [[Entwickler-AGB]] akzeptieren&lt;br /&gt;
&lt;br /&gt;
Diese Liste kann mit &#039;&#039;&#039;/apps developer&#039;&#039;&#039; im Chat angezeigt werden. Nachdem dort alle Kriterien erfüllt wurden, muss erneut &#039;&#039;&#039;/apps developer&#039;&#039;&#039; eingegeben werden. Daraufhin sendet James die notwendigen Informationen, um mit der Entwicklung beginnen zu können.&lt;br /&gt;
&lt;br /&gt;
==Installation einer User App von einem Entwickler==&lt;br /&gt;
Sobald ein User eine eigene App entwickelt hat, kann er diese für einzelne, mehrere oder gar für alle User freischalten. Sobald der Entwickler die App selber auf dem Server installiert hat, kann er die benötigten Daten zum Installieren an die Interessenten weitergeben. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Folgende Daten werden vom Entwickler benötigt:&lt;br /&gt;
* FTP Benutzername&lt;br /&gt;
* AppName / Ordername&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion, mit der man die App dann installieren kann, sieht wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;function&amp;gt;/apps install knuddelsDEV.ftpUserName.appName&amp;lt;/function&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Verwendbare Apps==&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name der App&lt;br /&gt;
! MyChannel&lt;br /&gt;
! Entwickler&lt;br /&gt;
! Kategorie&lt;br /&gt;
! MyChannel-Installation freigegeben?&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:2Ways|2Ways]]&lt;br /&gt;
| [[Channel:WürfelWunder|/Würfelwunder]]&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:App Entwickler|App Entwickler]]&lt;br /&gt;
| [[Channel:App Entwickler|/App Entwickler]] &lt;br /&gt;
| [[Ironist]]&lt;br /&gt;
| Newsletter&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Alles oder Nichts|Alles oder Nichts]]&lt;br /&gt;
| [[Channel:Alles oder Nichts|/Alles oder Nichts]]&lt;br /&gt;
| Dave20009&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Besserwisser|Besserwisser]]&lt;br /&gt;
| [[Channel:Besserwisser|/Besserwisser]]&lt;br /&gt;
| DerNeuanfang, Maexxchen&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Bingo Event|Bingo Event]]&lt;br /&gt;
| [[Channel:DiceSky|/DiceSky]]&lt;br /&gt;
[[Channel:Veranstaltung|/Veranstaltung]]&lt;br /&gt;
| Vampiric Desire&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Blitz!|Blitz!]]&lt;br /&gt;
| [[Channel:Blitz|/Blitz]]&lt;br /&gt;
| Spectra&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Braintainment|Braintainment]]&lt;br /&gt;
| [[Channel:Braintainment|/Braintainment]] &lt;br /&gt;
| IgelchenM&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Catch the Pandas|Catch the Pandas]]&lt;br /&gt;
| [[Channel:777|/777]]&lt;br /&gt;
| Kev777&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:ChannelControl|ChannelControl]]&lt;br /&gt;
| [[Channel:ChannelControl|/ChannelControl]]&lt;br /&gt;
| W a n n a b e - M o d e l&lt;br /&gt;
| Tool&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:ChannelHelper|ChannelHelper]]&lt;br /&gt;
| [[Channel:ChannelHelper|/ChannelHelper]]&lt;br /&gt;
| rmpg&lt;br /&gt;
| Tool&lt;br /&gt;
| Ja&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Chooso|Chooso]]&lt;br /&gt;
| [[Channel:Chooso|/Chooso]]&lt;br /&gt;
| J&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:ChannelMaster|ChannelMaster]]&lt;br /&gt;
| [[Channel:ChannelMaster|/ChannelMaster]]&lt;br /&gt;
| Vampiric Desire&lt;br /&gt;
| Tool&lt;br /&gt;
| Ja&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Chuck a Luck|Chuck a Luck]]&lt;br /&gt;
| -&lt;br /&gt;
| DNA 328 &lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:CrashFly|CrashFly]]&lt;br /&gt;
| [[Channel:CrashFly|/CrashFly]]&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:D&amp;amp;S Searchbox v2|D&amp;amp;S Searchbox v2]]&lt;br /&gt;
| [[Channel:Dom&amp;amp;Sub|/Dom&amp;amp;Sub]]&lt;br /&gt;
| SchlechteOnkelz&lt;br /&gt;
| Tool&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Darts|Darts]]&lt;br /&gt;
| [[Channel:Würfelwunder|/Würfelwunder]]&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Dice-o-mat|Dice-o-mat]]&lt;br /&gt;
| [[Channel:777|/777]]&lt;br /&gt;
| Kev777&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:DiceSkyV2|DiceSky]]&lt;br /&gt;
| [[Channel:DiceSky|/DiceSky]]&lt;br /&gt;
| Vampiric Desire&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Down|Down]]&lt;br /&gt;
| [[Channel:WürfelWunder|/WürfelWunder]]&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:EventSystem|EventSystem]]&lt;br /&gt;
| -&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Tool&lt;br /&gt;
| Ja&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Fivel|Fivel]]&lt;br /&gt;
| [[Channel:WürfelWunder|/WürfelWunder]]&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:FlappyKnuddel|FlappyKnuddel]]&lt;br /&gt;
| [[Channel:Flappy|/Flappy]]&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Fun|Fun]]&lt;br /&gt;
| [[Channel:Abenteuer18|/Abenteuer18]]&lt;br /&gt;
|&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Funny 7|Funny 7]]&lt;br /&gt;
| -&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Glücksrad (das TV-Quiz)|Glücksrad (das TV-Quiz)]]&lt;br /&gt;
| -&lt;br /&gt;
| Enrico-nrp&lt;br /&gt;
| Spiel&lt;br /&gt;
| Keine Information&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Glücksspiel|Glücksspiel]]&lt;br /&gt;
| -&lt;br /&gt;
| xz&lt;br /&gt;
| Spiel&lt;br /&gt;
| Keine Information&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Greedypiglet|Greedypiglet]]&lt;br /&gt;
| [[Channel:777|/777]]&lt;br /&gt;
| Kev777&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Hangman 2|Hangman 2]]&lt;br /&gt;
| -&lt;br /&gt;
| Enrico-nrp&lt;br /&gt;
| Spiel&lt;br /&gt;
| Keine Information&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Hau den Sidoh|Hau den Sidoh]]&lt;br /&gt;
| [[Channel:ParaDICE|/ParaDICE]]&lt;br /&gt;
| Vampiric Desire&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[HighOrLow]]&lt;br /&gt;
| -&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Keine Information&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Hit|Hit]]&lt;br /&gt;
| -&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Keine Information&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Hundred|Hundred]]&lt;br /&gt;
| [[Channel:WürfelWunder|/WürfelWunder]]&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:HZM-App|HZM-App]]&lt;br /&gt;
| -&lt;br /&gt;
| Pega16&lt;br /&gt;
| Tool&lt;br /&gt;
| Ja&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Ich hab noch nie|Ich hab noch nie]]&lt;br /&gt;
| [[Channel:Ich hab noch nie|/Ich hab noch nie]]&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Jukebox|Jukebox]]&lt;br /&gt;
| -&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| Keine Information&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Jumpo!|Jumpo!]]&lt;br /&gt;
| -&lt;br /&gt;
| Inuyasha20&lt;br /&gt;
| Spiel&lt;br /&gt;
| Keine Information&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Knuddelonia|Knuddelonia]]&lt;br /&gt;
| [[Channel:Knuddelonia|/Knuddelonia]]&lt;br /&gt;
| martin070476&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Knuddels Adventure|Knuddels Adventure]]&lt;br /&gt;
| [[Channel:Knuddels Adventure|/Knuddels Adventure]]&lt;br /&gt;
| Finomosec&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Knuddels-Wiki|Knuddels-Wiki]]&lt;br /&gt;
| [[Channel:Knuddels-Wiki|/Knuddels-Wiki]]&lt;br /&gt;
| Gery123&lt;br /&gt;
| Sonstiges&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Knudon|Knudon]]&lt;br /&gt;
| [[Channel:Knudon|/Knudon]]&lt;br /&gt;
| J&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Knuffel|Knuffel]]&lt;br /&gt;
| [[Channel:Knuffel|/Knuffel]]&lt;br /&gt;
| TobyB&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:KopfTrainer|KopfTrainer]]&lt;br /&gt;
| [[Channel:KopfTrainer|/KopfTrainer]]&lt;br /&gt;
| MarvinDerPraktikant&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Landreise|Landreise]]&lt;br /&gt;
| [[Channel:Landreise|/Landreise]]&lt;br /&gt;
| Vampiric Desire&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Lucky7|Lucky7]]&lt;br /&gt;
| [[Channel:Casino Knuddels|/Casino Knuddels]]&lt;br /&gt;
| Vampiric Desire&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Memory|Memory]]&lt;br /&gt;
| [[Channel:Memory|/Memory]]&lt;br /&gt;
| IgelchenM &lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:MiniSlot|MiniSlot]]&lt;br /&gt;
| -&lt;br /&gt;
| rmpg&lt;br /&gt;
| Spiel&lt;br /&gt;
| Ja&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Need for Speed|Need for Speed]]&lt;br /&gt;
| [[Channel:Need for Speed|/Need for Speed]]&lt;br /&gt;
| Weißer drache 007&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:NiJaSin|NiJaSin]]&lt;br /&gt;
| [[Channel:NiJaSin|/NiJaSin]]&lt;br /&gt;
| DerNeuanfang &lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:OR-Radio|OR-Radio]]&lt;br /&gt;
| [[Channel:or radio|/or radio]]&lt;br /&gt;
| SchlechteOnkelz&lt;br /&gt;
| Sonstiges&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Panzerknacker|Panzerknacker]]&lt;br /&gt;
| [[Channel:777|/777]]&lt;br /&gt;
| Kev777&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:ProMailer|ProMailer]]&lt;br /&gt;
| -&lt;br /&gt;
| Dreamboy-1996 &amp;lt;3&lt;br /&gt;
| Tool&lt;br /&gt;
| Ja&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Quatsch+|Quatsch+]]&lt;br /&gt;
| [[Channel:eXilant|/eXilant]]&lt;br /&gt;
| eXilant&lt;br /&gt;
| Tool/Spaß&lt;br /&gt;
| Ja&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Roulette American|Roulette American]]&lt;br /&gt;
| [[Channel:777|/777]]&lt;br /&gt;
| Kev777&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Raum der Wünsche|Raum der Wünsche]]&lt;br /&gt;
| [[Channel:Raum der Wünsche|/Raum der Wünsche]]&lt;br /&gt;
| DdvOiD&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:SpecialForces|SpecialForces]]&lt;br /&gt;
| [[Channel:Summer|/Summer]]&lt;br /&gt;
| Dave20009&lt;br /&gt;
| Tool&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:SidohCasino V2|SidohCasino V2]]&lt;br /&gt;
| [[Channel:SidohCasino|/SidohCasino]]&lt;br /&gt;
| rmpg&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:SkyJump|SkyJump]]&lt;br /&gt;
| [[Channel:SkyJump|/SkyJump]]&lt;br /&gt;
| IgelchenM &lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Snake|Snake]]&lt;br /&gt;
| [[Channel:SnakeGame|/SnakeGame]]&lt;br /&gt;
| Dreamboy-1996 &amp;lt;3&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Soccer|Soccer]]&lt;br /&gt;
| -&lt;br /&gt;
| J&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:SpaceKnuddelz|SpaceKnuddelz]]&lt;br /&gt;
| [[Channel:SpaceKnuddelz|/SpaceKnuddelz]]&lt;br /&gt;
| Plex&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:SpeedKnuffel|SpeedKnuffel]]&lt;br /&gt;
| [[Channel:SpeedKnuffel|/SpeedKnuffel]]&lt;br /&gt;
| TobyB&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Spot It|Spot It]]&lt;br /&gt;
| [[Channel:Spot It|/Spot It]]&lt;br /&gt;
| Vampiric Desire&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Spotlight|Spotlight]]&lt;br /&gt;
| [[Channel:Matratzensport|/Matratzensport]]&lt;br /&gt;
| Vampiric Desire&lt;br /&gt;
| sonstiges&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Stardust|Stardust]]&lt;br /&gt;
| [[Channel:777|/777]]&lt;br /&gt;
| Kev777&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Sudoku|Sudoku]]&lt;br /&gt;
| [[Channel:Sudoku|/Sudoku]]&lt;br /&gt;
| Ironist&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Sudoku Color|Sudoku Color]]&lt;br /&gt;
| [[Channel:Sudoku Color|/Sudoku Color]]&lt;br /&gt;
| Vampiric Desire&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Supercode|Supercode]]&lt;br /&gt;
| [[Channel:777|/777]]&lt;br /&gt;
| Kev777&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Tarot|Tarot]]&lt;br /&gt;
| [[Channel:Biss des Bösen|/Biss des Bösen]]&lt;br /&gt;
| denniscrazy&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Knutris|Knutris]]&lt;br /&gt;
| [[Channel:Knutris|/Knutris]]&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Tetris|Tetris]]&lt;br /&gt;
| -&lt;br /&gt;
| xz&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Three of a Kind|Three of a Kind]]&lt;br /&gt;
| [[Channel:777|/777]]&lt;br /&gt;
| Kev777&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Tic Tac Toe|Tic Tac Toe]]&lt;br /&gt;
| -&lt;br /&gt;
| xz&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Triple|Triple]]&lt;br /&gt;
| [[Channel:WürfelWunder|/WürfelWunder]]&lt;br /&gt;
| djchrisnet&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:Verrückte Worte|Verrückte Worte]]&lt;br /&gt;
| [[Channel:Verrückte Worte|/Verrückte Worte]]&lt;br /&gt;
| Pralinenfan&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|-&lt;br /&gt;
| [[User App:World of Knuddelonia|World of Knuddelonia]]&lt;br /&gt;
| [[Channel:World of Knuddelonia|/World of Knuddelonia]]&lt;br /&gt;
| martin070476&lt;br /&gt;
| Spiel&lt;br /&gt;
| Nein&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Weiterführende Informationen==&lt;br /&gt;
* [[/apps]] - Informationen zur Funktion&lt;br /&gt;
* [[/h appbot]] - Chathilfe zum App-Bot&lt;br /&gt;
* [[Apps-Team]] - Informationen zum Apps-Team&lt;br /&gt;
* [[App Manager]] - Informationen zum App Manager&lt;br /&gt;
&lt;br /&gt;
==Weblinks==&lt;br /&gt;
* [http://forum.knuddels.de/ubbthreads.php?ubb=showflat&amp;amp;Number=2708654#Post2708654 www.knuddels.de/forum] - Ankündigung der Apps von Ironist im Forum und Links zu den Vorstellungen der einzelnen Apps&lt;br /&gt;
* [http://developer.knuddels.de/docs www.developer.knuddels.de] - Aktuelle Version der Knuddels-Apps-API für Entwickler&lt;br /&gt;
* [http://www.knuddels.de/#/channels/nutzer-apps www.knuddels.de/#/channels/nutzer-apps] - Channelübersicht der aktuellen Nutzer-App-Channel&lt;br /&gt;
* [https://knuddelsapi.wordpress.com/2015/12/06/interview-holgi-2015-12/ knuddelsapi.wordpress.com] - &amp;quot;Holgi – Ein Blick zurück und ein Blick in die Glaskugel&amp;quot; (Interview, veröffentlicht 06.12.2015)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Begriffserklärung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Entwickler-AGB&amp;diff=128146</id>
		<title>Entwickler-AGB</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Entwickler-AGB&amp;diff=128146"/>
		<updated>2019-07-22T14:46:20Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Disclaimer hinzugefügt (Hinweis auf Chatbefehl)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines ==&lt;br /&gt;
Die &#039;&#039;&#039;Entwickler-AGB&#039;&#039;&#039; müssen von jedem App-Entwickler akzeptiert werden, um eigene [[User App]]s erstellen zu können.&amp;lt;br&amp;gt;&lt;br /&gt;
Achtung: Die aktuellste Version der Entwickler-AGB findest du, wenn du im Chat &#039;&#039;&#039;/apps AGB&#039;&#039;&#039; eingibst.&lt;br /&gt;
&lt;br /&gt;
===Präambel===&lt;br /&gt;
Die Knuddels GmbH &amp;amp; Co. KG, Erbprinzenstr. 27, 76133 Karlsruhe (nachfolgend &amp;quot;Knuddels&amp;quot; genannt) betreibt die Internet-Chat-Portale Knuddels.de und Knuddels.at. Auf diesen Plattformen gibt Knuddels seinen Nutzern die Möglichkeit, eigene Programme zu erstellen (sogenannte Apps), die im Chat genutzt werden können. Die Ersteller dieser Apps (im Weiteren „Entwickler“ genannt) haben die Möglichkeit, die Apps selbst zu nutzen und/oder an andere Nutzer weiterzugeben bzw. von diesen nutzen zu lassen. Die nachfolgenden allgemeinen Geschäftsbedingungen regeln die Bedingungen, unter denen die Entwickler von Apps diese bei Knuddels einpflegen können.&lt;br /&gt;
===§ 1 Erstellung von Apps===&lt;br /&gt;
a)     Die für den Chat von Knuddels entwickelte Software darf nur dann Drittsoftware oder Teile eines von Dritten erstellten Quellcodes enthalten, an denen Dritte Urheberrecht haben, wenn die berechtigten Dritten einer solchen Nutzung im Einzelfall oder allgemein zugestimmt haben. Trotz Zustimmung des berechtigten Dritten dürfen von Dritten erstellte Teile eines Quellcodes bzw. Drittsoftware etc. nicht genutzt werden, wenn der Dritte für die Einräumung von Rechten an seinem Werk eine Gegenleistung verlangt, die von Knuddels zu erbringen wäre.&lt;br /&gt;
b)     In der erstellten App dürfen keinerlei Sounds, Grafiken oder andere Werke von dritten Personen genutzt werden, die nicht ausdrücklich ihr Einverständnis für diese Nutzung gegeben haben.&lt;br /&gt;
c)     Damit die App bei Knuddels genutzt werden kann, ist diese an Knuddels zu übermitteln. Dabei ist auch der Quellcode sowie sämtlich genutzten Grafiken, Sounds oder Datenbanken an Knuddels zu übermitteln.&lt;br /&gt;
d)     Der Entwickler hat keinen Anspruch darauf, dass die von ihm erstellte App auch tatsächlich auf einer Knuddels-Plattform veröffentlicht wird. Knuddels behält sich ausdrücklich vor, nach Prüfung eine übermittelte App nicht zu veröffentlichen.&lt;br /&gt;
===§ 2 Inhalte von Apps===&lt;br /&gt;
Die erstellten Apps dürfen nachfolgende Inhalte nicht enthalten:&lt;br /&gt;
a)     Pornografie oder explizite sexuelle Inhalte&lt;br /&gt;
b)     Die Veranstaltung von Glücksspielen gegen Einsatz von Geld oder geldwerten Vorteilen, Leistungen oder Gegenständen.&lt;br /&gt;
c)     Aufforderungen oder Bitten um Geldzahlungen oder Überlassung von geldwerten Vorteilen, Leistungen oder Gegenständen außerhalb eines Bezahlsystems, das durch Knuddels bereitgestellt wird.&lt;br /&gt;
d)     Inhalte aus Affiliate-Programmen,&lt;br /&gt;
e)     Verherrlichende Gewaltdarstellungen&lt;br /&gt;
f)     Darstellungen, die bestimmte Personengruppen diskriminieren, sei es aufgrund ihrer Rasse, ethnischen Herkunft, Religion, Behinderung, Geschlechts, Alters der sexueller Orientierung bzw. geschlechtlicher Identität oder anderer Gründe&lt;br /&gt;
g)     Wahrheitswidrige Angaben des Entwicklers zu seiner Identität bzw. der Zugehörigkeit zu einer Firma, Organisation, einem Verein oder andere Personengruppe.&lt;br /&gt;
h)     Inhalte, die Schutzrechte Dritter, insbesondere Patent-, Marken- oder Urheberrechte verletzen.&lt;br /&gt;
i)     Private Daten Dritter ohne deren ausdrückliche Zustimmung&lt;br /&gt;
j)     Inhalte, die gegen geltendes Recht der Bundesrepublik Deutschland verstoßen&lt;br /&gt;
k)     Schadinhalte, bzw. Inhalte, die Schadsoftware wie Viren oder Trojaner verbreiten und/oder Soft- oder Hardware auf dem Rechner des Nutzers bzw. Server von Knuddels beschädigen, löschen etc. oder Daten des Nutzers oder von Knuddels gegen bzw. ohne dessen Willen ausspähen und/oder verbreiten.&lt;br /&gt;
l)     Kommerzielle Werbung jeglicher Art&lt;br /&gt;
m)     Irreführende Inhalte, die den Eindruck beim Nutzer erwecken, dass eine ganz bestimmte Aktion z.B. durch eine Eingabe des Nutzers hervorgerufen wird, wenn aber tatsächlich hierdurch eine andere Aktion ausgelöst wird.&lt;br /&gt;
===§ 3 Rechte und Pflichten des Entwicklers===&lt;br /&gt;
a)     Der Entwickler hat das Recht, mit denjenigen Nutzern, die seine App nutzen wollen, Vereinbarungen über die Nutzung dieser App zu treffen.&lt;br /&gt;
b)     Der Entwickler hat gegenüber Knuddels das Recht, die von ihm erstellte App jederzeit zu löschen bzw. aus dem Angebot von Knuddels zu entfernen. Dieses Recht gilt vorbehaltlich etwaiger Vereinbarungen, die der Entwickler mit Usern getroffen hat, die seine App nutzen.&lt;br /&gt;
c)     Der Entwickler hat das Recht gegenüber Knuddels, seine App jederzeit zu bearbeiten und zu ändern. Dieses Recht gilt vorbehaltlich etwaiger Vereinbarungen, die der Entwickler mit Usern getroffen hat, die seine App nutzen.&lt;br /&gt;
d)     Der Entwickler hat bei der Entwicklung und dem Betrieb der App die geltenden Datenschutzbestimmungen, insbesondere die Regelungen der Datenschutzgrundverordnung (DSGVO) und des Bundesdatenschutzgesetzes (BDSG neu) einzuhalten und die Nutzer der App vor der Nutzung gem. Art. 13 DSGVO zu informieren. Die Rechte der Nutzer nach Art. 15 ff. DSGVO sind diesen zu gewähren. Ohne Zustimmung des betroffenen Nutzers sind keine Daten an Dritte herauszugeben.&lt;br /&gt;
e)     Sofern in einer App Inhalte enthalten sind, die erst für Personen eines bestimmten Alters objektiv als geeignet anzusehen sind, muss der Entwickler dafür Sorge tragen, dass technisch ausgeschlossen ist, dass die entsprechenden Inhalte durch Nutzer, für die diese Inhalte wegen ihres Alters nicht geeignet sind, wahrgenommen werden können.&lt;br /&gt;
f)     Werden dem Nutzer in einer App Leistungen nur gegen Gegenleistung angeboten, so muss der Nutzer, bevor er seine Gegenleistung an den Entwickler gibt, darauf hingewiesen werden, wie lange er aufgrund der Gegenleistung von der erworbenen Leistung profitieren kann. Ferner muss der Entwickler sicherstellen, dass der Nutzer die ihm dargebotene Leistung auch über den gesamten vereinbarten Zeitraum nutzen kann. Wird die Leistung nicht über den gesamten Zeitraum zur Verfügung gestellt, ist dem Nutzer die von ihm entrichtete Gegenleistung anteilig unter Berücksichtigung der bisherigen Nutzungszeit zurückgewähren. Kann die Gegenleistung nicht geteilt werden, ist die gesamte Gegenleistung zu erstatten.&lt;br /&gt;
g)     Apps dürfen keine Funktion aufweisen, mit denen es den Nutzern ermöglicht wird, die von Knuddels angebotenen Smileys zu nutzen oder den Anschein zu erwecken, als würden diese Smileys genutzt, ohne dass der Nutzer diese Smileys selbst für seinen Account freigeschaltet hat.&lt;br /&gt;
===§ 4 Vertraulichkeit===&lt;br /&gt;
Um dem Entwickler die Möglichkeit zu geben, seine Apps entsprechend anzupassen, wird Knuddels gegebenenfalls in Einzelfällen die Entwickler über neue bzw. neu geplante Funktionalitäten des Chatangebotes von Knuddels informieren, noch bevor diese Informationen gegenüber allen Nutzern von Knuddels öffentlich gemacht werden. Der Entwickler ist verpflichtet, solche Informationen absolut vertraulich zu behandeln und nicht an Dritte weiterzugeben, bis die Information durch Knuddels allgemein für alle Nutzer veröffentlicht worden ist.&lt;br /&gt;
===§ 5 Rechte und Pflichten von Knuddels===&lt;br /&gt;
a)     Knuddels hat das Recht, bei einem Verstoß gegen diese AGB oder aus anderem wichtigem Grund die App des Entwicklers jederzeit zu entfernen und den Entwickler dahingehend zu sperren, dass zukünftig dieser oder eine bzw. mehrere Apps des Entwicklers nicht mehr über eine Knuddels-Plattform angeboten werden können.&lt;br /&gt;
===§ 6 Haftungsfreistellung durch den Entwickler===&lt;br /&gt;
Der Entwickler stellt Knuddels im Innenverhältnis von sämtlichen Forderungen und Ansprüchen Dritter frei, die sich daraus ergeben, dass der Entwickler gegen diese AGB verstößt, ein Nutzer Ansprüche wegen Mängeln der Software geltend macht oder die vom Entwickler erstellte Software Urheber-, Marken-, Patentrechte, Rechte an Betriebsgeheimnissen oder am Produktdesign oder andere gewerbliche Schutzrechte von Personen verletzt oder Personen verleumdet oder deren Persönlichkeits- oder Verwertungsrechte verletzt.&lt;br /&gt;
===§ 7 Haftung von Knuddels===&lt;br /&gt;
Knuddels haftet gegenüber dem Entwickler nach den gesetzlichen Vorschriften für Vorsatz und grobe Fahrlässigkeit von Knuddels, seinen gesetzlichen Vertretern, leitenden Angestellten oder sonstigen Erfüllungsgehilfen. Gleiches gilt bei der Übernahme von Garantien oder einer sonstigen verschuldensunabhängigen Haftung sowie bei Ansprüchen nach dem Produkthaftungsgesetz oder bei einer schuldhaften Verletzung des Lebens, des Körpers oder der Gesundheit. Knuddels haftet dem Grunde nach für durch Knuddels, seine Vertreter, leitende Angestellte und einfache Erfüllungsgehilfen verursachte einfach fahrlässige Verletzungen wesentlicher Vertragspflichten, also solcher Pflichten, auf deren Erfüllung der Entwickler zur ordnungsgemäßen Durchführung des Vertrages regelmäßig vertraut und vertrauen darf, in diesem Fall aber der Höhe nach begrenzt auf den typischerweise entstehenden, vorhersehbaren Schaden.&lt;br /&gt;
Eine weitere Haftung von Knuddels ist ausgeschlossen.&lt;br /&gt;
Soweit die Haftung von Knuddels ausgeschlossen oder beschränkt ist, gilt dies auch zugunsten der persönlichen Haftung ihrer gesetzlichen Vertreter, leitenden Angestellten und einfachen Erfüllungsgehilfen.&lt;br /&gt;
&lt;br /&gt;
== Weiterführende Informationen ==&lt;br /&gt;
*[[:/apps AGB]] - Funktion zum Öffnen der Entwickler-AGB im Chat&lt;br /&gt;
&lt;br /&gt;
== Andere Nutzungsbedingungen ==&lt;br /&gt;
{{Regeln}}&lt;br /&gt;
[[Kategorie:Regelwerk]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Familymitglied&amp;diff=128145</id>
		<title>Familymitglied</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Familymitglied&amp;diff=128145"/>
		<updated>2019-07-22T14:02:20Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Verlinkung von UserApps&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines == &lt;br /&gt;
&#039;&#039;&#039;Familymitglieder&#039;&#039;&#039; (kurz: &amp;quot;Family&amp;quot;) sind Chatter, die schon seit längerer Zeit dem Chat treu sind und eine Weile in der Community verbracht haben. Sie kennen sich gut mit dem Chat und den [[Funktionen]] aus, haben in der Regel bereits eine Menge Freundschaften geschlossen und legen ein besonderes Maß an gutem Benehmen und Freundlichkeit an den Tag. Alle Familymitglieder werden im Laufe ihrer Chatlaufbahn durch den [[Butler James]] ernannt. Hat man den [[Status]] des Familymitglieds einmal erreicht, kann man diesen nicht wieder verlieren.&lt;br /&gt;
&lt;br /&gt;
Familymitglieder werden in den meisten Channel als blau gefärbter [[Nickname]] in der [[Nickleiste]] angezeigt und sind somit leicht und eindeutig als solche zu erkennen.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Aufstieg zum Familymitglied==&lt;br /&gt;
Viele [[Onlineminuten]] sind für die Ernennung zum Familymitglied nicht ausschlaggebend. Man sollte dennoch eine hohe Aktivität an den Tag legen. Aber auch der Einsatz für ein gutes Chatklima, freundliche und hilfsbereite Aufnahme von neuen Chattern sollten an den Tag gelegt werden. Für die Ernennung spielt natürlich Glück eine große Rolle. Die genauen Kriterien um Familymitglied zu werden sind nicht bekannt und werden von der Chatleitung geheim gehalten.&lt;br /&gt;
&lt;br /&gt;
==Zusätzliche Funktionen und Möglichkeiten==&lt;br /&gt;
* Anlegen eines [[MyChannel]]&lt;br /&gt;
* Entwickeln von [[User_Apps|UserApps]]&lt;br /&gt;
* Die Vergabe des eigenen [[Herz]]&lt;br /&gt;
* Zugang zum [[Forum|Knuddels-Forum]]&lt;br /&gt;
* Zugang zum [[Channel]] [[Channel:Family|Family]]&lt;br /&gt;
* Vergrößerung der [[/f|Friendlist]]&lt;br /&gt;
* Erkennen neue [[Mitglieder]] an einer Biene hinter dem Nick, wenn sie unter 100 Onlineminuten haben&lt;br /&gt;
* Verwendung der Funktion [[/team]]&lt;br /&gt;
&lt;br /&gt;
==Weiterführende Informationen== &lt;br /&gt;
* [[/h family]] - Chathilfe zum Familymitglied&lt;br /&gt;
* [[/h mychannel]] - Chathilfe zum MyChannel&lt;br /&gt;
* [[Forum]] - Informationen zum Knuddels-Forum&lt;br /&gt;
* [[User_Apps|UserApps]] - Was ist eine UserApp?&lt;br /&gt;
* [[UserApp-Entwicklung]] - Tutorials und Wissen zum Entwickeln von UserApps&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Status}}&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung&amp;diff=128144</id>
		<title>UserApp-Entwicklung</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung&amp;diff=128144"/>
		<updated>2019-07-22T14:00:21Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: sinnvollere Verlinkungen von Tutorials und UserApp-Erklärung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Hier findest du alles was du wissen musst, um deine eigene UserApp auf Knuddels zu programmieren.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn du noch nicht weißt, was eine UserApp ist, schau einfach hier: [[User_App|Was ist eine UserApp?]]&amp;lt;br&amp;gt;&lt;br /&gt;
Einen Überblick über alles im Zusammenhang mit UserApps (auch dieses Wiki) findest du auf dem Entwickler-Portal unter [https://developer.knuddels.de/ developer.knuddels.de].&lt;br /&gt;
&lt;br /&gt;
== Tutorials https://knuddels-wiki.de/images/c/c9/Icon_-_Newbie.gif ==&lt;br /&gt;
&lt;br /&gt;
Wenn du noch keine UserApp entwickelt hast, kannst du das [[UserApp-Entwicklung/Tutorials/Beginner|Beginner-Tutorial]] machen. Dort lernst du Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
→ [[UserApp-Entwicklung/Tutorials|Hier ist die Übersicht über alle Tutorials.]]&lt;br /&gt;
&lt;br /&gt;
== Wichtige Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://developer.knuddels.de/ developer.knuddels.de] - das Entwickler-Portal (Überblick über alles im Zusammenhang mit UserApps)&lt;br /&gt;
* [https://developer.knuddels.de/docs/ UserApps-API Docs]&lt;br /&gt;
* [https://www.knuddels.de/changelog Changelog]&lt;br /&gt;
&lt;br /&gt;
== Andere UserApps-Entwickler ==&lt;br /&gt;
&lt;br /&gt;
* Wir freuen uns, wenn sich neue Entwickler kurz [https://forum.knuddels.de/ubbthreads.php?ubb=showflat&amp;amp;Number=2704910 im Forum vorstellen]. Aber das ist natürlich kein Muss.&lt;br /&gt;
* Die Kommunikation findet über den Discord Server statt.&amp;lt;br&amp;gt;Gib &#039;&#039;&#039;/apps developer&#039;&#039;&#039; ein und klicke auf den entsprechenden Link.&amp;lt;br&amp;gt;[https://blog.knuddels.de/2018/07/31/kommunikation-zukuenftig-auf-discord/ → Blogeintrag dazu]&lt;br /&gt;
* Außerdem gibt es im [https://forum.knuddels.de/ubbthreads.php?ubb=cfrm&amp;amp;c=9 UserApps-Forum] viele Beiträge!&lt;br /&gt;
&lt;br /&gt;
== Die UserApps-API https://knuddels-wiki.de/images/2/29/Quiz-Smiley.gif ==&lt;br /&gt;
&lt;br /&gt;
Willst du mehr über die UserApps-API wissen? Schau mal hier rein:&lt;br /&gt;
&lt;br /&gt;
* [[API|Was ist die UserApps-API?]]&lt;br /&gt;
* [https://developer.knuddels.de/docs/ UserApps-API Docs]&lt;br /&gt;
&lt;br /&gt;
== Design &amp;amp; Grafik in UserApps https://knuddels-wiki.de/images/a/a0/Rose.gif ==&lt;br /&gt;
&lt;br /&gt;
UserApps können natürlich auch Grafiken, Animationen und Sounds wiedergeben! Du kannst sogar ein 3D-Spiel als UserApp programmieren!&lt;br /&gt;
Mindestens kannst du aber mal &#039;&#039;&#039;KCode&#039;&#039;&#039; lernen, falls du das noch nicht getan hast.  &lt;br /&gt;
Schau dir als Einstieg folgende Links an:&lt;br /&gt;
&lt;br /&gt;
* Texte vom AppBot formatieren: [[Formatierungen]]&lt;br /&gt;
* Grafische Web-Oberfläche&lt;br /&gt;
** [[User_App:HTML-UI/Web|Einführung 1]]&lt;br /&gt;
** [https://bitbucket.org/knuddels/user-apps/wiki/HTML-UI/Web Einführung 2]&lt;br /&gt;
** [https://bitbucket.org/knuddels/user-apps/wiki/HTML-UI/Environment Besonderheiten der HTML-UI (Environment)]&lt;br /&gt;
&lt;br /&gt;
== Technische Infos ==&lt;br /&gt;
&lt;br /&gt;
* [https://bitbucket.org/knuddels/user-apps/wiki/Development Development] - einige Basics und technische Infos&lt;br /&gt;
* [[Limits|Technische Limits]] für UserApps&lt;br /&gt;
&lt;br /&gt;
== Bugs ==&lt;br /&gt;
&lt;br /&gt;
Wenn du einen Bug bemerkt hast, kannst du jemanden im &#039;&#039;&#039;/team bugs&#039;&#039;&#039; anschreiben.  &lt;br /&gt;
Deine Ideen und Wünsche kannst du mit uns auf Discord teilen.&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta&amp;diff=128087</id>
		<title>UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta&amp;diff=128087"/>
		<updated>2019-07-15T09:10:47Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tipps und Konventionen für das Schreiben von Tutorials zu UserApps.&lt;br /&gt;
&lt;br /&gt;
== Erstellen des Wiki-Artikels ==&lt;br /&gt;
&lt;br /&gt;
* [[Knuddels-Wiki:Tutorial01|Registriere dich zunächst im Wiki und logge dich ein.]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Knuddels-Wiki:Tutorial03|Hier wird erklärt, wie du neue Artikel erstellst.]]&lt;br /&gt;
&lt;br /&gt;
  Wichtig: Der &#039;&#039;&#039;Titel&#039;&#039;&#039; deines Tutorials sollte mit &#039;&#039;&#039;UserApp-Entwicklung/Tutorials/&#039;&#039;&#039; beginnen!&lt;br /&gt;
  Artikel, die kein Tutorial sind, sondern lediglich etwas dokumentieren, sollten mit &#039;&#039;&#039;UserApp-Entwicklung/Doku/&#039;&#039;&#039; beginnen.&lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
* Tutorial: [[UserApp-Entwicklung/Tutorials/HTML-UI]]&lt;br /&gt;
* Doku: [[UserApp-Entwicklung/Doku/AppId]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Code-Beispiele einfügen ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;amp;#x3C;pre&amp;amp;#x3E;-Tag ===&lt;br /&gt;
&lt;br /&gt;
Code ist auf dem Knuddels-Wiki am besten in einem &#039;&#039;&#039;&amp;amp;#x3C;pre&amp;amp;#x3E;&#039;&#039;&#039;-Tag aufgehoben.&amp;lt;br&amp;gt;&lt;br /&gt;
Allerdings gibt es auch hier noch Probleme mit der Formatierung, zum Beispiel werden Whitespaces am Anfang der Zeile entfernt.&lt;br /&gt;
&lt;br /&gt;
=== Whitespaces ===&lt;br /&gt;
&lt;br /&gt;
Die Whitespaces am Anfang der Zeile (oder einfach alle) können durch &#039;&#039;&#039;&amp;amp;#x26;nbsp;&#039;&#039;&#039; (geschütztes Leerzeichen) ersetzt werden, damit sie trotzdem angezeigt werden.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python sähe das so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; s = &amp;quot;&amp;quot;&amp;quot;... hier der Quellcode ...&lt;br /&gt;
... noch mehr Quellcode ...&lt;br /&gt;
...&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print(s.replace(&amp;quot; &amp;quot;, &amp;quot;&amp;amp;#x26;nbsp;&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTML-Quellcode ===&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung von XML-Tags sollte der Quellcode außerdem zuerst einmal durch dieses Tool &amp;quot;escaped&amp;quot; werden: https://mothereff.in/html-entities&lt;br /&gt;
&lt;br /&gt;
=== Syntax-Highlighting ===&lt;br /&gt;
&lt;br /&gt;
Das Knuddels-Wiki hat derzeit leider kein Syntax-Highlighting.&lt;br /&gt;
&lt;br /&gt;
=== Quellcode sichern ===&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist durch diese Änderungen im Bearbeitungsfeld im Wiki nicht mehr gut lesbar. Um für spätere Änderungen noch die originale Version des Code-Beispiels zu erhalten, kann es in einem XML-Kommentar gesichert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;#x3C;!--&lt;br /&gt;
hier die Originalversion&lt;br /&gt;
--&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;#x3C;pre&amp;amp;#x3E;&lt;br /&gt;
hier die &amp;quot;escapte&amp;quot; Version&lt;br /&gt;
&amp;amp;#x3C;/pre&amp;amp;#x3E;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zusammenfassung ===&lt;br /&gt;
&lt;br /&gt;
# Code in einem Kommentar &#039;&#039;&#039;&amp;amp;#x3C;!--  --&amp;amp;#x3E;&#039;&#039;&#039; sichern&lt;br /&gt;
# Falls XML-Tags im Code vorkommen, durch dieses Tool jagen: https://mothereff.in/html-entities&lt;br /&gt;
# alle Leerzeichen (eigentlich nur am Anfang jeder Zeile) durch &#039;&#039;&#039;&amp;amp;#x26;nbsp;&#039;&#039;&#039; ersetzen&lt;br /&gt;
# das Ergebnis in einem &#039;&#039;&#039;&amp;amp;#x3C;pre&amp;amp;#x3E;&amp;amp;#x3C;/pre&amp;amp;#x3E;&#039;&#039;&#039;-Tag einfügen&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta&amp;diff=128038</id>
		<title>UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta&amp;diff=128038"/>
		<updated>2019-07-12T13:51:05Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: kleine Fehler verbessert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tipps für das Schreiben von Tutorials zu UserApps.&lt;br /&gt;
&lt;br /&gt;
== Code-Beispiele einfügen ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;amp;#x3C;pre&amp;amp;#x3E;-Tag ===&lt;br /&gt;
&lt;br /&gt;
Code ist auf dem Knuddels-Wiki am besten in einem &#039;&#039;&#039;&amp;amp;#x3C;pre&amp;amp;#x3E;&#039;&#039;&#039;-Tag aufgehoben.&amp;lt;br&amp;gt;&lt;br /&gt;
Allerdings gibt es auch hier noch Probleme mit der Formatierung, zum Beispiel werden Whitespaces am Anfang der Zeile entfernt.&lt;br /&gt;
&lt;br /&gt;
=== Whitespaces ===&lt;br /&gt;
&lt;br /&gt;
Die Whitespaces am Anfang der Zeile (oder einfach alle) können durch &#039;&#039;&#039;&amp;amp;#x26;nbsp;&#039;&#039;&#039; (geschütztes Leerzeichen) ersetzt werden, damit sie trotzdem angezeigt werden.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python sähe das so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; s = &amp;quot;&amp;quot;&amp;quot;... hier der Quellcode ...&lt;br /&gt;
... noch mehr Quellcode ...&lt;br /&gt;
...&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print(s.replace(&amp;quot; &amp;quot;, &amp;quot;&amp;amp;#x26;nbsp;&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTML-Quellcode ===&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung von XML-Tags sollte der Quellcode außerdem zuerst einmal durch dieses Tool &amp;quot;escaped&amp;quot; werden: https://mothereff.in/html-entities&lt;br /&gt;
&lt;br /&gt;
=== Syntax-Highlighting ===&lt;br /&gt;
&lt;br /&gt;
Das Knuddels-Wiki hat derzeit leider kein Syntax-Highlighting.&lt;br /&gt;
&lt;br /&gt;
=== Quellcode sichern ===&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist durch diese Änderungen im Bearbeitungsfeld im Wiki nicht mehr gut lesbar. Um für spätere Änderungen noch die originale Version des Code-Beispiels zu erhalten, kann es in einem XML-Kommentar gesichert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;#x3C;!--&lt;br /&gt;
hier die Originalversion&lt;br /&gt;
--&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;#x3C;pre&amp;amp;#x3E;&lt;br /&gt;
hier die &amp;quot;escapte&amp;quot; Version&lt;br /&gt;
&amp;amp;#x3C;/pre&amp;amp;#x3E;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zusammenfassung ===&lt;br /&gt;
&lt;br /&gt;
# Code in einem Kommentar &#039;&#039;&#039;&amp;amp;#x3C;!--  --&amp;amp;#x3E;&#039;&#039;&#039; sichern&lt;br /&gt;
# Falls XML-Tags im Code vorkommen, durch dieses Tool jagen: https://mothereff.in/html-entities&lt;br /&gt;
# alle Leerzeichen (eigentlich nur am Anfang jeder Zeile) durch &#039;&#039;&#039;&amp;amp;#x26;nbsp;&#039;&#039;&#039; ersetzen&lt;br /&gt;
# das Ergebnis in einem &#039;&#039;&#039;&amp;amp;#x3C;pre&amp;amp;#x3E;&amp;amp;#x3C;/pre&amp;amp;#x3E;&#039;&#039;&#039;-Tag einfügen&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta&amp;diff=128037</id>
		<title>UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta&amp;diff=128037"/>
		<updated>2019-07-12T13:41:08Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: u.a. eine Hilfe zum Formatieren von Code in Tutorials&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tipps für das Schreiben von Tutorials zu UserApps.&lt;br /&gt;
&lt;br /&gt;
== Code-Beispiele einfügen ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;amp;#x3C;pre&amp;amp;#x3E;-Tag ===&lt;br /&gt;
&lt;br /&gt;
Code ist auf dem Knuddels-Wiki am besten in einem &amp;amp;#x3C;pre&amp;amp;#x3E;-Tag aufgehoben.&amp;lt;br&amp;gt;&lt;br /&gt;
Allerdings gibt es auch hier noch Probleme mit der Formatierung, zum Beispiel werden Whitespaces am Anfang der Zeile entfernt.&lt;br /&gt;
&lt;br /&gt;
=== Whitespaces ===&lt;br /&gt;
&lt;br /&gt;
Die Whitespaces am Anfang der Zeile (oder einfach alle) können durch &#039;&#039;&#039;&amp;quot;&amp;amp;#x26;nbsp;&amp;quot;&#039;&#039;&#039; (geschütztes Leerzeichen) ersetzt werden, damit sie trotzdem angezeigt werden.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python sähe das so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; s = &amp;quot;&amp;quot;&amp;quot;... hier der Quellcode ...&lt;br /&gt;
... noch mehr Quellcode ...&lt;br /&gt;
...&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; print(s.replace(&amp;quot; &amp;quot;, &amp;quot;&amp;amp;#x26;nbsp;&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTML-Quellcode ===&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung von XML-Tags sollte der Quellcode außerdem zuerst einmal durch dieses Tool &amp;quot;escaped&amp;quot; werden: https://mothereff.in/html-entities&lt;br /&gt;
&lt;br /&gt;
=== Syntax-Highlighting ===&lt;br /&gt;
&lt;br /&gt;
Das Knuddels-Wiki hat derzeit leider kein Syntax-Highlighting.&lt;br /&gt;
&lt;br /&gt;
=== Quellcode sichern ===&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis ist durch diese Änderungen im Bearbeitungsfeld im Wiki nicht mehr gut lesbar. Um für spätere Änderungen noch die originale Version des Code-Beispiels zu erhalten, kann es in einem XML-Kommentar gesichert werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;#x3C;!--&lt;br /&gt;
hier die Originalversion&lt;br /&gt;
--&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;#x3C;pre&amp;amp;#x3E;&lt;br /&gt;
hier die &amp;quot;escapte&amp;quot; Version&lt;br /&gt;
&amp;amp;#x3C;/pre&amp;amp;#x3E;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zusammenfassung ===&lt;br /&gt;
&lt;br /&gt;
# Code in einem Kommentar &#039;&#039;&#039;&amp;amp;#x3C;!--  --&amp;amp;#x3E;&#039;&#039;&#039; sichern&lt;br /&gt;
# Falls XML-Tags im Code vorkommen, durch dieses Tool jagen: [https://mothereff.in/html-entities]&lt;br /&gt;
# alle Leerzeichen (eigentlich nur am Anfang jeder Zeile) durch &amp;quot;&amp;amp;nbsp&amp;quot; ersetzen → daher am besten keine Tabs im Quellcode verwenden&lt;br /&gt;
# das Ergebnis in einem &amp;amp;#x3C;pre&amp;amp;#x3E;&amp;amp;#x3C;/pre&amp;amp;#x3E;-Tag einfügen&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128036</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128036"/>
		<updated>2019-07-12T13:13:57Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Redlinks hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Für Anfänger ==&lt;br /&gt;
Lerne Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Einstieg]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/HTML-UI|HTML-UI (grafische Oberfläche)]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/UserApps_teilen|UserApps teilen]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Newsletter-Versand|Newsletter-Versand]]&lt;br /&gt;
&lt;br /&gt;
== Für Fortgeschrittene ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Es gibt leider noch keine Tutorials für Fortgeschrittene.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Du kannst dich auf Discord an fortgeschrittene UserApp-Entwickler wenden. Den Link zum Discord-Channel findest du unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[User_Apps/Tutorial|Hallo Welt]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Meta ==&lt;br /&gt;
&lt;br /&gt;
Tutorial über das Schreiben von UserApp-Tutorials: [[UserApp-Entwicklung/Tutorials/UserApp-Tutorials-Meta|UserApp-Tutorials-Meta]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=Limits&amp;diff=128035</id>
		<title>Limits</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=Limits&amp;diff=128035"/>
		<updated>2019-07-12T13:06:26Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Limits für private Nachrichten und AppInstance.sendAppEvent() hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines ==&lt;br /&gt;
Innerhalb des Chats gibt es einige (technische) Begrenzungen. Diese dienen unter Anderem der Vermeidung von [[Spam]] oder Missbrauch der Dienste. Eine der bekanntesten Limits betrifft wohl die Anzahl der Smileys pro Chatnachricht.&lt;br /&gt;
&lt;br /&gt;
== Limitierungen ==&lt;br /&gt;
&lt;br /&gt;
=== Chat allgemein ===&lt;br /&gt;
==== Nachrichten ====&lt;br /&gt;
[[/m|Postfach]]-Nachricht: 2.000 Zeichen&lt;br /&gt;
&lt;br /&gt;
Öffentliche Nachricht: 1.000 Zeichen&lt;br /&gt;
&lt;br /&gt;
Private Nachricht: 2.000 Zeichen&lt;br /&gt;
&lt;br /&gt;
Zeilenumbrüche pro Nachricht: 4&lt;br /&gt;
&lt;br /&gt;
=== User App Entwicklung ===&lt;br /&gt;
Für die Entwicklung und den Betrieb einer [[User App]] gelten einige besondere Beschränkungen. Dies ist notwendig, da pro Server-Instanz mehrere User Apps laufen. Durch die Beschränkungen kann sichergestellt werden, dass keine User App übermäßig hohe Ressourcen beansprucht.&lt;br /&gt;
&lt;br /&gt;
Um eine Abschaltung oder Einschränkung der User App zu verhindern, sollte auf eine Einhaltung der Limits geachtet werden.&lt;br /&gt;
&lt;br /&gt;
In Einzelfällen können, für besonders große/aktive [[Channel]], bestimmte Beschränkungen durch das [[Knuddelsteam]] manuell angepasst werden. Hierzu bedarf es einer Kontaktaufnahme durch den Channelbesitzer.&lt;br /&gt;
&lt;br /&gt;
==== Externe Kommunikation ====&lt;br /&gt;
Alle hier genannten Daten gelten inklusive der Header-Daten.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Request size Limit: 10kB&lt;br /&gt;
&lt;br /&gt;
Response size Limit: 50kB&lt;br /&gt;
&lt;br /&gt;
Maximale Anzahl gleichzeitige Requests: 50&lt;br /&gt;
&lt;br /&gt;
Daten-Limit: 50MB pro 10min&lt;br /&gt;
&lt;br /&gt;
Request-Limit: 100 Requests pro 10min&lt;br /&gt;
&lt;br /&gt;
==== Knuddel-Transfer-Reason ====&lt;br /&gt;
Maximale Länge für displayReasonText: 2000 Zeichen&lt;br /&gt;
&lt;br /&gt;
==== Persistence ====&lt;br /&gt;
Maximale Länge: 102.400 Zeichen&lt;br /&gt;
&lt;br /&gt;
==== Server zu UI | UI zu Server ====&lt;br /&gt;
Maximale Länge: 10.000 Zeichen&lt;br /&gt;
&lt;br /&gt;
==== Nachrichten ====&lt;br /&gt;
&lt;br /&gt;
Öffentliche Nachrichten: 30 in 15s&amp;lt;br&amp;gt;&lt;br /&gt;
Private Nachrichten: 45 in 15s&amp;lt;br&amp;gt;&lt;br /&gt;
AppInstance.sendAppEvent(): 50 in 5s&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:User App]] [[Kategorie:Begriffserklärung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128034</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128034"/>
		<updated>2019-07-12T13:03:43Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Für Anfänger ==&lt;br /&gt;
Lerne Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Einstieg]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/HTML-UI|HTML-UI (grafische Oberfläche)]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/UserApps_teilen|UserApps teilen]]&lt;br /&gt;
&lt;br /&gt;
== Für Fortgeschrittene ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Es gibt leider noch keine Tutorials für Fortgeschrittene.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Du kannst dich auf Discord an fortgeschrittene UserApp-Entwickler wenden. Den Link zum Discord-Channel findest du unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[User_Apps/Tutorial|Hallo Welt]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/HTML-UI&amp;diff=128015</id>
		<title>UserApp-Entwicklung/Tutorials/HTML-UI</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/HTML-UI&amp;diff=128015"/>
		<updated>2019-07-09T17:03:44Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Hinweis auf Client.includeJS hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
In diesem Tutorial lernst du, wie du eine grafische Oberfläche in deinen UserApps verwenden kannst, um z.B. grafische Spiele für Knuddels zu programmieren. Du solltest schon einmal etwas mit HTML und JavaScript gemacht haben, um folgen zu können.&lt;br /&gt;
&lt;br /&gt;
== Der Server ==&lt;br /&gt;
&lt;br /&gt;
Der Server-Code deiner UserApp steht in der &#039;&#039;&#039;main.js&#039;&#039;&#039;. Wenn du nur in der &#039;&#039;&#039;main.js&#039;&#039;&#039; programmierst, läuft der ganze Code deiner UserApp ausschließlich auf den Servern von Knuddels.&amp;lt;br&amp;gt;&lt;br /&gt;
Damit kann man zwar schon viel machen, aber für mehr Interaktionsmöglichkeiten brauchst du eine grafische Oberfläche.&lt;br /&gt;
&lt;br /&gt;
== Der Client ==&lt;br /&gt;
&lt;br /&gt;
Der Code für den Client befindet sich im &#039;&#039;&#039;www&#039;&#039;&#039;-Unterordner deiner UserApp.&lt;br /&gt;
Den Einstieg bildet eine HTML-Datei, die du nennen kannst, wie du willst. Dort kannst du dann auch JavaScript-Dateien einbinden, um Code auf dem Gerät deines Besuchers auszuführen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur deiner UserApp könnte dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
KnuddelJumper/&lt;br /&gt;
    www/&lt;br /&gt;
        game.html&lt;br /&gt;
        game.js&lt;br /&gt;
        player.png&lt;br /&gt;
        enemy.png&lt;br /&gt;
    main.js&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
KnuddelJumper/&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;www/&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;game.html&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;game.js&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;player.png&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;enemy.png&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;main.js&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die HTML-Datei kann dann z.B. so eine Struktur haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- use https://mothereff.in/html-entities and replace &amp;quot; &amp;quot; with &amp;quot;&amp;amp;nbsp;&amp;quot;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;head&amp;gt;&lt;br /&gt;
        &amp;lt;script src=&amp;quot;game.js&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/head&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        &amp;lt;button&amp;gt;Hier klicken&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;#x3C;html&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;head&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;script&amp;amp;nbsp;src=&amp;amp;#x22;game.js&amp;amp;#x22;/&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/head&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;body&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;button&amp;amp;#x3E;Hier&amp;amp;nbsp;klicken&amp;amp;#x3C;/button&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/body&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;#x3C;/html&amp;amp;#x3E;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Während der Entwicklung wirst du allerdings oft Änderungen an deinem Script machen. Da Knuddels dein Script zwischenspeichert, wenn du es einfach mit dem &#039;&#039;&#039;&amp;lt;script&amp;gt;&#039;&#039;&#039;-Tag einbindest, werden deine Änderungen oft nicht übernommen. Um Knuddels dazu zu zwingen immer die aktuellste Version deines Scripts zu laden, musst du das Knuddels stattdessen mit [https://developer.knuddels.de/docs/classes/Client.html#method_includeJS Client.includeJS()] mitteilen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;head&amp;gt;&lt;br /&gt;
        &amp;lt;script&amp;gt;&lt;br /&gt;
            Client.includeJS(&amp;quot;game.js&amp;quot;);&lt;br /&gt;
        &amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;/head&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        &amp;lt;button&amp;gt;Hier klicken&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;#x3C;html&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;head&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;script&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Client.includeJS(&amp;amp;#x22;game.js&amp;amp;#x22;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/script&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/head&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;body&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;button&amp;amp;#x3E;Hier&amp;amp;nbsp;klicken&amp;amp;#x3C;/button&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/body&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;#x3C;/html&amp;amp;#x3E;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Server und Client ==&lt;br /&gt;
&lt;br /&gt;
=== AppContent senden ===&lt;br /&gt;
&lt;br /&gt;
Die HTML-Datei und der restliche Inhalt des &#039;&#039;&#039;www&#039;&#039;&#039;-Unterordners wird [https://developer.knuddels.de/docs/classes/AppContent.html AppContent] genannt. Das ist die grafische Oberfäche deiner UserApp.&amp;lt;br&amp;gt;&lt;br /&gt;
Der AppContent erscheint aber nicht automatisch bei dem Besucher deines Channels! Du musst den AppContent erst an den Besucher (den Client) senden.&lt;br /&gt;
In der Regel macht man das direkt wenn der Besucher den Channel betritt, also in &#039;&#039;&#039;App.onUserJoined&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
var App = (new function() {&lt;br /&gt;
&lt;br /&gt;
    let htmlFile = new HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
    let appContent = AppContent.overlayContent(htmlFile, 640, 480);&lt;br /&gt;
&lt;br /&gt;
    this.onUserJoined = function(user) {&lt;br /&gt;
        user.sendAppContent(appContent);&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;htmlFile&amp;amp;nbsp;=&amp;amp;nbsp;new&amp;amp;nbsp;HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;appContent&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.overlayContent(htmlFile,&amp;amp;nbsp;640,&amp;amp;nbsp;480);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(appContent);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der [https://developer.knuddels.de/docs/classes/AppContent.html AppContent] wird so nur einmal von der App geladen und dann einfach an jeden Besucher mit [https://developer.knuddels.de/docs/classes/User.html#method_sendAppContent User.sendAppContent()] gesendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  Hinweis: [https://developer.knuddels.de/docs/classes/HTMLFile.html new HTMLFile()] sucht die angegebene Datei im &#039;&#039;&#039;www&#039;&#039;&#039;-Unterordner.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Damit ist dieses Tutorial eigentlich fertig:&#039;&#039;&#039; Deine Besucher sehen jetzt eine grafische Oberfläche, wenn sie deinen Channel betreten und du kannst wie auf Webseiten Scripts einbinden. Ein paar wichtige Hinweise kommen aber noch!&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der AppContent kann verschiedene &#039;&#039;&#039;ViewModes&#039;&#039;&#039; annehmen, je nachdem welche Methode du verwendest:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Overlay&#039;&#039;&#039; mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_overlayContent AppContent.overlayContent()]&lt;br /&gt;
* &#039;&#039;&#039;Popup&#039;&#039;&#039; mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_popupContent AppContent.popupContent()]&lt;br /&gt;
* &#039;&#039;&#039;Headerbar&#039;&#039;&#039; mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_headerbarContent AppContent.headerbarContent()]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Tipp:&#039;&#039;&#039; Nicht alle Geräte können jeden &#039;&#039;&#039;ViewMode&#039;&#039;&#039; anzeigen. Daher ist es gute Praxis, wenn du mit [https://developer.knuddels.de/docs/classes/User.html#method_canSendAppContent User.canSendAppContent()] entscheidest, welchen AppContent du sendest.&lt;br /&gt;
&#039;&#039;&#039;Beispiel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
var App = (new function() {&lt;br /&gt;
&lt;br /&gt;
    let htmlFile = new HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
    let overlay = AppContent.overlayContent(htmlFile, 640, 480);&lt;br /&gt;
    let popup  = AppContent.popupContent(htmlFile, 640, 480);&lt;br /&gt;
    let headerbar = AppContent.headerbarContent(htmlFile, 480);&lt;br /&gt;
&lt;br /&gt;
    this.onUserJoined = function(user) {&lt;br /&gt;
&lt;br /&gt;
        if (user.canSendAppContent(overlay)) {&lt;br /&gt;
            user.sendAppContent(overlay);&lt;br /&gt;
&lt;br /&gt;
        } else if (user.canSendAppContent(popup)) {&lt;br /&gt;
            user.sendAppContent(popup);&lt;br /&gt;
&lt;br /&gt;
        } else if (user.canSendAppContent(headerbar)) {&lt;br /&gt;
            user.sendAppContent(headerbar);&lt;br /&gt;
&lt;br /&gt;
        } else {&lt;br /&gt;
            user.sendPrivateMessage(&amp;quot;Die UserApp kann auf deinem Gerät leider nicht angezeigt werden.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;htmlFile&amp;amp;nbsp;=&amp;amp;nbsp;new&amp;amp;nbsp;HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;overlay&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.overlayContent(htmlFile,&amp;amp;nbsp;640,&amp;amp;nbsp;480);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;popup&amp;amp;nbsp;&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.popupContent(htmlFile,&amp;amp;nbsp;640,&amp;amp;nbsp;480);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;headerbar&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.headerbarContent(htmlFile,&amp;amp;nbsp;480);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(user.canSendAppContent(overlay))&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(overlay);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;if&amp;amp;nbsp;(user.canSendAppContent(popup))&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(popup);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;if&amp;amp;nbsp;(user.canSendAppContent(headerbar))&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(headerbar);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(&amp;quot;Die&amp;amp;nbsp;UserApp&amp;amp;nbsp;kann&amp;amp;nbsp;auf&amp;amp;nbsp;deinem&amp;amp;nbsp;Gerät&amp;amp;nbsp;leider&amp;amp;nbsp;nicht&amp;amp;nbsp;angezeigt&amp;amp;nbsp;werden.&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events senden ===&lt;br /&gt;
&lt;br /&gt;
Dein Code auf dem Server und dein Code auf dem Client laufen jetzt praktisch unabhängig voneinander. Meistens ist es aber hilfreich, wenn Server und Client miteinander kommunizieren können.&lt;br /&gt;
&lt;br /&gt;
==== Client → Server ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Beispiel:&#039;&#039;&#039; Wenn der Nutzer auf der grafischen Oberfläche einen Knopf drückt, soll der AppBot eine öffentliche Nachricht in den Channel schreiben.&amp;lt;br&amp;gt;&lt;br /&gt;
Du kannst aber nur von der &#039;&#039;&#039;main.js&#039;&#039;&#039; (also vom Server aus) Chat-Nachrichten schicken. [https://developer.knuddels.de/docs/classes/BotUser.html#method_sendPublicMessage BotUser.sendPublicMessage()] funktioniert im Client nicht.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Client muss also dem Server mitteilen, dass der Nutzer einen Button gedrückt hat. Das ist mit [https://developer.knuddels.de/docs/classes/Client.html#method_sendEvent Client.sendEvent()] möglich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Client.sendEvent(&amp;quot;buttonPressed&amp;quot;, {});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei können noch zusätzliche Daten in Form eines JavaScript-Objekts mitgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Der Server kann dann in der &#039;&#039;&#039;main.js&#039;&#039;&#039; in [https://developer.knuddels.de/docs/classes/App.html#method_onEventReceived App.onEventReceived()] reagieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
var App = (new function() {&lt;br /&gt;
    &lt;br /&gt;
    //...&lt;br /&gt;
    &lt;br /&gt;
    this.onEventReceived = function(user, type, data, appContentSession) {&lt;br /&gt;
&lt;br /&gt;
        if (type == &amp;quot;buttonPressed&amp;quot;) {&lt;br /&gt;
            let bot = KnuddelsServer.getDefaultBotUser();&lt;br /&gt;
            bot.sendPublicMessage(user.getProfileLink()+&amp;quot; hat den Knopf gedrückt!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;//...&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onEventReceived&amp;amp;nbsp;=&amp;amp;nbsp;function(user,&amp;amp;nbsp;type,&amp;amp;nbsp;data,&amp;amp;nbsp;appContentSession)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(type&amp;amp;nbsp;==&amp;amp;nbsp;&amp;quot;buttonPressed&amp;quot;)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;bot&amp;amp;nbsp;=&amp;amp;nbsp;KnuddelsServer.getDefaultBotUser();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;bot.sendPublicMessage(user.getProfileLink()+&amp;quot;&amp;amp;nbsp;hat&amp;amp;nbsp;den&amp;amp;nbsp;Knopf&amp;amp;nbsp;gedrückt!&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Server → alle Clients ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Beispiel:&#039;&#039;&#039; In der &#039;&#039;&#039;main.js&#039;&#039;&#039; wird eine zufällige Zahl generiert. Diese Zahl soll an alle Besucher des Channels geschickt werden, sodass diese dann in der HTML-UI angezeigt werden kann.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_sendEvent AppContent.sendEvent()] kannst du ein Event an alle Besucher schicken, bei denen dieser AppContent aktiv ist:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let randomNumber = Math.floor(10 * Math.random());&lt;br /&gt;
appContent.sendEvent(&amp;quot;showNumber&amp;quot;, {randomNumber: number});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Client kannst du mit [https://developer.knuddels.de/docs/classes/Client.html#method_addEventListener Client.addEventListener()] auf die Events vom Server reagieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Client.addEventListener(&amp;quot;showNumber&amp;quot;, function(event) {&lt;br /&gt;
        let number = event.data.number;&lt;br /&gt;
        &lt;br /&gt;
        document.open();&lt;br /&gt;
        document.write(&amp;quot;Die magische Zahl heißt: &amp;quot;+number);&lt;br /&gt;
        document.close()&lt;br /&gt;
});&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Client.addEventListener(&amp;quot;showNumber&amp;quot;,&amp;amp;nbsp;function(event)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;number&amp;amp;nbsp;=&amp;amp;nbsp;event.data.number;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;document.open();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;document.write(&amp;quot;Die&amp;amp;nbsp;magische&amp;amp;nbsp;Zahl&amp;amp;nbsp;heißt:&amp;amp;nbsp;&amp;quot;+number);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;document.close()&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Server → ein bestimmter Client ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel:&#039;&#039;&#039; Du wählst einen Besucher zufällig aus und möchtest, dass sich bei diesem Besucher die Farbe der HTML-UI ändert.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dazu musst du vom Server aus (also in der &#039;&#039;&#039;main.js&#039;&#039;&#039;) diesem Client ein Event senden.&amp;lt;br&amp;gt;&lt;br /&gt;
Du kannst aber nicht einfach &#039;&#039;User.sendEvent()&#039;&#039; aufrufen (diesen Befehl gibt es nicht). Eine UserApp kann nämlich verschiedene &#039;&#039;&#039;ViewModes&#039;&#039;&#039; auf einmal verwenden (sogenannte &#039;&#039;&#039;AppContentSessions&#039;&#039;&#039;). Du musst der API also sagen, an welche &#039;&#039;&#039;AppContentSession&#039;&#039;&#039; du das Event senden möchtest.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn du weißt, welchen &#039;&#039;&#039;ViewMode&#039;&#039;&#039; der Besucher verwendet (z.B. weil du sowieso immer nur ein Popup sendest), kannst du einfach mit dem Befehl [https://developer.knuddels.de/docs/classes/User.html#method_getAppContentSession User.getAppContentSession] die AppContentSession erhalten und dann das Event senden. &#039;&#039;&#039;Beispiel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let appContentSession = user.getAppContentSession(AppViewMode.Popup);&lt;br /&gt;
appContentSession.sendEvent(&amp;quot;changeColor&amp;quot;, {red:255, green:0, blue:255});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn dein Client allerdings gleichzeitig mehrere aktive &#039;&#039;&#039;AppContentSessions&#039;&#039;&#039; haben könnte (z.B. eine Headerbar und ein Popup), kannst du eine Liste aller aktiven AppContentSessions eines Besuchers mit [https://developer.knuddels.de/docs/classes/User.html#method_getAppContentSessions User.getAppContentSessions()] erhalten. &#039;&#039;&#039;Beispiel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
let appContentSessions = user.getAppContentSessions();&lt;br /&gt;
&lt;br /&gt;
for (let i = 0; i &amp;lt; appContentSessions.length; i++) {&lt;br /&gt;
    let appContentSession = appContentSessions[i];&lt;br /&gt;
    appContentSession.sendEvent(&amp;quot;changeColor&amp;quot;, {red:255, green:0, blue:255});&lt;br /&gt;
}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let&amp;amp;nbsp;appContentSessions&amp;amp;nbsp;=&amp;amp;nbsp;user.getAppContentSessions();&lt;br /&gt;
&lt;br /&gt;
for&amp;amp;nbsp;(let&amp;amp;nbsp;i&amp;amp;nbsp;=&amp;amp;nbsp;0;&amp;amp;nbsp;i&amp;amp;nbsp;&amp;lt;&amp;amp;nbsp;appContentSessions.length;&amp;amp;nbsp;i++)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;appContentSession&amp;amp;nbsp;=&amp;amp;nbsp;appContentSessions[i];&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;appContentSession.sendEvent(&amp;quot;changeColor&amp;quot;,&amp;amp;nbsp;{red:255,&amp;amp;nbsp;green:0,&amp;amp;nbsp;blue:255});&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier kannst du im Client wieder mit [https://developer.knuddels.de/docs/classes/Client.html#method_addEventListener Client.addEventListener()] auf die Events reagieren.&lt;br /&gt;
&lt;br /&gt;
==== Limits ====&lt;br /&gt;
&lt;br /&gt;
Für die Daten, die du mit den Events zwischen Client und Server sendest, gibt es gewisse [[Limits]]. Diese Limits werden [[Limits|hier]] beschrieben.&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128014</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=128014"/>
		<updated>2019-07-09T16:22:02Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Link zum HTML-UI Tutorial hinzugefügt und Kategorien eingeführt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Für Anfänger ==&lt;br /&gt;
Lerne Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Einstieg]]&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/HTML-UI|HTML-UI (grafische Oberfläche)]]&lt;br /&gt;
&lt;br /&gt;
== Für Fortgeschrittene ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Es gibt leider noch keine Tutorials für Fortgeschrittene.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Du kannst dich auf Discord an fortgeschrittene UserApp-Entwickler wenden. Den Link zum Discord-Channel findest du unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[User_Apps/Tutorial|Hallo Welt]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/HTML-UI&amp;diff=128013</id>
		<title>UserApp-Entwicklung/Tutorials/HTML-UI</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/HTML-UI&amp;diff=128013"/>
		<updated>2019-07-09T16:12:18Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Basic Tutorial für das senden von AppContent (HTML-UI) und dem senden von Events zwischen Server und Client&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
In diesem Tutorial lernst du, wie du eine grafische Oberfläche in deinen UserApps verwenden kannst, um z.B. grafische Spiele für Knuddels zu programmieren. Du solltest schon einmal etwas mit HTML und JavaScript gemacht haben, um folgen zu können.&lt;br /&gt;
&lt;br /&gt;
== Der Server ==&lt;br /&gt;
&lt;br /&gt;
Der Server-Code deiner UserApp steht in der &#039;&#039;&#039;main.js&#039;&#039;&#039;. Wenn du nur in der &#039;&#039;&#039;main.js&#039;&#039;&#039; programmierst, läuft der ganze Code deiner UserApp ausschließlich auf den Servern von Knuddels.&amp;lt;br&amp;gt;&lt;br /&gt;
Damit kann man zwar schon viel machen, aber für mehr Interaktionsmöglichkeiten brauchst du eine grafische Oberfläche.&lt;br /&gt;
&lt;br /&gt;
== Der Client ==&lt;br /&gt;
&lt;br /&gt;
Der Code für den Client befindet sich im &#039;&#039;&#039;www&#039;&#039;&#039;-Unterordner deiner UserApp.&lt;br /&gt;
Den Einstieg bildet eine HTML-Datei, die du nennen kannst, wie du willst. Dort kannst du dann auch JavaScript-Dateien einbinden, um Code auf dem Gerät deines Besuchers auszuführen.&lt;br /&gt;
&lt;br /&gt;
Die Struktur deiner UserApp könnte dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
KnuddelJumper/&lt;br /&gt;
    www/&lt;br /&gt;
        game.html&lt;br /&gt;
        game.js&lt;br /&gt;
        player.png&lt;br /&gt;
        enemy.png&lt;br /&gt;
    main.js&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
KnuddelJumper/&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;www/&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;game.html&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;game.js&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;player.png&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;enemy.png&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;main.js&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die HTML-Datei kann dann z.B. so eine Struktur haben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- use https://mothereff.in/html-entities and replace &amp;quot; &amp;quot; with &amp;quot;&amp;amp;nbsp;&amp;quot;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
    &amp;lt;head&amp;gt;&lt;br /&gt;
        &amp;lt;script src=&amp;quot;game.js&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/head&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        &amp;lt;button&amp;gt;Hier klicken&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;#x3C;html&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;head&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;script&amp;amp;nbsp;src=&amp;amp;#x22;game.js&amp;amp;#x22;/&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/head&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;body&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;button&amp;amp;#x3E;Hier&amp;amp;nbsp;klicken&amp;amp;#x3C;/button&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;#x3C;/body&amp;amp;#x3E;&lt;br /&gt;
&amp;amp;#x3C;/html&amp;amp;#x3E;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommunikation zwischen Server und Client ==&lt;br /&gt;
&lt;br /&gt;
=== AppContent senden ===&lt;br /&gt;
&lt;br /&gt;
Die HTML-Datei und der restliche Inhalt des &#039;&#039;&#039;www&#039;&#039;&#039;-Unterordners wird [https://developer.knuddels.de/docs/classes/AppContent.html AppContent] genannt. Das ist die grafische Oberfäche deiner UserApp.&amp;lt;br&amp;gt;&lt;br /&gt;
Der AppContent erscheint aber nicht automatisch bei dem Besucher deines Channels! Du musst den AppContent erst an den Besucher (den Client) senden.&lt;br /&gt;
In der Regel macht man das direkt wenn der Besucher den Channel betritt, also in &#039;&#039;&#039;App.onUserJoined&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
var App = (new function() {&lt;br /&gt;
&lt;br /&gt;
    let htmlFile = new HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
    let appContent = AppContent.overlayContent(htmlFile, 640, 480);&lt;br /&gt;
&lt;br /&gt;
    this.onUserJoined = function(user) {&lt;br /&gt;
        user.sendAppContent(appContent);&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;htmlFile&amp;amp;nbsp;=&amp;amp;nbsp;new&amp;amp;nbsp;HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;appContent&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.overlayContent(htmlFile,&amp;amp;nbsp;640,&amp;amp;nbsp;480);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(appContent);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der [https://developer.knuddels.de/docs/classes/AppContent.html AppContent] wird so nur einmal von der App geladen und dann einfach an jeden Besucher mit [https://developer.knuddels.de/docs/classes/User.html#method_sendAppContent User.sendAppContent()] gesendet.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  Hinweis: [https://developer.knuddels.de/docs/classes/HTMLFile.html new HTMLFile()] sucht die angegebene Datei im &#039;&#039;&#039;www&#039;&#039;&#039;-Unterordner.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Damit ist dieses Tutorial eigentlich fertig:&#039;&#039;&#039; Deine Besucher sehen jetzt eine grafische Oberfläche, wenn sie deinen Channel betreten und du kannst wie auf Webseiten Scripts einbinden. Ein paar wichtige Hinweise kommen aber noch!&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der AppContent kann verschiedene &#039;&#039;&#039;ViewModes&#039;&#039;&#039; annehmen, je nachdem welche Methode du verwendest:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Overlay&#039;&#039;&#039; mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_overlayContent AppContent.overlayContent()]&lt;br /&gt;
* &#039;&#039;&#039;Popup&#039;&#039;&#039; mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_popupContent AppContent.popupContent()]&lt;br /&gt;
* &#039;&#039;&#039;Headerbar&#039;&#039;&#039; mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_headerbarContent AppContent.headerbarContent()]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Tipp:&#039;&#039;&#039; Nicht alle Geräte können jeden &#039;&#039;&#039;ViewMode&#039;&#039;&#039; anzeigen. Daher ist es gute Praxis, wenn du mit [https://developer.knuddels.de/docs/classes/User.html#method_canSendAppContent User.canSendAppContent()] entscheidest, welchen AppContent du sendest.&lt;br /&gt;
&#039;&#039;&#039;Beispiel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
var App = (new function() {&lt;br /&gt;
&lt;br /&gt;
    let htmlFile = new HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
    let overlay = AppContent.overlayContent(htmlFile, 640, 480);&lt;br /&gt;
    let popup  = AppContent.popupContent(htmlFile, 640, 480);&lt;br /&gt;
    let headerbar = AppContent.headerbarContent(htmlFile, 480);&lt;br /&gt;
&lt;br /&gt;
    this.onUserJoined = function(user) {&lt;br /&gt;
&lt;br /&gt;
        if (user.canSendAppContent(overlay)) {&lt;br /&gt;
            user.sendAppContent(overlay);&lt;br /&gt;
&lt;br /&gt;
        } else if (user.canSendAppContent(popup)) {&lt;br /&gt;
            user.sendAppContent(popup);&lt;br /&gt;
&lt;br /&gt;
        } else if (user.canSendAppContent(headerbar)) {&lt;br /&gt;
            user.sendAppContent(headerbar);&lt;br /&gt;
&lt;br /&gt;
        } else {&lt;br /&gt;
            user.sendPrivateMessage(&amp;quot;Die UserApp kann auf deinem Gerät leider nicht angezeigt werden.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;htmlFile&amp;amp;nbsp;=&amp;amp;nbsp;new&amp;amp;nbsp;HTMLFile(&amp;quot;game.html&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;overlay&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.overlayContent(htmlFile,&amp;amp;nbsp;640,&amp;amp;nbsp;480);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;popup&amp;amp;nbsp;&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.popupContent(htmlFile,&amp;amp;nbsp;640,&amp;amp;nbsp;480);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;headerbar&amp;amp;nbsp;=&amp;amp;nbsp;AppContent.headerbarContent(htmlFile,&amp;amp;nbsp;480);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(user.canSendAppContent(overlay))&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(overlay);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;if&amp;amp;nbsp;(user.canSendAppContent(popup))&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(popup);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;if&amp;amp;nbsp;(user.canSendAppContent(headerbar))&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendAppContent(headerbar);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(&amp;quot;Die&amp;amp;nbsp;UserApp&amp;amp;nbsp;kann&amp;amp;nbsp;auf&amp;amp;nbsp;deinem&amp;amp;nbsp;Gerät&amp;amp;nbsp;leider&amp;amp;nbsp;nicht&amp;amp;nbsp;angezeigt&amp;amp;nbsp;werden.&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events senden ===&lt;br /&gt;
&lt;br /&gt;
Dein Code auf dem Server und dein Code auf dem Client laufen jetzt praktisch unabhängig voneinander. Meistens ist es aber hilfreich, wenn Server und Client miteinander kommunizieren können.&lt;br /&gt;
&lt;br /&gt;
==== Client → Server ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Beispiel:&#039;&#039;&#039; Wenn der Nutzer auf der grafischen Oberfläche einen Knopf drückt, soll der AppBot eine öffentliche Nachricht in den Channel schreiben.&amp;lt;br&amp;gt;&lt;br /&gt;
Du kannst aber nur von der &#039;&#039;&#039;main.js&#039;&#039;&#039; (also vom Server aus) Chat-Nachrichten schicken. [https://developer.knuddels.de/docs/classes/BotUser.html#method_sendPublicMessage BotUser.sendPublicMessage()] funktioniert im Client nicht.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Client muss also dem Server mitteilen, dass der Nutzer einen Button gedrückt hat. Das ist mit [https://developer.knuddels.de/docs/classes/Client.html#method_sendEvent Client.sendEvent()] möglich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Client.sendEvent(&amp;quot;buttonPressed&amp;quot;, {});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei können noch zusätzliche Daten in Form eines JavaScript-Objekts mitgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Der Server kann dann in der &#039;&#039;&#039;main.js&#039;&#039;&#039; in [https://developer.knuddels.de/docs/classes/App.html#method_onEventReceived App.onEventReceived()] reagieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
var App = (new function() {&lt;br /&gt;
    &lt;br /&gt;
    //...&lt;br /&gt;
    &lt;br /&gt;
    this.onEventReceived = function(user, type, data, appContentSession) {&lt;br /&gt;
&lt;br /&gt;
        if (type == &amp;quot;buttonPressed&amp;quot;) {&lt;br /&gt;
            let bot = KnuddelsServer.getDefaultBotUser();&lt;br /&gt;
            bot.sendPublicMessage(user.getProfileLink()+&amp;quot; hat den Knopf gedrückt!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;//...&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onEventReceived&amp;amp;nbsp;=&amp;amp;nbsp;function(user,&amp;amp;nbsp;type,&amp;amp;nbsp;data,&amp;amp;nbsp;appContentSession)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(type&amp;amp;nbsp;==&amp;amp;nbsp;&amp;quot;buttonPressed&amp;quot;)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;bot&amp;amp;nbsp;=&amp;amp;nbsp;KnuddelsServer.getDefaultBotUser();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;bot.sendPublicMessage(user.getProfileLink()+&amp;quot;&amp;amp;nbsp;hat&amp;amp;nbsp;den&amp;amp;nbsp;Knopf&amp;amp;nbsp;gedrückt!&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Server → alle Clients ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Beispiel:&#039;&#039;&#039; In der &#039;&#039;&#039;main.js&#039;&#039;&#039; wird eine zufällige Zahl generiert. Diese Zahl soll an alle Besucher des Channels geschickt werden, sodass diese dann in der HTML-UI angezeigt werden kann.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit [https://developer.knuddels.de/docs/classes/AppContent.html#method_sendEvent AppContent.sendEvent()] kannst du ein Event an alle Besucher schicken, bei denen dieser AppContent aktiv ist:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let randomNumber = Math.floor(10 * Math.random());&lt;br /&gt;
appContent.sendEvent(&amp;quot;showNumber&amp;quot;, {randomNumber: number});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Client kannst du mit [https://developer.knuddels.de/docs/classes/Client.html#method_addEventListener Client.addEventListener()] auf die Events vom Server reagieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Client.addEventListener(&amp;quot;showNumber&amp;quot;, function(event) {&lt;br /&gt;
        let number = event.data.number;&lt;br /&gt;
        &lt;br /&gt;
        document.open();&lt;br /&gt;
        document.write(&amp;quot;Die magische Zahl heißt: &amp;quot;+number);&lt;br /&gt;
        document.close()&lt;br /&gt;
});&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Client.addEventListener(&amp;quot;showNumber&amp;quot;,&amp;amp;nbsp;function(event)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;number&amp;amp;nbsp;=&amp;amp;nbsp;event.data.number;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;document.open();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;document.write(&amp;quot;Die&amp;amp;nbsp;magische&amp;amp;nbsp;Zahl&amp;amp;nbsp;heißt:&amp;amp;nbsp;&amp;quot;+number);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;document.close()&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Server → ein bestimmter Client ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel:&#039;&#039;&#039; Du wählst einen Besucher zufällig aus und möchtest, dass sich bei diesem Besucher die Farbe der HTML-UI ändert.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dazu musst du vom Server aus (also in der &#039;&#039;&#039;main.js&#039;&#039;&#039;) diesem Client ein Event senden.&amp;lt;br&amp;gt;&lt;br /&gt;
Du kannst aber nicht einfach &#039;&#039;User.sendEvent()&#039;&#039; aufrufen (diesen Befehl gibt es nicht). Eine UserApp kann nämlich verschiedene &#039;&#039;&#039;ViewModes&#039;&#039;&#039; auf einmal verwenden (sogenannte &#039;&#039;&#039;AppContentSessions&#039;&#039;&#039;). Du musst der API also sagen, an welche &#039;&#039;&#039;AppContentSession&#039;&#039;&#039; du das Event senden möchtest.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn du weißt, welchen &#039;&#039;&#039;ViewMode&#039;&#039;&#039; der Besucher verwendet (z.B. weil du sowieso immer nur ein Popup sendest), kannst du einfach mit dem Befehl [https://developer.knuddels.de/docs/classes/User.html#method_getAppContentSession User.getAppContentSession] die AppContentSession erhalten und dann das Event senden. &#039;&#039;&#039;Beispiel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let appContentSession = user.getAppContentSession(AppViewMode.Popup);&lt;br /&gt;
appContentSession.sendEvent(&amp;quot;changeColor&amp;quot;, {red:255, green:0, blue:255});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn dein Client allerdings gleichzeitig mehrere aktive &#039;&#039;&#039;AppContentSessions&#039;&#039;&#039; haben könnte (z.B. eine Headerbar und ein Popup), kannst du eine Liste aller aktiven AppContentSessions eines Besuchers mit [https://developer.knuddels.de/docs/classes/User.html#method_getAppContentSessions User.getAppContentSessions()] erhalten. &#039;&#039;&#039;Beispiel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
let appContentSessions = user.getAppContentSessions();&lt;br /&gt;
&lt;br /&gt;
for (let i = 0; i &amp;lt; appContentSessions.length; i++) {&lt;br /&gt;
    let appContentSession = appContentSessions[i];&lt;br /&gt;
    appContentSession.sendEvent(&amp;quot;changeColor&amp;quot;, {red:255, green:0, blue:255});&lt;br /&gt;
}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let&amp;amp;nbsp;appContentSessions&amp;amp;nbsp;=&amp;amp;nbsp;user.getAppContentSessions();&lt;br /&gt;
&lt;br /&gt;
for&amp;amp;nbsp;(let&amp;amp;nbsp;i&amp;amp;nbsp;=&amp;amp;nbsp;0;&amp;amp;nbsp;i&amp;amp;nbsp;&amp;lt;&amp;amp;nbsp;appContentSessions.length;&amp;amp;nbsp;i++)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;appContentSession&amp;amp;nbsp;=&amp;amp;nbsp;appContentSessions[i];&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;appContentSession.sendEvent(&amp;quot;changeColor&amp;quot;,&amp;amp;nbsp;{red:255,&amp;amp;nbsp;green:0,&amp;amp;nbsp;blue:255});&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier kannst du im Client wieder mit [https://developer.knuddels.de/docs/classes/Client.html#method_addEventListener Client.addEventListener()] auf die Events reagieren.&lt;br /&gt;
&lt;br /&gt;
==== Limits ====&lt;br /&gt;
&lt;br /&gt;
Für die Daten, die du mit den Events zwischen Client und Server sendest, gibt es gewisse [[Limits]]. Diese Limits werden [[Limits|hier]] beschrieben.&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/Beginner&amp;diff=127799</id>
		<title>UserApp-Entwicklung/Tutorials/Beginner</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials/Beginner&amp;diff=127799"/>
		<updated>2019-06-26T19:28:36Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Tutorial von bitbucket hierher umgezogen, Formatierung angepasst, verbesserte Erklärung, mehr Wiki-interne Links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
In diesem Tutorial lernst du Schritt für Schritt, deine erste UserApp zu programmieren.&amp;lt;br&amp;gt;&lt;br /&gt;
Hier geht es darum, erstmal alles zum Laufen zu bringen und ein paar Basics zu vermitteln, sodass ab dann selbstständig weiterentwickelt werden kann.&lt;br /&gt;
&lt;br /&gt;
== Bevor es losgeht ==&lt;br /&gt;
&lt;br /&gt;
=== Werde Entwickler ===&lt;br /&gt;
&lt;br /&gt;
Stelle sicher, dass du ein Entwickler bist. Gib dazu &#039;&#039;&#039;/apps developer&#039;&#039;&#039; im Chat ein und erfülle die Kriterien, falls du das noch nicht getan hast.&lt;br /&gt;
&lt;br /&gt;
=== Verwende die Desktop-App ===&lt;br /&gt;
&lt;br /&gt;
Wir empfehlen dir stark, zum Entwickeln die Desktop-App auf deinem Computer zu verwenden. Du kannst die App [https://www.knuddels.de/stapp-win hier herunterladen].&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Die erste UserApp ==&lt;br /&gt;
&lt;br /&gt;
=== Entwicklungs-Server ===&lt;br /&gt;
Das Entwickeln beginnt auf dem Entwicklungs-Server. Gib &#039;&#039;&#039;/apps developer&#039;&#039;&#039; ein und wähle den Punkt &#039;&#039;&#039;Login auf Entwicklungs-Server&#039;&#039;&#039; aus. Jetzt sollte eine Desktop-Verknüpfung für den Login auf dem Entwicklungs-Server angelegt worden sein.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn du Knuddels über diese Verknüpfung startest, landest du nach dem Login auf dem Entwicklungs-Server. Hier kannst du später in Ruhe an deiner UserApp tüfteln, bevor du deine Änderungen auf dem Live-Server hochlädst.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logge dich jetzt mit den Zugangsdaten auf dem  Entwicklungsserver ein, die dir James gesendet hat (&#039;&#039;&#039;Entwickler-Nick&#039;&#039;&#039; und &#039;&#039;&#039;Entwickler-Passwort&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
  Tipp: Du kannst die Zugangsdaten aus James&#039; Nachricht mit Shift+Rechtsklick in das Chat-Fenster kopieren.&lt;br /&gt;
&lt;br /&gt;
=== MyChannel ===&lt;br /&gt;
&lt;br /&gt;
Nach dem Einloggen sollte sich automatisch das [[MyChannel]]-Edit Fenster öffnen. Ansonsten gib &#039;&#039;&#039;/mychannel&#039;&#039;&#039; ein.&amp;lt;br&amp;gt;&lt;br /&gt;
Du legst dir jetzt einen eigenen Channel an, in dem du gleich deine erste UserApp installieren wirst. Eine Info zu den Einstellungen erhältst du durch Klicken auf den Titel des jeweiligen Feldes. Außer über deinen Channel-Namen musst du dir aber erstmal keine Gedanken machen (du kannst dieses Fenster jederzeit wieder mit &#039;&#039;&#039;/mychannel&#039;&#039;&#039; öffnen). Drücke anschließend auf &#039;&#039;&#039;Speichern&#039;&#039;&#039; und &#039;&#039;&#039;Schließen&#039;&#039;&#039; und betritt deinen MyChannel mit &#039;&#039;&#039;/go &amp;lt;dein eigener Channel-Name&amp;gt;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Installation der UserApp ===&lt;br /&gt;
&lt;br /&gt;
Für dieses Tutorial haben wir dir schon Dateien für eine Beispiel-UserApp namens &amp;quot;HeyThere&amp;quot; auf den Server geladen. Installiere diese UserApp in deinem MyChannel mit &#039;&#039;&#039;/apps install HeyThere&#039;&#039;&#039;. Du kannst die UserApp später wieder aus deinem Channel löschen.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es müsste sich nun automatisch das Konfigurationsfenster für die UserApp geöffnet haben. Ansonsten öffne es selbst mit  &#039;&#039;&#039;/apps&#039;&#039;&#039; und klicke auf den Namen der UserApp (&amp;quot;HeyThere&amp;quot;).&lt;br /&gt;
  Hinweis: Durch einen Bug kann es sein, dass das Fenster auf dem Entwicklungs-Server nichts anzeigt. Schließe es einfach und öffne es gleich nochmal mit &#039;&#039;&#039;/apps&#039;&#039;&#039;. Wir hoffen, diesen Bug bald beheben zu können.&lt;br /&gt;
&lt;br /&gt;
Im Menüpunkt &amp;quot;AppBot&amp;quot; kannst du einen AppBot erstellen und an deine UserApp binden. Ein AppBot ist ein bisschen wie Butler James, nur eben für deine UserApp in deinem Channel. Drücke hierzu auf &amp;quot;hinzufügen&amp;quot; → &amp;quot;Nick anlegen&amp;quot;, denk dir einen Nicknamen aus und bestätige. Mehr dazu findest du hier: [https://bitbucket.org/knuddels/user-apps/wiki/AppBotBinden Wie binde ich einen AppBot?]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Starte jetzt deine erste UserApp.&lt;br /&gt;
  Falls sich kein entsprechendes Fenster öffnet, starte die UserApp selbst, indem du im App-Menü auf &#039;&#039;&#039;aktivieren&#039;&#039;&#039; klickst.&lt;br /&gt;
Verlasse nun deinen Channel (indem du in einen anderen Channel gehst) und betritt ihn dann wieder (z.B. mit &#039;&#039;&#039;/go &amp;lt;dein eigener Channel-Name&amp;gt;&#039;&#039;&#039;). Dein AppBot sollte dich jetzt begrüßen!&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um mit dem Entwickeln zu starten, mach mit dem nächsten Schritt weiter (FTP-Setup). Du kannst auch schon mal einen Blick in die [http://developer.knuddels.de/docs/ UserApps-API-Dokumentation] werfen.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bestimmt wird es auch mal eine Stelle geben, an der du nicht weiter weißt. Zögere nicht, [http://forum.knuddels.de/ubbthreads.php?ubb=postlist&amp;amp;Board=272&amp;amp;page=1 im Forum] Fragen zu stellen, wenn dir etwas nicht klar ist! Die anderen Entwickler sind freundlich, gehen fair miteinander um und helfen sich gerne gegenseitig.&lt;br /&gt;
&lt;br /&gt;
== FTP-Setup ==&lt;br /&gt;
&lt;br /&gt;
Du benötigst für die UserApp-Entwicklung ein FTP-Programm, um die Dateien für deine UserApp auf die Server von Knuddels hochzuladen.&lt;br /&gt;
&lt;br /&gt;
=== Was ist eigentlich FTP? ===&lt;br /&gt;
&lt;br /&gt;
FTP (File Transfer Protocol) ist ein Protokoll, mit dem Daten zwischen zwei Computern im Internet ausgetauscht werden können.&amp;lt;br&amp;gt;&lt;br /&gt;
Zum Glück gibt es ganz einfache Programme, die hinter den Kulissen dieses Protokoll sprechen, sodass du die Dateien mit wenigen Klicks hochladen kannst.&lt;br /&gt;
&lt;br /&gt;
=== Einrichtung des FTP-Zugangs ===&lt;br /&gt;
&lt;br /&gt;
Du wirst die Dateien deiner UserApp auf zwei verschiedenen Servern hochladen:&lt;br /&gt;
# auf dem &#039;&#039;&#039;Entwicklungs-Server&#039;&#039;&#039;, unter der URL &#039;&#039;&#039;devappupload.knuddels.de&#039;&#039;&#039;&lt;br /&gt;
# auf dem &#039;&#039;&#039;Live-Server&#039;&#039;&#039;, unter der URL &#039;&#039;&#039;appupload.knuddels.de&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Für beide Server musst du dir jeweils eine Verbindung einrichten. Dafür brauchst du ein FTP-Programm.&lt;br /&gt;
Schau dir dazu [https://bitbucket.org/knuddels/user-apps/wiki/Bootstrap/FTP-Setup diese Erklärung] an.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Diese Erklärung zeigt allerdings nur die Verbindung zum Live-Server&#039;&#039;&#039; - verwende für den Entwicklungs-Server stattdessen die URL &#039;&#039;&#039;devappupload.knuddels.de&#039;&#039;&#039;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als Zugangsdaten verwendest du die Zugangsdaten, die James dir geschickt hat (&#039;&#039;&#039;FTP-Nutzer&#039;&#039;&#039; und &#039;&#039;&#039;FTP-Passwort&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
  Tipp: Du kannst die Zugangsdaten aus James&#039; Nachricht mit Shift+Rechtsklick in das Chat-Fenster kopieren.&lt;br /&gt;
  Unter &#039;&#039;&#039;/apps developer&#039;&#039;&#039; kannst du sie außerdem erneut anfordern.&lt;br /&gt;
&lt;br /&gt;
Achte außerdem jeweils darauf, eine &#039;&#039;&#039;unverschlüsselte Verbindung&#039;&#039;&#039; zu wählen.&lt;br /&gt;
&lt;br /&gt;
== Beispiel-Code anschauen ==&lt;br /&gt;
&lt;br /&gt;
Wenn du weißt, wie du Dateien über den FTP-Zugang von dem Server herunter- und hochladen kannst, kannst du dir jetzt anschauen, wie eine UserApp aufgebaut ist.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Logge dich in deinem FTP-Programm auf dem Entwicklungs-Server ein, navigiere in den Ordner &#039;&#039;&#039;ftp → HeyThere&#039;&#039;&#039; und lade dort die Datei &#039;&#039;&#039;main.js&#039;&#039;&#039; herunter. Du kannst diese Datei jetzt anschauen, verändern und dann wieder dort hochladen. So verstehst du, wie alles funktioniert.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;&#039;main.js&#039;&#039;&#039; kannst du sogar im normalen Texteditor anschauen und bearbeiten.&amp;lt;br&amp;gt;&lt;br /&gt;
Empfehlenswert ist das aber nicht.&lt;br /&gt;
*Auf Windows kannst du dir (zum Beispiel) [http://notepad-plus-plus.org/ Notepad++] herunterladen.&lt;br /&gt;
* Auf macOS kannst du dir (zum Beispiel) [https://itunes.apple.com/de/app/textwrangler/id404010395?mt=12 Textwrangler] herunterladen.&lt;br /&gt;
Diese Programme können dir das Entwickeln erleichtern. (Natürlich kannst du auch eine IDE verwenden, wenn du dich damit auskennst.)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schau dir den Code jetzt an und nimm einige Veränderungen vor.&lt;br /&gt;
&lt;br /&gt;
  Idee: Lass deinen AppBot Besucher abhängig von ihrem Geschlecht begrüßen! Zum Beispiel männliche Besucher mit &amp;quot;Hey Prinz &amp;lt;Nickname&amp;gt;&amp;quot; und weibliche Besucher mit &amp;quot;Hey Prinzessin &amp;lt;Nickname&amp;gt;&amp;quot;. Findest du heraus, wie das geht?&lt;br /&gt;
&lt;br /&gt;
→ Jetzt ist ein guter Zeitpunkt, die [https://developer.knuddels.de/docs/ API-Dokumentation] anzuschauen.&lt;br /&gt;
Der Aufbau der &#039;&#039;&#039;main.js&#039;&#039;&#039; wird [https://bitbucket.org/knuddels/user-apps/wiki/Bootstrap/App-Erstellen hier] erklärt.&lt;br /&gt;
&lt;br /&gt;
Gehe danach folgendermaßen vor:&lt;br /&gt;
# Verändere die Datei und speichere sie.&lt;br /&gt;
# Lade die Datei auf den FTP-Server hoch (ersetze die alte &#039;&#039;&#039;main.js&#039;&#039;&#039;).&lt;br /&gt;
# Öffne das App-Menü in deinem Channel mit &#039;&#039;&#039;/apps&#039;&#039;&#039; und drücke auf &#039;&#039;&#039;update/restart&#039;&#039;&#039;. Deine App fährt herunter und startet nach wenigen Sekunden erneut - mit deinem neuen Code.&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt wird gezeigt, wie man Besucher abhängig von ihrem Geschlecht begrüßen kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Begrüße Besucher abhängig von ihrem Geschlecht ==&lt;br /&gt;
&lt;br /&gt;
So kannst du neuen Besuchern eine Begrüßungsnachricht abhängig von ihrem Geschlecht schicken:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;main.js&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;!-- schneller Workaround (&amp;lt;code&amp;gt; ist kaputt, whitespaces werden gestript): Leerzeichen durch &amp;amp;nbsp; ersetzen --&amp;gt;&lt;br /&gt;
&amp;lt;!-- in Python: print(&amp;quot;code() {...}&amp;quot;.replace(&amp;quot; &amp;quot;, &amp;quot;&amp;amp;nbsp;&amp;quot;)) --&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&amp;amp;nbsp;&amp;amp;nbsp;//&amp;amp;nbsp;diese&amp;amp;nbsp;Funktion&amp;amp;nbsp;wird&amp;amp;nbsp;aufgerufen,&amp;amp;nbsp;wenn&amp;amp;nbsp;ein&amp;amp;nbsp;Nutzer&amp;amp;nbsp;den&amp;amp;nbsp;Channel&amp;amp;nbsp;betritt&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;gender&amp;amp;nbsp;=&amp;amp;nbsp;user.getGender();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;nick&amp;amp;nbsp;&amp;amp;nbsp;=&amp;amp;nbsp;user.getNick();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;title;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(gender&amp;amp;nbsp;==&amp;amp;nbsp;Gender.Male)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;title&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Prinz&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;nick;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;if&amp;amp;nbsp;(gender&amp;amp;nbsp;==&amp;amp;nbsp;Gender.Female)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;title&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Prinzessin&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;nick;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&amp;amp;nbsp;else&amp;amp;nbsp;{&amp;amp;nbsp;&amp;amp;nbsp;//&amp;amp;nbsp;der&amp;amp;nbsp;Nutzer&amp;amp;nbsp;hat&amp;amp;nbsp;sich&amp;amp;nbsp;nicht&amp;amp;nbsp;als&amp;amp;nbsp;männlich&amp;amp;nbsp;oder&amp;amp;nbsp;weiblich&amp;amp;nbsp;ausgegeben&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;title&amp;amp;nbsp;=&amp;amp;nbsp;nick;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;message&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Hey&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;title&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;,&amp;amp;nbsp;willkommen&amp;amp;nbsp;im&amp;amp;nbsp;Channel!&amp;amp;nbsp;Du&amp;amp;nbsp;bist&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;user.getAge()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;Jahre&amp;amp;nbsp;alt.&amp;quot;;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(message);&amp;amp;nbsp;&amp;amp;nbsp;//&amp;amp;nbsp;der&amp;amp;nbsp;AppBot&amp;amp;nbsp;sendet&amp;amp;nbsp;eine&amp;amp;nbsp;private&amp;amp;nbsp;Nachricht&amp;amp;nbsp;an&amp;amp;nbsp;den&amp;amp;nbsp;Nutzer&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schaffst du es außerdem, die Besucher sowohl abhängig von ihrem Alter, als auch von ihrem Geschlecht zu begrüßen?   &lt;br /&gt;
→ Begrüße Besucher...&lt;br /&gt;
* unter 18 Jahren mit: &#039;&#039;&#039;&amp;quot;Hallo Junge &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;quot;Hallo Mädchen &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
* zwischen 18 und 60 Jahren mit: &#039;&#039;&#039;&amp;quot;Hallo Herr &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;quot;Hallo Frau &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
* über 60 Jahren mit: &#039;&#039;&#039;&amp;quot;Hallo Opa &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039; bzw. &#039;&#039;&#039;&amp;quot;Hallo Oma &amp;lt;Nickname&amp;gt;&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Schau in die [https://developer.knuddels.de/docs/ UserApps-API-Dokumentation], wenn du eine Funktion suchst.&lt;br /&gt;
Den fertigen Code kannst du dir hier herunterladen: [https://bitbucket.org/knuddels/user-apps/downloads/Beispielcode%20HeyThere%20-%20Stufe%202%20-%20Erweiterung.zip Begrüßung nach Alter und Geschlecht]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt lernst du, wie Besucher &#039;&#039;&#039;Knuddel&#039;&#039;&#039; an deinen AppBot transferieren können!&lt;br /&gt;
&lt;br /&gt;
== Knuddel überweisen ==&lt;br /&gt;
&lt;br /&gt;
Nutzer können Knuddel an deinen AppBot überweisen. Diese Knuddel kannst du dir dann später auf deinen eigenen Nick überweisen lassen. Hier lernst du, wie du das in deiner UserApp machen kannst.&lt;br /&gt;
&lt;br /&gt;
Der AppBot soll jeden neuen Nutzer nach einem Knuddel fragen. Wenn er diesen bekommt, bedankt er sich bei dem Nutzer.&lt;br /&gt;
&lt;br /&gt;
  Auf dem Entwicklungs-Server hat dein Nick so viele Knuddel, dass du das einfach testen kannst.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;main.js&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;appBotNick&amp;amp;nbsp;=&amp;amp;nbsp;KnuddelsServer.getDefaultBotUser().getNick();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;message&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Gibst&amp;amp;nbsp;du&amp;amp;nbsp;mir&amp;amp;nbsp;_°BB°°&amp;gt;_heinen&amp;amp;nbsp;Knuddel|/appknuddel&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;appBotNick.escapeKCode()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;&amp;lt;°°°_?&amp;quot;;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(message);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onKnuddelReceived&amp;amp;nbsp;=&amp;amp;nbsp;function(sender,&amp;amp;nbsp;receiver,&amp;amp;nbsp;knuddelAmount,&amp;amp;nbsp;transferReason)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;sender.sendPrivateMessage(&amp;quot;Danke,&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;sender.getNick()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;!&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Erklärung: Was ist KCode? ===&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;App.onUserJoined&#039;&#039;&#039; wird dem Nutzer eine Nachricht mit seltsamen Zeichen gesendet:  &lt;br /&gt;
&lt;br /&gt;
  &amp;quot;Gibst du mir _°BB°°&amp;gt;_heinen Knuddel|/appknuddel &amp;quot; + appBotNick.escapeKCode() + &amp;quot;&amp;lt;°°°_?&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Das ist [[Formatierungen|KCode]]. Dieser Code wird vor dem Anzeigen umgewandelt, sodass die Nutzer einen Link präsentiert bekommen, auf dessen Klick hin ein Befehl ausgeführt wird: Hier ist dieser Befehl &#039;&#039;&#039;/appknuddel &amp;lt;Nickname des AppBots&amp;gt;&#039;&#039;&#039;. Mit dem Klicken auf den Link überweist der Nutzer also einen Knuddel an den AppBot.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;appBotNick.escapeKCode()&#039;&#039;&#039; dient dazu, dass der Befehl auch bei Sonderzeichen im Nicknamen deines AppBots richtig ausgeführt wird.&lt;br /&gt;
&lt;br /&gt;
[[Formatierungen|→ Hier kannst du dir anschauen, wie KCode funktioniert.]]&lt;br /&gt;
&lt;br /&gt;
  Idee für wahre Kapitalisten: Du kannst den Besucher deines Channels vielleicht dazu bringen, dem AppBot einen Knuddel zu schenken, wenn der AppBot dem Besucher nach einiger Zeit eine traurige Nachricht schreibt, falls er bis dahin keinen Knuddel von dem Besucher erhalten hat.&lt;br /&gt;
&lt;br /&gt;
Eine mögliche Lösung dieses Problems kannst du dir hier anschauen: [https://bitbucket.org/knuddels/user-apps/downloads/Beispielcode%20HeyThere%20-%20Stufe%203%20-%20Erweiterung.zip Download Code-Beispiel (Traurige Nachricht vom AppBot)]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im nächsten Schritt lernst du, wie du dauerhaft Daten über deine Besucher speichern kannst.&lt;br /&gt;
&lt;br /&gt;
== UserPersistence: Nutzerdaten speichern ==&lt;br /&gt;
&lt;br /&gt;
Wenn du dir beispielsweise dauerhaft merken willst, wie viele Knuddel ein Nutzer jeweils schon deinem AppBot überwiesen hat, brauchst du eine Möglichkeit, zu jedem Nutzer eine Zahl zu speichern.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  Allerdings kannst du nicht einfach eine Variable in deinem Code haben, worüber du alles speicherst - das wäre nämlich mit jedem Neustart der App wieder weg.&lt;br /&gt;
&lt;br /&gt;
In der [https://developer.knuddels.de/docs/ UserApps-API] gibt es genau dafür das Objekt [https://developer.knuddels.de/docs/classes/UserPersistence.html UserPersistence].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;main.js&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var&amp;amp;nbsp;App&amp;amp;nbsp;=&amp;amp;nbsp;(new&amp;amp;nbsp;function()&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onUserJoined&amp;amp;nbsp;=&amp;amp;nbsp;function(user)&amp;amp;nbsp;{&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;userPersistence&amp;amp;nbsp;=&amp;amp;nbsp;user.getPersistence();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;userSpending&amp;amp;nbsp;=&amp;amp;nbsp;userPersistence.getNumber(&amp;quot;spending&amp;quot;,&amp;amp;nbsp;0);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;if&amp;amp;nbsp;(userSpending&amp;amp;nbsp;&amp;gt;&amp;amp;nbsp;10)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(&amp;quot;Willkommen,&amp;amp;nbsp;gütiger&amp;amp;nbsp;Spender!&amp;quot;);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;appBotNick&amp;amp;nbsp;=&amp;amp;nbsp;KnuddelsServer.getDefaultBotUser().getNick();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;var&amp;amp;nbsp;message&amp;amp;nbsp;=&amp;amp;nbsp;&amp;quot;Gibst&amp;amp;nbsp;du&amp;amp;nbsp;mir&amp;amp;nbsp;_°BB°°&amp;gt;_heinen&amp;amp;nbsp;Knuddel|/appknuddel&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;appBotNick.escapeKCode()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;&amp;lt;°°°_?&amp;quot;;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;user.sendPrivateMessage(message);&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;this.onKnuddelReceived&amp;amp;nbsp;=&amp;amp;nbsp;function(sender,&amp;amp;nbsp;receiver,&amp;amp;nbsp;knuddelAmount,&amp;amp;nbsp;transferReason)&amp;amp;nbsp;{&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;sender.sendPrivateMessage(&amp;quot;Danke,&amp;amp;nbsp;&amp;quot;&amp;amp;nbsp;+&amp;amp;nbsp;sender.getNick()&amp;amp;nbsp;+&amp;amp;nbsp;&amp;quot;!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;let&amp;amp;nbsp;userPersistence&amp;amp;nbsp;=&amp;amp;nbsp;sender.getPersistence();&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;userPersistence.addNumber(&amp;quot;spending&amp;quot;,&amp;amp;nbsp;knuddelAmount.asNumber());&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;}&lt;br /&gt;
}());&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die App merkt sich nun, wie viele Knuddel deine Besucher bereits eingezahlt haben. Besonders gönnerische Besucher begrüßt er ehrerbietig!&lt;br /&gt;
&lt;br /&gt;
== Dein Fortschitt ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Du bist schon weit gekommen!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Du hast gelernt, wie man sich auf dem Entwicklungs-Server anmeldet und eine App installiert.&lt;br /&gt;
* Du hast dich mit FTP vertraut gemacht und kannst deine Dateien jetzt einfach an den Knuddels-Server senden.&lt;br /&gt;
* Du weißt jetzt, wie man auf verschiedene Events in deinem Channel reagiert.&lt;br /&gt;
* Du bist mit der Überweisung von Knuddel an deinen AppBot vertraut.&lt;br /&gt;
* Du kannst Daten über deine Besucher dauerhaft speichern.&lt;br /&gt;
&lt;br /&gt;
Jetzt kannst du deine UserApp mal veröffentlichen! Dazu musst du deine UserApp per FTP auf dem Live-Server hochladen - so wie schon vorher auf dem Entwicklungs-Server. Melde dich dann ganz normal bei Knuddels an und installiere deine UserApp mit &#039;&#039;&#039;/apps install &amp;lt;UserApp-Name&amp;gt;&#039;&#039;&#039; in deinem MyChannel.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und wenn du jetzt noch deinen MyChannel unter &#039;&#039;&#039;/mychannel&#039;&#039;&#039; veröffentlichst, können auch andere Nutzer zufällig auf deinen MyChannel stoßen.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Wie geht&#039;s weiter? ==&lt;br /&gt;
&lt;br /&gt;
Vielleicht hast du Lust, ein grafisches Spiel zu programmieren? Oder ein textbasiertes RPG?&amp;lt;br&amp;gt;&lt;br /&gt;
Ab jetzt bist du dir selbst überlassen - und kannst dich natürlich jederzeit an die Community wenden.&amp;lt;br&amp;gt;&lt;br /&gt;
Auf dem Entwickler-Portal [https://developer.knuddels.de/ developer.knuddels.de] findest du das meiste im Zusammenhang mit UserApps.&lt;br /&gt;
&lt;br /&gt;
[[UserApp-Entwicklung|→ Übersicht: UserApp-Entwicklung]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung&amp;diff=127794</id>
		<title>UserApp-Entwicklung</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung&amp;diff=127794"/>
		<updated>2019-06-26T16:55:03Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Link auf Tutorial-Übersicht und Beginner-Tutorial hinzugefügt.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Hier findest du alles was du wissen musst, um deine eigene UserApp auf Knuddels zu programmieren.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn du noch nicht weißt, was eine [[User_App|UserApp]] ist, schau einfach [[User_App|hier]].&amp;lt;br&amp;gt;&lt;br /&gt;
Einen Überblick über alles im Zusammenhang mit UserApps (auch dieses Wiki) findest du auf dem Entwickler-Portal unter [https://developer.knuddels.de/ developer.knuddels.de].&lt;br /&gt;
&lt;br /&gt;
== Tutorials https://knuddels-wiki.de/images/c/c9/Icon_-_Newbie.gif ==&lt;br /&gt;
&lt;br /&gt;
Wenn du noch keine UserApp entwickelt hast, kannst du das Beginner-Tutorial machen. Dort lernst du Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Beginner-Tutorial]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Hier findest du eine Übersicht über alle Tutorials:&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials]]&lt;br /&gt;
&lt;br /&gt;
== Wichtige Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://developer.knuddels.de/ developer.knuddels.de] - das Entwickler-Portal (Überblick über alles im Zusammenhang mit UserApps)&lt;br /&gt;
* [https://developer.knuddels.de/docs/ UserApps-API Docs]&lt;br /&gt;
* [https://www.knuddels.de/changelog Changelog]&lt;br /&gt;
&lt;br /&gt;
== Andere UserApps-Entwickler ==&lt;br /&gt;
&lt;br /&gt;
* Wir freuen uns, wenn sich neue Entwickler kurz [https://forum.knuddels.de/ubbthreads.php?ubb=showflat&amp;amp;Number=2704910 im Forum vorstellen]. Aber das ist natürlich kein Muss.&lt;br /&gt;
* Die Kommunikation findet über den Discord Server statt.&amp;lt;br&amp;gt;Gib &#039;&#039;&#039;/apps developer&#039;&#039;&#039; ein und klicke auf den entsprechenden Link.&amp;lt;br&amp;gt;[https://blog.knuddels.de/2018/07/31/kommunikation-zukuenftig-auf-discord/ → Blogeintrag dazu]&lt;br /&gt;
* Außerdem gibt es im [https://forum.knuddels.de/ubbthreads.php?ubb=cfrm&amp;amp;c=9 UserApps-Forum] viele Beiträge!&lt;br /&gt;
&lt;br /&gt;
== Die UserApps-API https://knuddels-wiki.de/images/2/29/Quiz-Smiley.gif ==&lt;br /&gt;
&lt;br /&gt;
Willst du mehr über die UserApps-API wissen? Schau mal hier rein:&lt;br /&gt;
&lt;br /&gt;
* [[API|Was ist die UserApps-API?]]&lt;br /&gt;
* [https://developer.knuddels.de/docs/ UserApps-API Docs]&lt;br /&gt;
&lt;br /&gt;
== Design &amp;amp; Grafik in UserApps https://knuddels-wiki.de/images/a/a0/Rose.gif ==&lt;br /&gt;
&lt;br /&gt;
UserApps können natürlich auch Grafiken, Animationen und Sounds wiedergeben! Du kannst sogar ein 3D-Spiel als UserApp programmieren!&lt;br /&gt;
Mindestens kannst du aber mal &#039;&#039;&#039;KCode&#039;&#039;&#039; lernen, falls du das noch nicht getan hast.  &lt;br /&gt;
Schau dir als Einstieg folgende Links an:&lt;br /&gt;
&lt;br /&gt;
* Texte vom AppBot formatieren: [[Formatierungen]]&lt;br /&gt;
* Grafische Web-Oberfläche&lt;br /&gt;
** [[User_App:HTML-UI/Web|Einführung 1]]&lt;br /&gt;
** [https://bitbucket.org/knuddels/user-apps/wiki/HTML-UI/Web Einführung 2]&lt;br /&gt;
** [https://bitbucket.org/knuddels/user-apps/wiki/HTML-UI/Environment Besonderheiten der HTML-UI (Environment)]&lt;br /&gt;
&lt;br /&gt;
== Technische Infos ==&lt;br /&gt;
&lt;br /&gt;
* [https://bitbucket.org/knuddels/user-apps/wiki/Development Development] - einige Basics und technische Infos&lt;br /&gt;
* [[Limits|Technische Limits]] für UserApps&lt;br /&gt;
&lt;br /&gt;
== Bugs ==&lt;br /&gt;
&lt;br /&gt;
Wenn du einen Bug bemerkt hast, kannst du jemanden im &#039;&#039;&#039;/team bugs&#039;&#039;&#039; anschreiben.  &lt;br /&gt;
Deine Ideen und Wünsche kannst du mit uns auf Discord teilen.&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung&amp;diff=127793</id>
		<title>UserApp-Entwicklung</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung&amp;diff=127793"/>
		<updated>2019-06-26T16:46:52Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Technische Limits verweist jetzt auf den Artikel im Wiki (ehem. bitbucket)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Hier findest du alles was du wissen musst, um deine eigene UserApp auf Knuddels zu programmieren.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn du noch nicht weißt, was eine [[User_App|UserApp]] ist, schau einfach [[User_App|hier]].&amp;lt;br&amp;gt;&lt;br /&gt;
Einen Überblick über alles im Zusammenhang mit UserApps (auch dieses Wiki) findest du auf dem Entwickler-Portal unter [https://developer.knuddels.de/ developer.knuddels.de].&lt;br /&gt;
&lt;br /&gt;
== Tutorial für Anfänger https://knuddels-wiki.de/images/c/c9/Icon_-_Newbie.gif ==&lt;br /&gt;
&lt;br /&gt;
In [https://bitbucket.org/knuddels/user-apps/wiki/Tutorial diesem Tutorial] lernst du Schritt für Schritt, deine erste UserApp zu programmieren: → [https://bitbucket.org/knuddels/user-apps/wiki/Tutorial Tutorial]&amp;lt;br&amp;gt;&lt;br /&gt;
Alternativ gibt es noch [[User_Apps/Tutorial|dieses Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Wichtige Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://developer.knuddels.de/ developer.knuddels.de] - das Entwickler-Portal (Überblick über alles im Zusammenhang mit UserApps)&lt;br /&gt;
* [https://www.knuddels.de/changelog Changelog]&lt;br /&gt;
* [https://developer.knuddels.de/docs/ UserApps-API Docs]&lt;br /&gt;
&lt;br /&gt;
== Andere UserApps-Entwickler ==&lt;br /&gt;
&lt;br /&gt;
* Wir freuen uns, wenn sich neue Entwickler kurz [https://forum.knuddels.de/ubbthreads.php?ubb=showflat&amp;amp;Number=2704910 im Forum vorstellen]. Aber das ist natürlich kein Muss.&lt;br /&gt;
* Die Kommunikation findet über den Discord Server statt.&amp;lt;br&amp;gt;Gib &#039;&#039;&#039;/apps developer&#039;&#039;&#039; ein und klicke auf den entsprechenden Link.&amp;lt;br&amp;gt;[https://blog.knuddels.de/2018/07/31/kommunikation-zukuenftig-auf-discord/ → Blogeintrag dazu]&lt;br /&gt;
* Außerdem gibt es im [https://forum.knuddels.de/ubbthreads.php?ubb=cfrm&amp;amp;c=9 UserApps-Forum] viele Beiträge!&lt;br /&gt;
&lt;br /&gt;
== Die UserApps-API https://knuddels-wiki.de/images/2/29/Quiz-Smiley.gif ==&lt;br /&gt;
&lt;br /&gt;
Willst du mehr über die UserApps-API wissen? Schau mal hier rein:&lt;br /&gt;
&lt;br /&gt;
* [[API|Was ist die UserApps-API?]]&lt;br /&gt;
* [https://developer.knuddels.de/docs/ UserApps-API Docs]&lt;br /&gt;
&lt;br /&gt;
== Design &amp;amp; Grafik in UserApps https://knuddels-wiki.de/images/a/a0/Rose.gif ==&lt;br /&gt;
&lt;br /&gt;
UserApps können natürlich auch Grafiken, Animationen und Sounds wiedergeben! Du kannst sogar ein 3D-Spiel als UserApp programmieren!&lt;br /&gt;
Mindestens kannst du aber mal &#039;&#039;&#039;KCode&#039;&#039;&#039; lernen, falls du das noch nicht getan hast.  &lt;br /&gt;
Schau dir als Einstieg folgende Links an:&lt;br /&gt;
&lt;br /&gt;
* Texte vom AppBot formatieren: [[Formatierungen]]&lt;br /&gt;
* Grafische Web-Oberfläche&lt;br /&gt;
** [[User_App:HTML-UI/Web|Einführung 1]]&lt;br /&gt;
** [https://bitbucket.org/knuddels/user-apps/wiki/HTML-UI/Web Einführung 2]&lt;br /&gt;
** [https://bitbucket.org/knuddels/user-apps/wiki/HTML-UI/Environment Besonderheiten der HTML-UI (Environment)]&lt;br /&gt;
&lt;br /&gt;
== Technische Infos ==&lt;br /&gt;
&lt;br /&gt;
* [https://bitbucket.org/knuddels/user-apps/wiki/Development Development] - einige Basics und technische Infos&lt;br /&gt;
* [[Limits|Technische Limits]] für UserApps&lt;br /&gt;
&lt;br /&gt;
== Bugs ==&lt;br /&gt;
&lt;br /&gt;
Wenn du einen Bug bemerkt hast, kannst du jemanden im &#039;&#039;&#039;/team bugs&#039;&#039;&#039; anschreiben.  &lt;br /&gt;
Deine Ideen und Wünsche kannst du mit uns auf Discord teilen.&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=127792</id>
		<title>UserApp-Entwicklung/Tutorials</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung/Tutorials&amp;diff=127792"/>
		<updated>2019-06-26T16:03:06Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Hier werden alle Tutorials gesammelt, nach Themen und Schwierigkeitsgrad gegliedert. Kann gerne ergänzt werden.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier ist eine Sammlung aller Tutorials zur UserApp-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
== Beginner ==&lt;br /&gt;
Hier lernst du Schritt für Schritt, deine erste UserApp zu programmieren.&lt;br /&gt;
* [[UserApp-Entwicklung/Tutorials/Beginner|Tutorial für Beginner]]&lt;br /&gt;
&lt;br /&gt;
== Weitere Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[User_Apps/Tutorial]]&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
	<entry>
		<id>https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung&amp;diff=127791</id>
		<title>UserApp-Entwicklung</title>
		<link rel="alternate" type="text/html" href="https://knuddels-wiki.de/index.php?title=UserApp-Entwicklung&amp;diff=127791"/>
		<updated>2019-06-26T14:46:24Z</updated>

		<summary type="html">&lt;p&gt;Tom Unterwegs: Seite neu angelegt um das UserApps-Wiki zwecks Zentralisierung von bitbucket hierher umzuziehen.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines ==&lt;br /&gt;
&lt;br /&gt;
Hier findest du alles was du wissen musst, um deine eigene UserApp auf Knuddels zu programmieren.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn du noch nicht weißt, was eine [[User_App|UserApp]] ist, schau einfach [[User_App|hier]].&amp;lt;br&amp;gt;&lt;br /&gt;
Einen Überblick über alles im Zusammenhang mit UserApps (auch dieses Wiki) findest du auf dem Entwickler-Portal unter [https://developer.knuddels.de/ developer.knuddels.de].&lt;br /&gt;
&lt;br /&gt;
== Tutorial für Anfänger https://knuddels-wiki.de/images/c/c9/Icon_-_Newbie.gif ==&lt;br /&gt;
&lt;br /&gt;
In [https://bitbucket.org/knuddels/user-apps/wiki/Tutorial diesem Tutorial] lernst du Schritt für Schritt, deine erste UserApp zu programmieren: → [https://bitbucket.org/knuddels/user-apps/wiki/Tutorial Tutorial]&amp;lt;br&amp;gt;&lt;br /&gt;
Alternativ gibt es noch [[User_Apps/Tutorial|dieses Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Wichtige Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://developer.knuddels.de/ developer.knuddels.de] - das Entwickler-Portal (Überblick über alles im Zusammenhang mit UserApps)&lt;br /&gt;
* [https://www.knuddels.de/changelog Changelog]&lt;br /&gt;
* [https://developer.knuddels.de/docs/ UserApps-API Docs]&lt;br /&gt;
&lt;br /&gt;
== Andere UserApps-Entwickler ==&lt;br /&gt;
&lt;br /&gt;
* Wir freuen uns, wenn sich neue Entwickler kurz [https://forum.knuddels.de/ubbthreads.php?ubb=showflat&amp;amp;Number=2704910 im Forum vorstellen]. Aber das ist natürlich kein Muss.&lt;br /&gt;
* Die Kommunikation findet über den Discord Server statt.&amp;lt;br&amp;gt;Gib &#039;&#039;&#039;/apps developer&#039;&#039;&#039; ein und klicke auf den entsprechenden Link.&amp;lt;br&amp;gt;[https://blog.knuddels.de/2018/07/31/kommunikation-zukuenftig-auf-discord/ → Blogeintrag dazu]&lt;br /&gt;
* Außerdem gibt es im [https://forum.knuddels.de/ubbthreads.php?ubb=cfrm&amp;amp;c=9 UserApps-Forum] viele Beiträge!&lt;br /&gt;
&lt;br /&gt;
== Die UserApps-API https://knuddels-wiki.de/images/2/29/Quiz-Smiley.gif ==&lt;br /&gt;
&lt;br /&gt;
Willst du mehr über die UserApps-API wissen? Schau mal hier rein:&lt;br /&gt;
&lt;br /&gt;
* [[API|Was ist die UserApps-API?]]&lt;br /&gt;
* [https://developer.knuddels.de/docs/ UserApps-API Docs]&lt;br /&gt;
&lt;br /&gt;
== Design &amp;amp; Grafik in UserApps https://knuddels-wiki.de/images/a/a0/Rose.gif ==&lt;br /&gt;
&lt;br /&gt;
UserApps können natürlich auch Grafiken, Animationen und Sounds wiedergeben! Du kannst sogar ein 3D-Spiel als UserApp programmieren!&lt;br /&gt;
Mindestens kannst du aber mal &#039;&#039;&#039;KCode&#039;&#039;&#039; lernen, falls du das noch nicht getan hast.  &lt;br /&gt;
Schau dir als Einstieg folgende Links an:&lt;br /&gt;
&lt;br /&gt;
* Texte vom AppBot formatieren: [[Formatierungen]]&lt;br /&gt;
* Grafische Web-Oberfläche&lt;br /&gt;
** [[User_App:HTML-UI/Web|Einführung 1]]&lt;br /&gt;
** [https://bitbucket.org/knuddels/user-apps/wiki/HTML-UI/Web Einführung 2]&lt;br /&gt;
** [https://bitbucket.org/knuddels/user-apps/wiki/HTML-UI/Environment Besonderheiten der HTML-UI (Environment)]&lt;br /&gt;
&lt;br /&gt;
== Technische Infos ==&lt;br /&gt;
&lt;br /&gt;
* [https://bitbucket.org/knuddels/user-apps/wiki/Development Development] - einige Basics und technische Infos&lt;br /&gt;
* [https://bitbucket.org/knuddels/user-apps/wiki/Limits/ Limits] - Daten-Limits für UserApps&lt;br /&gt;
&lt;br /&gt;
== Bugs ==&lt;br /&gt;
&lt;br /&gt;
Wenn du einen Bug bemerkt hast, kannst du jemanden im &#039;&#039;&#039;/team bugs&#039;&#039;&#039; anschreiben.  &lt;br /&gt;
Deine Ideen und Wünsche kannst du mit uns auf Discord teilen.&lt;/div&gt;</summary>
		<author><name>Tom Unterwegs</name></author>
	</entry>
</feed>