!7 //lib 1400198 // jSlack 1.2.2 (fat jar) lib 1400206 // jSlack 1.4.2 (fat jar) import com.github.seratch.jslack.*; import com.github.seratch.jslack.api.rtm.*; import com.github.seratch.jslack.api.methods.request.chat.*; import com.github.seratch.jslack.api.methods.response.chat.*; static Slack slack; sbool slackDump = false; sS slackToken; static File slackTokenFile() { ret javaxSecretDir("oibot-token-2.txt"); } svoid loadSlackToken() { slackToken = trim(loadTextFile(slackTokenFile())); } static RTMClient initSlackBot(O answerer) ctex { if (slack != null) fail("Slack already started"); fixContextClassLoader(); if (slackToken == null) loadSlackToken(); assertNempty("Need slack token: " + slackTokenFile(), slackToken); slack = new Slack; RTMClient rtm = slack.rtm(slackToken); rtm.addErrorHandler(error -> { print("Got Slack error: " + error); appendToTextFile("slack-errors.txt", "\n " + getStackTrace(error) + "\n"); print("...reconnecting to be sure."); thread "Reconnect to Slack" { fixContextClassLoader(); pcall { rtm.disconnect(); } print("Disconnected (hopefully)"); print("Waiting 10, then reconnecting."); sleepSeconds(10); print("Reconnecting to Slack"); try { rtm.connect(); print("Done"); } catch e { printStackTrace(e); print("Connect failed, restarting module."); dm_reloadModule(); } } }); rtm.addMessageHandler((message) -> { Map json = jsonDecodeMap(message); if (slackDump) pnlStruct(json); if (eq(json.get("type"), "message")) pcall { bool bot = eq(json.get("subtype"), "bot_message"); S channelID = cast json.get("channel"); S ts = cast json.get("ts"); S text = cast json.get("text"); vmBus_send('incomingSlackMessage, litmapparams( fromBot := bot, msgID := ts, +channelID, content := text, +json /*+isPrivate*/)); } }); // must connect within 30 seconds after issuing wss endpoint rtm.connect(); print("Slack inited!"); ret rtm; } // no cmodule because of doPost / loadPage module SlackModule > DynPrintLogAndEnabled { switchable S token; transient new ThreadLocal msgJSON; transient RTMClient rtm; start { if (!enabled) ret with print("Not enabled"); vm_cleanPrints(); // avoid Swing Unicode problem logModuleOutput(); // good idea for chat bots dm_registerAs('slackModule); if (nempty(token)) ret with startSlack(); inputText("Please enter Slack bot token", voidfunc(S s) { setField(token := s); startSlack(); }); } void startSlack enter { ownResource(rtm = initSlackBot(this)); } }