persistable sclass Gazelle_GrabPostsLoop { S server = gazelle_server(); S _user, _botToken; Set fields = litset("_modified", "text"); long changedAfter; double delay = 0.5; double errorDelay = 10; bool verbose, enabled = true; int pollFor = 600; // seconds for each poll bool firstGrab = true; !include #1028121 // setField + change() run { while licensed { pcall { if (enabled) grab(); } sleepSeconds(delay); } } void grab { O[] params = litobjectarray(+_user, +_botToken, fields := joinWithSpace(fields), +changedAfter, +pollFor); print(params := litorderedmap(params)); Map _result = cast postJSONPage(server + "bot/listPosts", params); if (verbose) print(+_result); S error = cast _result.get("error"); if (error != null) { print("Server ERROR: " + error); sleepSeconds(errorDelay); ret; } L posts = cast _result.get("result"); print("Found " + n2(posts, "new post")); L posts2 = map(posts, p -> GazellePost(p)); for (GazellePost p : posts2) setField(changedAfter := max(changedAfter, p.modified)); if (nempty(posts2)) handlePosts(posts2); firstGrab = false; } swappable void handlePosts(Cl posts) { for (GazellePost p : posts) pcall { handlePost(p); } } transient swappable void handlePost(GazellePost post) { } void reset { setField(changedAfter := 0L); } Cl allPostIDs() { Map _result = cast postJSONPage(server + "bot/listPosts", +_user, +_botToken); L posts = cast _result.get("result"); ret allToLong(collect id(posts)); } }