NEWS
[Gelöst] text2command mit Telegram: verkettete Befehle...?
-
Hallo zusammen,
ich möchte per Telegram ein Datum in einem Datenpunkt speichern. Um die Eingabe zu erleichtern habe ich mir per Javascript die Arrays für die Telegram-Tastaturen zusammengebaut:
- Jahr (dieses, sowie 3 folgenden)
- Monat (abhängig vom Jahr - dieser Monat bis zum Ende des Jahres oder alle Monate, wenn das gewählte Jahr in der Zukunft liegt)
- Tag (abhängig von Jahr und Monat - heute bis zum Ende des Monats, oder alle Tage zukünftiger Monate)
Das ist meiner Ansicht nach intuitiv und man kann kein Datum aus der Vergangenheit wählen.
Jetzt kommt die Schwierigkeit: das ganze muss auch verarbeitet werden und so stelle ich mir das vor:
- man sendet ein Schlüsselwort als Befehl, auf den Text2Command reagiert, die Tastatur für die Jahresauswahl wird angezeigt
- Man wählt das Jahr, gesendet wird zum Beispiel
2023, das irgendwo gespeichert wird - Die Tastatur für den Monat wird angezeigt
- Man wählt den Monat, zum Beispiel
Jan, der wieder irgendwo gespeichert wird - Die Tastatur für den Tag wird angezeigt
- Man wählt den Tag, zum Beispiel
12, der wieder irgendwo gespeichert wird
Erst jetzt ist die Eingabe abgeschlossen.
Was nicht passieren darf ist, dass ich aus dem Nichts heraus einfach nur
23über die ganz normale Tastatur eingebe und dies als Teil des Datums interpretiert wird, wenn ich nicht zuvor das Schlüsselwort gesendet habe.War das irgendwie verständlich? Hat jemand eine Idee, wie man das lösen kann?
-
Hallo zusammen,
ich möchte per Telegram ein Datum in einem Datenpunkt speichern. Um die Eingabe zu erleichtern habe ich mir per Javascript die Arrays für die Telegram-Tastaturen zusammengebaut:
- Jahr (dieses, sowie 3 folgenden)
- Monat (abhängig vom Jahr - dieser Monat bis zum Ende des Jahres oder alle Monate, wenn das gewählte Jahr in der Zukunft liegt)
- Tag (abhängig von Jahr und Monat - heute bis zum Ende des Monats, oder alle Tage zukünftiger Monate)
Das ist meiner Ansicht nach intuitiv und man kann kein Datum aus der Vergangenheit wählen.
Jetzt kommt die Schwierigkeit: das ganze muss auch verarbeitet werden und so stelle ich mir das vor:
- man sendet ein Schlüsselwort als Befehl, auf den Text2Command reagiert, die Tastatur für die Jahresauswahl wird angezeigt
- Man wählt das Jahr, gesendet wird zum Beispiel
2023, das irgendwo gespeichert wird - Die Tastatur für den Monat wird angezeigt
- Man wählt den Monat, zum Beispiel
Jan, der wieder irgendwo gespeichert wird - Die Tastatur für den Tag wird angezeigt
- Man wählt den Tag, zum Beispiel
12, der wieder irgendwo gespeichert wird
Erst jetzt ist die Eingabe abgeschlossen.
Was nicht passieren darf ist, dass ich aus dem Nichts heraus einfach nur
23über die ganz normale Tastatur eingebe und dies als Teil des Datums interpretiert wird, wenn ich nicht zuvor das Schlüsselwort gesendet habe.War das irgendwie verständlich? Hat jemand eine Idee, wie man das lösen kann?
Ich habs hinbekommen :)
Laut der Github-Doku des Adapters kann man Regeln auch per Script verarbeiten:
https://github.com/ioBroker/ioBroker.text2command#external-rules-with-javascriptDas Script reagiert immer auf Telegram-Eingaben, wird aber tatsächlich nur dann aktiv, wenn es das wirklich soll. Und so sieht es dann aus:

(sorry für die schlechte Qualität, das Original war viel zu groß für einen Upload hier)Der initiale Aufruf erfolgt über den text2command-Adapter:

Damit bei einem Neustart das Script nicht in einen undefinierten Zustand fährt, wird intern nochmal abgefragt, ob wirklich der Befehl gesendet wurde. Man kennt das ja, die ganzen Tastaturscripte werden ausgeführt, sobald man den Javascript-Adapter neustartet, wenn man keine Vorkehrungen trifft.
Der Rest erklärt sich glaube ich von selbst. Was jetzt natürlich noch geschehen muss ist, dass das eingegebene Datum weiterverarbeitet werden muss, aber das ist ja ein ganz anderes Thema.
Das Script benötigt diese Datenpunkte (bitte manuell anlegen):
0_userdata.0.Telegram.text2command.datePicker_Datum-> String
0_userdata.0.Telegram.text2command.datePicker_Jahr-> Number
0_userdata.0.Telegram.text2command.datePicker_Monat-> Number
0_userdata.0.Telegram.text2command.datePicker_Tag-> Number
0_userdata.0.Telegram.text2command.textProcessor-> String oder mixedLetzterer muss auch in den Einstellungen des text2command-Adapters hinterlegt werden.
var today = new Date(); var currentYear = today.getYear() + 1900; var currentMonth = today.getMonth(); var currentDay = today.getDate(); var currentWeekday = today.getDay(); const months = ['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez']; var year = 0; var month = 0; var day = 0; function go() { // Bei Auslösung Status schreiben damit klar ist, dass reagiert werden muss setState("0_userdata.0.Telegram.text2command.datePicker_Datum", 'running'); // Mit Jahreseingabe beginnen keyboardYear(); }; function keyboardYear () { // Tastatur für die Jahresauswahl zusammenbauen var yearKeys = [ [currentYear.toString(), (currentYear + 1).toString()], [(currentYear + 2).toString(), (currentYear + 3).toString()], ["Abbrechen", ""] ] // Tastatur senden sendTo('telegram.0', { text: 'Jahr wählen', reply_markup: { keyboard: yearKeys, resize_keyboard: true, one_time_keyboard: false } }); }; function keyboardMonth () { // Tastatur für die Monatsauswahl zusammenbauen var avMonths = new Array(11); var monthKeys = new Array(4); year = getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val; for (let i = 0; i < 12; i++) { if (year == currentYear) { if (i < currentMonth) { avMonths[i] = " "; } else { avMonths[i] = months[i]; } } else { avMonths = months; } } monthKeys[0] = avMonths.slice(0,4); monthKeys[1] = avMonths.slice(4,8); monthKeys[2] = avMonths.slice(8); monthKeys[3] = ["Abbrechen",""]; // Tastatur senden sendTo('telegram.0', { text: 'Monat wählen', reply_markup: { keyboard: monthKeys, resize_keyboard: true, one_time_keyboard: false } }); }; function keyboardDay () { // Tastatur für die Tagesauswahl zusammenbauen var days = new Array(); var dayKeys = new Array(8); year = getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val; month = getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val; let firstDay = new Date(year, month, 1).getDay(); let daysInMonth = new Date(year, month + 1, 0).getDate() // Tages-Array mit " " füllen, falls erster Tag nicht Montag if (firstDay == 0) { for (let i = 0; i < 6; i++) { days.push(" "); } } else if (firstDay > 1) { for (let i = 1; i < firstDay; i++) { days.push(" "); } } // Tage zum Array hinzufügen for (let i = 1; i <= daysInMonth; i++) { if (getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val == currentYear && getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val == currentMonth) { if (i < currentDay) { days.push(" "); } else { days.push(i.toString()); } } else { days.push(i.toString()); } } // Rest mit " " füllen for (let i = days.length; i < 42; i++) { days.push(" "); } dayKeys[0] = ['M','D','M','D','F','S','S']; dayKeys[1] = days.slice(0,7); dayKeys[2] = days.slice(7,14); dayKeys[3] = days.slice(14,21); dayKeys[4] = days.slice(21,28); dayKeys[5] = days.slice(28,35); dayKeys[6] = days.slice(35); dayKeys[7] = ["Abbrechen"]; // Tastatur senden sendTo('telegram.0', { text: 'Tag wählen', reply_markup: { keyboard: dayKeys, resize_keyboard: true, one_time_keyboard: false } }); }; // Auf Eingabe reagieren on({id: "0_userdata.0.Telegram.text2command.textProcessor", change: "ne"}, async function (obj) { try { var task = JSON.parse(obj.state.val); // Start if (isNaN(task.command) && task.command == "Abwesenheit planen") { go(); } // Jahr eingegeben else if (!isNaN(task.command) && task.command >= currentYear && getState("0_userdata.0.Telegram.text2command.textProcessor").val != "" && getState("0_userdata.0.Telegram.text2command.datePicker_Datum").val == 'running' && getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val == 0 && getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val == 0 && getState("0_userdata.0.Telegram.text2command.datePicker_Tag").val == 0) { // Jahr abspeichern setState("0_userdata.0.Telegram.text2command.datePicker_Jahr", Number(task.command), true); //Bestätigung an textProcessor setState("0_userdata.0.Telegram.text2command.textProcessor", 'Jahr gespeichert', true); // Monat aufrufen keyboardMonth(); } // Monat eingegeben else if (isNaN(task.command) && getState("0_userdata.0.Telegram.text2command.textProcessor").val != "" && getState("0_userdata.0.Telegram.text2command.datePicker_Datum").val == 'running' && getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val > 0 && getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val == 0 && getState("0_userdata.0.Telegram.text2command.datePicker_Tag").val == 0) { // Monat abspeichern setState("0_userdata.0.Telegram.text2command.datePicker_Monat", months.indexOf(task.command), true); //Bestätigung an textProcessor setState("0_userdata.0.Telegram.text2command.textProcessor", 'Monat gespeichert', true); // Tag aufrufen keyboardDay(); } // Tag eingegeben else if (!isNaN(task.command) && getState("0_userdata.0.Telegram.text2command.textProcessor").val != "" && getState("0_userdata.0.Telegram.text2command.datePicker_Datum").val == 'running' && getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val > 0 && getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val > 0 && getState("0_userdata.0.Telegram.text2command.datePicker_Tag").val == 0) { //Tag abspeichern setState("0_userdata.0.Telegram.text2command.datePicker_Tag", Number(task.command), true); //Bestätigung an textProcessor setState("0_userdata.0.Telegram.text2command.textProcessor", 'Tag gespeichert', true); //Datum zusammenbauen und in Datenpunkt schreiben setState("0_userdata.0.Telegram.text2command.datePicker_Datum", getState("0_userdata.0.Telegram.text2command.datePicker_Jahr").val + "-" + (getState("0_userdata.0.Telegram.text2command.datePicker_Monat").val + 1) + "-" + getState("0_userdata.0.Telegram.text2command.datePicker_Tag").val , true); //Einzel-DP für Datum zurücksetzen setState("0_userdata.0.Telegram.text2command.datePicker_Jahr", 0, true); setState("0_userdata.0.Telegram.text2command.datePicker_Monat", 0, true); setState("0_userdata.0.Telegram.text2command.datePicker_Tag", 0, true); //Bestätigung senden sendTo("telegram", "send", { text: 'Datum gespeichert' }); //zurück ins Hauptmenü setState("javascript.0.scriptEnabled.Telegram-Menu.000_menu", true); } //Abbrechen else if (isNaN(task.command) && task.command == "Abbrechen") { //Einzel-DP für Datum zurücksetzen setState("0_userdata.0.Telegram.text2command.datePicker_Jahr", 0, true); setState("0_userdata.0.Telegram.text2command.datePicker_Monat", 0, true); setState("0_userdata.0.Telegram.text2command.datePicker_Tag", 0, true); //Datum zurücksetzen setState("0_userdata.0.Telegram.text2command.datePicker_Datum", "", true); //Bestätigung an textProcessor setState("0_userdata.0.Telegram.text2command.textProcessor", 'Abbruch', true); //zurück ins Hauptmenü setState("javascript.0.scriptEnabled.Telegram-Menu.000_menu", true); } // Rückmeldung geben, dass das Script nicht reagieren wird else { setState("0_userdata.0.Telegram.text2command.textProcessor", '', true); } } catch { // do nothing } });Was mich derzeit noch stört ist, dass im Log immer eine Warnung auftaucht, wenn ein Befehl gesendet wurde, auf den das Script nicht reagieren wird. Das halte ich aber für einen Bug, da die Rückmeldung, dass das Script nichts tun wird, ja korrekt ausgeführt wird.
text2command.0 2022-08-10 13:27:06.692 warn Timeout for external processor: 0_userdata.0.Telegram.text2command.textProcessorWas mich außerdem stört ist, dass die Aufforderung zur nächsten Eingabe eher kommt, als die Bestätigung der letzten Eingabe. Das sieht im Chat-Verlauf echt komisch aus, aber ich habe noch keine Idee, woran das liegt und wie man das lösen könnte.
Vielleicht kann das Ganze ja jemand gebrauchen - viel Spaß damit :)
Für Verbessungsvorschläge bin ich offen, falls jemand welche hat.
Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.
Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.
Mit deinem Input könnte dieser Beitrag noch besser werden 💗
Registrieren Anmelden