static double stefansChat_onLine_safetyDelay = 1; // seconds static double stefansChat_onLine_shortSafetyDelay = 0.1; static double stefansChat_onLine_errorDelay = 10; static int stefansChat_onLine_lookback = 0; static int stefansChat_onLine_firstRead = -1; static new ThreadLocal stefansChat_onLine_fullParams; static new ThreadLocal stefansChat_onLine_onHistoryRead; static void stefansChat_onLine(int lookback, O f) { stefansChat_onLine_lookback = lookback; stefansChat_onLine(f); } static void stefansChat_onLine(fO f) { fO hr = getAndClearThreadLocal(stefansChat_onLine_onHistoryRead); thread "Stefan's Chat" { int a = stefansChat_onLine_firstRead = max(0, stefansChat_n()-stefansChat_onLine_lookback); bool first = true; while licensed { pcall { S s = loadPageWithTimeout("http://botcompany.de/1008998/raw/incremental?json=1&a=" + a, 120*1000); if (empty(trim(s))) { sleepSeconds(stefansChat_onLine_safetyDelay); //print("Re-polling."); continue; } try { Map map = safeUnstructMap(s); int n = getInt n(map); L msgs = cast get(map, 'msgs); for (O msg : msgs) try { stefansChat_onLine_fullParams.set(mapPlus((Map) msg, chatName := "Stefan's Chat")); pcallF(f, getString(msg, 'text)); } finally { stefansChat_onLine_fullParams.set(null); } sleepSeconds(stefansChat_onLine_shortSafetyDelay); a = n; } catch e { printException(e); sleepSeconds(stefansChat_onLine_errorDelay); } if (first) { pcallF(hr); first = false; } }} // end pcall, while licensed } }