Warning: session_start(): open(/var/lib/php/sessions/sess_b1coii8ahuedp81oc1toiaaqf7, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
sS dbBotID = #1026247;
static Env env;
static new ThreadLocal session;
static new ThreadLocal out;
sclass Out {
S buttonsIntro;
LS buttons;
S placeholder;
S defaultInput;
}
sbool testFunctions = false;
static interface Env {
void sayAsync(S session, S msg);
}
concept Session {
S cookie;
S language;
S lastQuestion;
FormInFlight form, lastForm;
void cancelForm {
cset(this, lastForm := form, form := null);
}
S language() { ret or2(language, 'en); }
}
sclass FormStep {
S key;
S displayText, desc;
S defaultValue;
S placeholder; // null for same as displayText, "" for none
LS buttons;
S value;
void update(Runnable onChange) {}
}
sclass FormInFlight {
S hashTag;
new L steps;
int stepIndex; // in steps list
FormStep currentStep() {
ret get(steps, stepIndex);
}
void update(Runnable onChange) {
if (currentStep() != null) currentStep().update(onChange);
}
S complete() { ret "Form complete"; }
S cancel() { ret "Request cancelled"; }
bool shouldCancel() { false; }
}
sclass MainForm > FormInFlight {
FormStep stepInterested, stepMailAddress, stepDevice, stepConfirm;
*() {
hashTag = "#mainForm";
steps.add(stepInterested = setAll(new StepInterested,
key := "interested",
desc := "Interested in free trial",
displayText := "Are you after a free trial of our IPTV services?",
buttons := ll("Yes, please!", "No, thanks.")));
steps.add(stepMailAddress = nu FormStep(
key := "mailAddress",
desc := "E-mail address",
displayText := "What is your e-mail address?"));
steps.add(stepDevice = nu FormStep(
key := "device",
desc := "Device",
displayText := "Which IPTV-capable device do you own?",
buttons := ll("Android box", "Android phone", "Android tablet", "Firestick", "Smart TV", "None/Unsure")));
steps.add(stepConfirm = setAll(new StepConfirm,
key := "confirm",
placeholder := "",
buttons := ll("Yes")
));
}
bool shouldCancel() {
ret isNo(stepInterested.value);
}
class StepInterested extends FormStep {
/*S handleAnswer(S s) {
session->cancelForm();
}*/
}
class StepConfirm extends FormStep {
void update(Runnable onChange) {
if (set_trueIfChanged(this, displayText :=
summary() + "\n\n" + "Submit contact request?")) callF(onChange);
}
}
S summary() {
print("Will send to: " + sendToViberIDs());
ret mapToLines_rtrim(listMinus(steps, stepConfirm), step ->
(nempty(step.desc)
? addSuffix(step.desc, ":") : step.displayText)
+ " " + step.value);
}
LS sendToViberIDs() {
ret llNempties(stefanViberID(), loadTextFileTrim(javaxSecretDir("iptv-viber-id.txt");
}
S complete() {
LS viberIDs = sendToViberIDs();
S text = summary() + "\n\n" + "[Form submitted in smart-iptv-solutions.co.uk chat bot, " + timeInTimeZoneWithDate_24(ukTimeZone_string()) + "]";
pcall {
for (S viberID : sendToViberIDs())
viber_sendMessage(mandatoryViberToken(),
"BotCompany",
viberID,
text);
ret "Thank you, your contact request was sent!";
}
ret "Sorry, an error occurred sending the message.";
}
S cancel() { ret "Contact request cancelled"; }
}
sbool debug;
svoid setSession(S cookie, SS params) {
session.set(uniq_sync(Session, +cookie));
S lang = mapGet(params, 'language);
if (nempty(lang))
cset(session!, language := lang);
S lang_default = mapGet(params, 'language_default);
if (nempty(lang_default)) {
print("lang_default=" + lang_default + ", have: " + session->language);
if (empty(session->language)) {
print("Setting language.");
cset(session!, language := lang_default);
}
}
}
svoid clearSession(S cookie) {
deleteConcepts(Session, +cookie);
}
p {
db();
// for testing on desktop
if (isMain()) { veryBigConsole(); bot(); }
}
sS returnQuestion(S q) {
cset(session!, lastQuestion := q);
ret q;
}
sS answer(S s) {
if (session! == null) setSession("default", new Map);
out.set(new Out);
if (creator() == null) if "debug" set debug;
S lq = session->lastQuestion;
cset(session!, lastQuestion := null);
FormInFlight form = session->form;
if (form != null && form.currentStep() != null) {
if (eqicOneOf(s, "cancel", "Abbrechen", unicode_crossProduct())) {
S answer = form.cancel();
session->cancelForm();
ret answer;
}
else if (eqicOneOf(s, "back", "zurück", unicode_undoArrow()) && form.stepIndex > 0) {
--form.stepIndex;
session->change();
ret deliverAnswerAndFormStep("");
} else {
FormStep step = form.currentStep();
if (nempty(step.buttons) && !cic(step.buttons, s))
ret deliverAnswerAndFormStep(de() ? "Bitte wählen Sie eine Option!" : "Please choose an option.");
step.value = s;
++form.stepIndex;
session->change();
if (form.currentStep() == null) {
S answer = form.complete();
session->cancelForm();
ret answer;
}
ret deliverAnswerAndFormStep("");
}
}
if (testFunctions) {
if (eq(lq, "Would you like some tea?")) {
if "yes" ret "Here's your tea.";
if "no" ret "Very well then.";
}
if "test buttons" {
out->buttons = ll("Yes", "No");
ret returnQuestion("Would you like some tea?");
}
if "say something later" {
if (env == null) ret("No env");
final S mySession = session->cookie;
thread {
sleepSeconds(5);
env.sayAsync(mySession, "Here it is.");
}
ret "OK, will do it in 5 seconds";
}
}
// get answer from bot, switch language
O bot = dbBot();
S a = (S) call(bot, 'answer, s, session->language());
S lang = cast getThreadLocal(((ThreadLocal) get(bot, 'language_out)));
if (nempty(lang)) cset(session!, language := lang);
S a2 = replaceAll(a, "\\s*#mainForm\\b", "");
if (neq(a, a2)) {
form = new MainForm;
print("Made form for cookie " + session->cookie + ": " + sfu(form));
cset(session!, +form);
}
ret deliverAnswerAndFormStep(a2);
}
sS deliverAnswerAndFormStep(S answer) {
FormInFlight form = session->form;
if (form == null) ret answer;
form.update(r { session->change() });
if (form.shouldCancel()) {
session->cancelForm();
ret answer;
}
if (form.currentStep() == null) ret answer;
FormStep step = form.currentStep();
if (empty(answer))
answer = step.displayText;
else
out->buttonsIntro = step.displayText;
out->placeholder = or(step.placeholder, step.displayText);
print("Step " + form.stepIndex + ": " + sfu(step));
out->defaultInput = or2(step.value, step.defaultValue);
out->buttons = cloneList(step.buttons);
if (form.stepIndex > 0) out->buttons.add(de() ? "Zurück" : "Back");
out->buttons.add(de() ? "Abbrechen" : "Cancel");
ret answer;
}
sS initialMessage() {
print("initialMessage, lang=" + session->language());
ret or2(answer("#greeting"), "Hello");
}
sO dbBot() {
ret getBot(dbBotID);
}
sbool de() {
ret eqic(session->language(), "de");
}
sbool botOn() {
ret isTrue(call(dbBot(), "botOn"));
}
sbool botAutoOpen() {
ret isTrue(call(dbBot(), "botAutoOpen"));
}