!7 cmodule eeZee > DynDiscordHopper { switchable S url = "tcp://0.tcp.ngrok.io:16892"; switchable S httpURL = "https://55392290.ngrok.io"; transient S prefix = "<@599426196647706645> "; transient S drbPrefix = "<@599426196647706645> drb "; L authorizedUsers = ll(463778175432785932); transient NotTooOften ntoError = notTooOften_1min(); @Override S answer(S input, Map map) { try answer super.answer(input, map); setField(httpURL := or2(loadProgramTextFile("http-url"), httpURL)); new Matches m; long userID = getLong userID(map); print("User ID: " + userID); if (eqic(input, "hey " + trim(prefix))) ret "hey"; if (swic_trim(input, prefix + "add master ", m)) { if (!contains(authorizedUsers, userID)) ret "You are not my master"; add(authorizedUsers, parseFirstLong(m.rest())); change(); ret "Okidoki. Have " + n2(l(authorizedUsers), "master"); } if (swic_trim(input, prefix + "set url ", m)) { if (!contains(authorizedUsers, userID)) ret "You are not my master"; setField(httpURL := m.rest()); saveProgramTextFile("http-url", httpURL); ret "URL set to " + httpURL + ", master"; } long time = sysNow(); S s; try { if (startsWith_trim(input, drbPrefix, m)) { input = m.rest(); temp DialogIO io = talkToTCPURL(url); io.sendLine(trim(firstLine(input))); new LS lines; while (addUnlessNull(lines, io.readLine()) != null); s = lines_rtrim(lines); } else { temp doAfterSecondsIfStillRunning(2.0, r { iAmTyping(map) }); s = loadPageWithTimeout(60.0, httpURL + hquery(message := input, +userID, channelID := map.get('channelID))); } print("Got " + (s == null ? "timeout" : nChars(s)) + " in " + elapsedSeconds(time) + " s"); ret s; } catch e { if (!ntoError.yo()) null; S str = exceptionToStringShort(e); if (cicOneOf(str, "Server returned HTTP response code: 502", "FileNotFoundException", "SocketTimeoutException")) // rough ret null with print("Bot is offline (502/404/timeout)"); print(e); ret "Error: " + shorten(100, str); } } }